From 115dc8764233e442d276ae73ce4555fabc9b7469 Mon Sep 17 00:00:00 2001 From: Malte Reents Date: Fri, 16 Aug 2024 10:27:40 +0200 Subject: [PATCH] deleted old files Alte Datein entfernt --- Configuration.h | 3166 ----- Configuration_adv.h | 4354 ------- Makefile | 1035 -- Marlin.ino.mega.hex | 10345 --------------- Marlin.ino.with_bootloader.mega.hex | 10813 ---------------- Marlin/Configuration.h | 3166 ----- Marlin/Configuration_adv.h | 4354 ------- Marlin/Marlin.ino | 57 - Marlin/Version.h | 76 - Version.h | 76 - lib/readme.txt | 36 - src/HAL/AVR/HAL.cpp | 172 - src/HAL/AVR/HAL.h | 277 - src/HAL/AVR/HAL_SPI.cpp | 254 - src/HAL/AVR/MarlinSPI.h | 26 - src/HAL/AVR/MarlinSerial.cpp | 652 - src/HAL/AVR/MarlinSerial.h | 297 - src/HAL/AVR/Servo.cpp | 226 - src/HAL/AVR/ServoTimers.h | 93 - src/HAL/AVR/eeprom.cpp | 74 - src/HAL/AVR/endstop_interrupts.h | 306 - src/HAL/AVR/fast_pwm.cpp | 222 - src/HAL/AVR/fastio.cpp | 288 - src/HAL/AVR/fastio.h | 350 - src/HAL/AVR/fastio/fastio_1280.h | 1114 -- src/HAL/AVR/fastio/fastio_1281.h | 715 - src/HAL/AVR/fastio/fastio_168.h | 357 - src/HAL/AVR/fastio/fastio_644.h | 552 - src/HAL/AVR/fastio/fastio_AT90USB.h | 697 - src/HAL/AVR/inc/Conditionals_LCD.h | 26 - src/HAL/AVR/inc/Conditionals_adv.h | 22 - src/HAL/AVR/inc/Conditionals_post.h | 22 - src/HAL/AVR/inc/SanityCheck.h | 101 - src/HAL/AVR/math.h | 113 - src/HAL/AVR/pinsDebug.h | 400 - src/HAL/AVR/pinsDebug_Teensyduino.h | 111 - src/HAL/AVR/pinsDebug_plus_70.h | 332 - src/HAL/AVR/spi_pins.h | 65 - src/HAL/AVR/timers.h | 260 - src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp | 193 - src/HAL/DUE/HAL.cpp | 201 - src/HAL/DUE/HAL.h | 233 - src/HAL/DUE/HAL_SPI.cpp | 819 -- src/HAL/DUE/InterruptVectors.cpp | 98 - src/HAL/DUE/InterruptVectors.h | 45 - src/HAL/DUE/MarlinSPI.h | 26 - src/HAL/DUE/MarlinSerial.cpp | 494 - src/HAL/DUE/MarlinSerial.h | 156 - src/HAL/DUE/MarlinSerialUSB.cpp | 142 - src/HAL/DUE/MarlinSerialUSB.h | 65 - src/HAL/DUE/MinSerial.cpp | 91 - src/HAL/DUE/Servo.cpp | 163 - src/HAL/DUE/ServoTimers.h | 107 - src/HAL/DUE/Tone.cpp | 60 - .../dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp | 143 - .../dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp | 186 - src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp | 145 - .../dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp | 113 - .../DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h | 35 - src/HAL/DUE/eeprom_flash.cpp | 998 -- src/HAL/DUE/eeprom_wired.cpp | 76 - src/HAL/DUE/endstop_interrupts.h | 73 - src/HAL/DUE/fastio.h | 565 - src/HAL/DUE/fastio/G2_PWM.cpp | 206 - src/HAL/DUE/fastio/G2_PWM.h | 78 - src/HAL/DUE/fastio/G2_pins.h | 278 - src/HAL/DUE/inc/Conditionals_LCD.h | 26 - src/HAL/DUE/inc/Conditionals_adv.h | 22 - src/HAL/DUE/inc/Conditionals_post.h | 28 - src/HAL/DUE/inc/SanityCheck.h | 89 - src/HAL/DUE/pinsDebug.h | 185 - src/HAL/DUE/spi_pins.h | 64 - src/HAL/DUE/timers.cpp | 139 - src/HAL/DUE/timers.h | 129 - src/HAL/DUE/upload_extra_script.py | 19 - src/HAL/DUE/usb/arduino_due_x.h | 97 - src/HAL/DUE/usb/compiler.h | 1150 -- src/HAL/DUE/usb/conf_access.h | 116 - src/HAL/DUE/usb/conf_clock.h | 100 - src/HAL/DUE/usb/conf_usb.h | 296 - src/HAL/DUE/usb/ctrl_access.c | 647 - src/HAL/DUE/usb/ctrl_access.h | 402 - src/HAL/DUE/usb/genclk.h | 278 - src/HAL/DUE/usb/mrepeat.h | 339 - src/HAL/DUE/usb/osc.h | 261 - src/HAL/DUE/usb/pll.h | 288 - src/HAL/DUE/usb/preprocessor.h | 55 - src/HAL/DUE/usb/sbc_protocol.h | 173 - src/HAL/DUE/usb/sd_mmc_spi_mem.cpp | 142 - src/HAL/DUE/usb/sd_mmc_spi_mem.h | 177 - src/HAL/DUE/usb/spc_protocol.h | 337 - src/HAL/DUE/usb/stringz.h | 85 - src/HAL/DUE/usb/sysclk.c | 122 - src/HAL/DUE/usb/sysclk.h | 229 - src/HAL/DUE/usb/tpaste.h | 105 - src/HAL/DUE/usb/udc.c | 1149 -- src/HAL/DUE/usb/udc.h | 697 - src/HAL/DUE/usb/udc_desc.h | 135 - src/HAL/DUE/usb/udd.h | 396 - src/HAL/DUE/usb/udi.h | 133 - src/HAL/DUE/usb/udi_cdc.c | 1155 -- src/HAL/DUE/usb/udi_cdc.h | 810 -- src/HAL/DUE/usb/udi_cdc_conf.h | 156 - src/HAL/DUE/usb/udi_cdc_desc.c | 261 - src/HAL/DUE/usb/udi_composite_desc.c | 192 - src/HAL/DUE/usb/udi_msc.c | 1132 -- src/HAL/DUE/usb/udi_msc.h | 376 - src/HAL/DUE/usb/uotghs_device_due.c | 2074 --- src/HAL/DUE/usb/uotghs_device_due.h | 664 - src/HAL/DUE/usb/uotghs_otg.h | 241 - src/HAL/DUE/usb/usb_protocol.h | 496 - src/HAL/DUE/usb/usb_protocol_cdc.h | 320 - src/HAL/DUE/usb/usb_protocol_msc.h | 147 - src/HAL/DUE/usb/usb_task.c | 341 - src/HAL/DUE/usb/usb_task.h | 134 - src/HAL/ESP32/FlushableHardwareSerial.cpp | 29 - src/HAL/ESP32/FlushableHardwareSerial.h | 34 - src/HAL/ESP32/HAL.cpp | 429 - src/HAL/ESP32/HAL.h | 246 - src/HAL/ESP32/HAL_SPI.cpp | 113 - src/HAL/ESP32/MarlinSPI.h | 26 - src/HAL/ESP32/Servo.cpp | 67 - src/HAL/ESP32/Servo.h | 48 - src/HAL/ESP32/Tone.cpp | 59 - src/HAL/ESP32/WebSocketSerial.cpp | 148 - src/HAL/ESP32/WebSocketSerial.h | 85 - src/HAL/ESP32/eeprom.cpp | 57 - src/HAL/ESP32/endstop_interrupts.h | 68 - src/HAL/ESP32/esp32.csv | 6 - src/HAL/ESP32/fastio.h | 93 - src/HAL/ESP32/i2s.cpp | 364 - src/HAL/ESP32/i2s.h | 35 - src/HAL/ESP32/inc/Conditionals_LCD.h | 26 - src/HAL/ESP32/inc/Conditionals_adv.h | 29 - src/HAL/ESP32/inc/Conditionals_post.h | 22 - src/HAL/ESP32/inc/SanityCheck.h | 54 - src/HAL/ESP32/ota.cpp | 72 - src/HAL/ESP32/ota.h | 23 - src/HAL/ESP32/servotimers.h | 22 - src/HAL/ESP32/spi_pins.h | 27 - src/HAL/ESP32/spiffs.cpp | 43 - src/HAL/ESP32/spiffs.h | 26 - src/HAL/ESP32/timers.cpp | 171 - src/HAL/ESP32/timers.h | 140 - src/HAL/ESP32/u8g_esp32_spi.cpp | 94 - src/HAL/ESP32/web.cpp | 47 - src/HAL/ESP32/web.h | 24 - src/HAL/ESP32/wifi.cpp | 66 - src/HAL/ESP32/wifi.h | 30 - src/HAL/HAL.h | 47 - src/HAL/LINUX/HAL.cpp | 61 - src/HAL/LINUX/HAL.h | 165 - src/HAL/LINUX/MarlinSPI.h | 26 - src/HAL/LINUX/arduino.cpp | 99 - src/HAL/LINUX/eeprom.cpp | 104 - src/HAL/LINUX/fastio.h | 111 - src/HAL/LINUX/hardware/Clock.cpp | 31 - src/HAL/LINUX/hardware/Clock.h | 89 - src/HAL/LINUX/hardware/Gpio.cpp | 29 - src/HAL/LINUX/hardware/Gpio.h | 141 - src/HAL/LINUX/hardware/Heater.cpp | 60 - src/HAL/LINUX/hardware/Heater.h | 47 - src/HAL/LINUX/hardware/IOLoggerCSV.cpp | 49 - src/HAL/LINUX/hardware/IOLoggerCSV.h | 40 - src/HAL/LINUX/hardware/LinearAxis.cpp | 65 - src/HAL/LINUX/hardware/LinearAxis.h | 45 - src/HAL/LINUX/hardware/Timer.cpp | 117 - src/HAL/LINUX/hardware/Timer.h | 76 - src/HAL/LINUX/inc/Conditionals_LCD.h | 26 - src/HAL/LINUX/inc/Conditionals_adv.h | 22 - src/HAL/LINUX/inc/Conditionals_post.h | 22 - src/HAL/LINUX/inc/SanityCheck.h | 43 - src/HAL/LINUX/include/Arduino.h | 94 - src/HAL/LINUX/include/pinmapping.cpp | 32 - src/HAL/LINUX/include/pinmapping.h | 65 - src/HAL/LINUX/include/serial.h | 118 - src/HAL/LINUX/main.cpp | 138 - src/HAL/LINUX/pinsDebug.h | 63 - src/HAL/LINUX/servo_private.h | 79 - src/HAL/LINUX/spi_pins.h | 55 - src/HAL/LINUX/timers.cpp | 71 - src/HAL/LINUX/timers.h | 96 - src/HAL/LPC1768/HAL.cpp | 124 - src/HAL/LPC1768/HAL.h | 267 - src/HAL/LPC1768/HAL_SPI.cpp | 406 - src/HAL/LPC1768/MarlinSPI.h | 45 - src/HAL/LPC1768/MarlinSerial.cpp | 71 - src/HAL/LPC1768/MarlinSerial.h | 69 - src/HAL/LPC1768/MinSerial.cpp | 51 - src/HAL/LPC1768/Servo.h | 69 - src/HAL/LPC1768/eeprom_flash.cpp | 131 - src/HAL/LPC1768/eeprom_sdcard.cpp | 186 - src/HAL/LPC1768/eeprom_wired.cpp | 77 - src/HAL/LPC1768/endstop_interrupts.h | 158 - src/HAL/LPC1768/fast_pwm.cpp | 37 - src/HAL/LPC1768/fastio.h | 119 - src/HAL/LPC1768/inc/Conditionals_LCD.h | 26 - src/HAL/LPC1768/inc/Conditionals_adv.h | 26 - src/HAL/LPC1768/inc/Conditionals_post.h | 34 - src/HAL/LPC1768/inc/SanityCheck.h | 276 - src/HAL/LPC1768/include/SPI.h | 182 - .../include/digipot_mcp4451_I2C_routines.c | 77 - .../include/digipot_mcp4451_I2C_routines.h | 43 - src/HAL/LPC1768/include/i2c_util.c | 96 - src/HAL/LPC1768/include/i2c_util.h | 61 - src/HAL/LPC1768/main.cpp | 163 - src/HAL/LPC1768/pinsDebug.h | 55 - src/HAL/LPC1768/spi_pins.h | 54 - src/HAL/LPC1768/tft/tft_spi.cpp | 130 - src/HAL/LPC1768/tft/tft_spi.h | 77 - src/HAL/LPC1768/tft/xpt2046.cpp | 131 - src/HAL/LPC1768/tft/xpt2046.h | 83 - src/HAL/LPC1768/timers.cpp | 65 - src/HAL/LPC1768/timers.h | 173 - src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp | 89 - src/HAL/LPC1768/u8g/LCD_I2C_routines.h | 28 - src/HAL/LPC1768/u8g/LCD_defines.h | 49 - src/HAL/LPC1768/u8g/LCD_delay.h | 43 - src/HAL/LPC1768/u8g/LCD_pin_routines.c | 110 - src/HAL/LPC1768/u8g/LCD_pin_routines.h | 37 - .../u8g/u8g_com_HAL_LPC1768_hw_spi.cpp | 129 - .../u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp | 198 - .../u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp | 138 - .../u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp | 147 - .../u8g/u8g_com_HAL_LPC1768_sw_spi.cpp | 209 - src/HAL/LPC1768/upload_extra_script.py | 127 - src/HAL/LPC1768/usb_serial.cpp | 38 - .../win_usb_driver/lpc176x_usb_driver.inf | 36 - src/HAL/NATIVE_SIM/HAL.h | 266 - src/HAL/NATIVE_SIM/MarlinSPI.h | 26 - src/HAL/NATIVE_SIM/fastio.h | 111 - src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h | 22 - src/HAL/NATIVE_SIM/inc/Conditionals_adv.h | 31 - src/HAL/NATIVE_SIM/inc/Conditionals_post.h | 22 - src/HAL/NATIVE_SIM/inc/SanityCheck.h | 43 - src/HAL/NATIVE_SIM/pinsDebug.h | 61 - src/HAL/NATIVE_SIM/servo_private.h | 80 - src/HAL/NATIVE_SIM/spi_pins.h | 55 - src/HAL/NATIVE_SIM/tft/tft_spi.h | 64 - src/HAL/NATIVE_SIM/tft/xpt2046.h | 80 - src/HAL/NATIVE_SIM/timers.h | 91 - src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp | 52 - src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h | 37 - src/HAL/NATIVE_SIM/u8g/LCD_defines.h | 44 - src/HAL/NATIVE_SIM/u8g/LCD_delay.h | 43 - src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp | 52 - src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h | 46 - .../NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp | 171 - src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp | 218 - src/HAL/SAMD51/HAL.cpp | 690 - src/HAL/SAMD51/HAL.h | 216 - src/HAL/SAMD51/HAL_SPI.cpp | 148 - src/HAL/SAMD51/MarlinSPI.h | 26 - src/HAL/SAMD51/MarlinSerial_AGCM4.cpp | 54 - src/HAL/SAMD51/MarlinSerial_AGCM4.h | 29 - src/HAL/SAMD51/QSPIFlash.cpp | 78 - src/HAL/SAMD51/QSPIFlash.h | 49 - src/HAL/SAMD51/SAMD51.h | 70 - src/HAL/SAMD51/Servo.cpp | 217 - src/HAL/SAMD51/ServoTimers.h | 39 - src/HAL/SAMD51/eeprom_flash.cpp | 95 - src/HAL/SAMD51/eeprom_qspi.cpp | 71 - src/HAL/SAMD51/eeprom_wired.cpp | 75 - src/HAL/SAMD51/endstop_interrupts.h | 202 - src/HAL/SAMD51/fastio.h | 253 - src/HAL/SAMD51/inc/Conditionals_LCD.h | 26 - src/HAL/SAMD51/inc/Conditionals_adv.h | 22 - src/HAL/SAMD51/inc/Conditionals_post.h | 28 - src/HAL/SAMD51/inc/SanityCheck.h | 57 - src/HAL/SAMD51/pinsDebug.h | 154 - src/HAL/SAMD51/spi_pins.h | 54 - src/HAL/SAMD51/timers.cpp | 168 - src/HAL/SAMD51/timers.h | 143 - src/HAL/STM32/HAL.cpp | 182 - src/HAL/STM32/HAL.h | 281 - src/HAL/STM32/HAL_SPI.cpp | 231 - src/HAL/STM32/MarlinSPI.cpp | 174 - src/HAL/STM32/MarlinSPI.h | 107 - src/HAL/STM32/MarlinSerial.cpp | 110 - src/HAL/STM32/MarlinSerial.h | 59 - src/HAL/STM32/MinSerial.cpp | 153 - src/HAL/STM32/README.md | 11 - src/HAL/STM32/Servo.cpp | 112 - src/HAL/STM32/Servo.h | 54 - src/HAL/STM32/eeprom_bl24cxx.cpp | 85 - src/HAL/STM32/eeprom_flash.cpp | 277 - src/HAL/STM32/eeprom_if_iic.cpp | 56 - src/HAL/STM32/eeprom_sdcard.cpp | 94 - src/HAL/STM32/eeprom_sram.cpp | 70 - src/HAL/STM32/eeprom_wired.cpp | 80 - src/HAL/STM32/endstop_interrupts.h | 55 - src/HAL/STM32/fast_pwm.cpp | 88 - src/HAL/STM32/fastio.cpp | 36 - src/HAL/STM32/fastio.h | 91 - src/HAL/STM32/inc/Conditionals_LCD.h | 22 - src/HAL/STM32/inc/Conditionals_adv.h | 35 - src/HAL/STM32/inc/Conditionals_post.h | 29 - src/HAL/STM32/inc/SanityCheck.h | 57 - src/HAL/STM32/msc_sd.cpp | 130 - src/HAL/STM32/msc_sd.h | 18 - src/HAL/STM32/pinsDebug.h | 283 - src/HAL/STM32/pins_Xref.h | 612 - src/HAL/STM32/sdio.cpp | 451 - src/HAL/STM32/sdio.h | 29 - src/HAL/STM32/spi_pins.h | 38 - src/HAL/STM32/tft/gt911.cpp | 208 - src/HAL/STM32/tft/gt911.h | 120 - src/HAL/STM32/tft/tft_fsmc.cpp | 174 - src/HAL/STM32/tft/tft_fsmc.h | 171 - src/HAL/STM32/tft/tft_ltdc.cpp | 389 - src/HAL/STM32/tft/tft_ltdc.h | 155 - src/HAL/STM32/tft/tft_spi.cpp | 270 - src/HAL/STM32/tft/tft_spi.h | 84 - src/HAL/STM32/tft/xpt2046.cpp | 173 - src/HAL/STM32/tft/xpt2046.h | 81 - src/HAL/STM32/timers.cpp | 330 - src/HAL/STM32/timers.h | 120 - src/HAL/STM32/usb_host.cpp | 119 - src/HAL/STM32/usb_host.h | 60 - src/HAL/STM32/usb_serial.cpp | 60 - src/HAL/STM32/usb_serial.h | 24 - src/HAL/STM32F1/HAL.cpp | 387 - src/HAL/STM32F1/HAL.h | 309 - src/HAL/STM32F1/HAL_SPI.cpp | 171 - src/HAL/STM32F1/MarlinSPI.h | 45 - src/HAL/STM32F1/MarlinSerial.cpp | 204 - src/HAL/STM32F1/MarlinSerial.h | 58 - src/HAL/STM32F1/MinSerial.cpp | 117 - src/HAL/STM32F1/README.md | 11 - src/HAL/STM32F1/SPI.cpp | 738 -- src/HAL/STM32F1/SPI.h | 417 - src/HAL/STM32F1/Servo.cpp | 226 - src/HAL/STM32F1/Servo.h | 61 - src/HAL/STM32F1/build_flags.py | 56 - .../STM32F1/dogm/u8g_com_stm32duino_swspi.cpp | 170 - src/HAL/STM32F1/eeprom_bl24cxx.cpp | 82 - src/HAL/STM32F1/eeprom_flash.cpp | 113 - src/HAL/STM32F1/eeprom_if_iic.cpp | 54 - src/HAL/STM32F1/eeprom_sdcard.cpp | 93 - src/HAL/STM32F1/eeprom_wired.cpp | 89 - src/HAL/STM32F1/endstop_interrupts.h | 80 - src/HAL/STM32F1/fast_pwm.cpp | 85 - src/HAL/STM32F1/fastio.h | 186 - src/HAL/STM32F1/inc/Conditionals_LCD.h | 22 - src/HAL/STM32F1/inc/Conditionals_adv.h | 30 - src/HAL/STM32F1/inc/Conditionals_post.h | 34 - src/HAL/STM32F1/inc/SanityCheck.h | 51 - .../maple_win_usb_driver/maple_serial.inf | 56 - src/HAL/STM32F1/msc_sd.cpp | 98 - src/HAL/STM32F1/msc_sd.h | 26 - src/HAL/STM32F1/onboard_sd.cpp | 571 - src/HAL/STM32F1/onboard_sd.h | 96 - src/HAL/STM32F1/pinsDebug.h | 123 - src/HAL/STM32F1/sdio.cpp | 307 - src/HAL/STM32F1/sdio.h | 155 - src/HAL/STM32F1/spi_pins.h | 57 - src/HAL/STM32F1/tft/tft_fsmc.cpp | 237 - src/HAL/STM32F1/tft/tft_fsmc.h | 71 - src/HAL/STM32F1/tft/tft_spi.cpp | 129 - src/HAL/STM32F1/tft/tft_spi.h | 72 - src/HAL/STM32F1/tft/xpt2046.cpp | 144 - src/HAL/STM32F1/tft/xpt2046.h | 83 - src/HAL/STM32F1/timers.cpp | 183 - src/HAL/STM32F1/timers.h | 201 - src/HAL/TEENSY31_32/HAL.cpp | 129 - src/HAL/TEENSY31_32/HAL.h | 190 - src/HAL/TEENSY31_32/HAL_SPI.cpp | 130 - src/HAL/TEENSY31_32/MarlinSPI.h | 26 - src/HAL/TEENSY31_32/Servo.cpp | 54 - src/HAL/TEENSY31_32/Servo.h | 37 - src/HAL/TEENSY31_32/eeprom.cpp | 76 - src/HAL/TEENSY31_32/endstop_interrupts.h | 73 - src/HAL/TEENSY31_32/fastio.h | 98 - src/HAL/TEENSY31_32/inc/Conditionals_LCD.h | 26 - src/HAL/TEENSY31_32/inc/Conditionals_adv.h | 22 - src/HAL/TEENSY31_32/inc/Conditionals_post.h | 26 - src/HAL/TEENSY31_32/inc/SanityCheck.h | 46 - src/HAL/TEENSY31_32/pinsDebug.h | 1 - src/HAL/TEENSY31_32/spi_pins.h | 27 - src/HAL/TEENSY31_32/timers.cpp | 113 - src/HAL/TEENSY31_32/timers.h | 113 - src/HAL/TEENSY35_36/HAL.cpp | 156 - src/HAL/TEENSY35_36/HAL.h | 197 - src/HAL/TEENSY35_36/HAL_SPI.cpp | 125 - src/HAL/TEENSY35_36/MarlinSPI.h | 26 - src/HAL/TEENSY35_36/Servo.cpp | 59 - src/HAL/TEENSY35_36/Servo.h | 41 - src/HAL/TEENSY35_36/eeprom.cpp | 76 - src/HAL/TEENSY35_36/endstop_interrupts.h | 72 - src/HAL/TEENSY35_36/fastio.h | 98 - src/HAL/TEENSY35_36/inc/Conditionals_LCD.h | 26 - src/HAL/TEENSY35_36/inc/Conditionals_adv.h | 22 - src/HAL/TEENSY35_36/inc/Conditionals_post.h | 26 - src/HAL/TEENSY35_36/inc/SanityCheck.h | 46 - src/HAL/TEENSY35_36/pinsDebug.h | 111 - src/HAL/TEENSY35_36/spi_pins.h | 31 - src/HAL/TEENSY35_36/timers.cpp | 113 - src/HAL/TEENSY35_36/timers.h | 112 - src/HAL/TEENSY40_41/HAL.cpp | 210 - src/HAL/TEENSY40_41/HAL.h | 219 - src/HAL/TEENSY40_41/HAL_SPI.cpp | 141 - src/HAL/TEENSY40_41/MarlinSPI.h | 26 - src/HAL/TEENSY40_41/Servo.cpp | 61 - src/HAL/TEENSY40_41/Servo.h | 43 - src/HAL/TEENSY40_41/eeprom.cpp | 76 - src/HAL/TEENSY40_41/endstop_interrupts.h | 72 - src/HAL/TEENSY40_41/fastio.h | 58 - src/HAL/TEENSY40_41/inc/Conditionals_LCD.h | 26 - src/HAL/TEENSY40_41/inc/Conditionals_adv.h | 22 - src/HAL/TEENSY40_41/inc/Conditionals_post.h | 26 - src/HAL/TEENSY40_41/inc/SanityCheck.h | 42 - src/HAL/TEENSY40_41/pinsDebug.h | 154 - src/HAL/TEENSY40_41/spi_pins.h | 31 - src/HAL/TEENSY40_41/timers.cpp | 106 - src/HAL/TEENSY40_41/timers.h | 117 - src/HAL/platforms.h | 55 - src/HAL/shared/Delay.cpp | 178 - src/HAL/shared/Delay.h | 219 - src/HAL/shared/HAL.cpp | 36 - src/HAL/shared/HAL_SPI.h | 93 - src/HAL/shared/HAL_ST7920.h | 36 - src/HAL/shared/HAL_spi_L6470.cpp | 139 - src/HAL/shared/Marduino.h | 96 - src/HAL/shared/MinSerial.cpp | 33 - src/HAL/shared/MinSerial.h | 79 - src/HAL/shared/backtrace/backtrace.cpp | 106 - src/HAL/shared/backtrace/backtrace.h | 28 - src/HAL/shared/backtrace/unwarm.cpp | 175 - src/HAL/shared/backtrace/unwarm.h | 140 - src/HAL/shared/backtrace/unwarm_arm.cpp | 534 - src/HAL/shared/backtrace/unwarm_thumb.cpp | 1066 -- src/HAL/shared/backtrace/unwarmbytab.cpp | 430 - src/HAL/shared/backtrace/unwarmbytab.h | 31 - src/HAL/shared/backtrace/unwarmmem.cpp | 106 - src/HAL/shared/backtrace/unwarmmem.h | 21 - src/HAL/shared/backtrace/unwinder.cpp | 52 - src/HAL/shared/backtrace/unwinder.h | 172 - src/HAL/shared/backtrace/unwmemaccess.cpp | 210 - src/HAL/shared/backtrace/unwmemaccess.h | 22 - .../shared/cpu_exception/exception_arm.cpp | 379 - .../shared/cpu_exception/exception_hook.cpp | 28 - src/HAL/shared/cpu_exception/exception_hook.h | 54 - src/HAL/shared/eeprom_api.cpp | 30 - src/HAL/shared/eeprom_api.h | 71 - src/HAL/shared/eeprom_if.h | 29 - src/HAL/shared/eeprom_if_i2c.cpp | 102 - src/HAL/shared/eeprom_if_spi.cpp | 84 - src/HAL/shared/esp_wifi.cpp | 43 - src/HAL/shared/esp_wifi.h | 24 - src/HAL/shared/math_32bit.h | 31 - src/HAL/shared/progmem.h | 190 - src/HAL/shared/servo.cpp | 157 - src/HAL/shared/servo.h | 115 - src/HAL/shared/servo_private.h | 98 - src/MarlinCore.cpp | 1668 --- src/MarlinCore.h | 86 - src/core/boards.h | 475 - src/core/bug_on.h | 39 - src/core/debug_out.h | 120 - src/core/debug_section.h | 49 - src/core/drivers.h | 203 - src/core/language.h | 564 - src/core/macros.h | 720 - src/core/millis_t.h | 33 - src/core/multi_language.h | 93 - src/core/serial.cpp | 110 - src/core/serial.h | 374 - src/core/serial_base.h | 258 - src/core/serial_hook.h | 308 - src/core/types.h | 743 -- src/core/utility.cpp | 178 - src/core/utility.h | 94 - src/feature/adc/adc_mcp3426.cpp | 104 - src/feature/adc/adc_mcp3426.h | 38 - src/feature/ammeter.cpp | 54 - src/feature/ammeter.h | 39 - src/feature/babystep.cpp | 67 - src/feature/babystep.h | 82 - src/feature/backlash.cpp | 217 - src/feature/backlash.h | 96 - src/feature/baricuda.cpp | 32 - src/feature/baricuda.h | 25 - src/feature/bedlevel/abl/bbl.cpp | 439 - src/feature/bedlevel/abl/bbl.h | 70 - src/feature/bedlevel/bedlevel.cpp | 217 - src/feature/bedlevel/bedlevel.h | 99 - src/feature/bedlevel/hilbert_curve.cpp | 110 - src/feature/bedlevel/hilbert_curve.h | 32 - .../bedlevel/mbl/mesh_bed_leveling.cpp | 131 - src/feature/bedlevel/mbl/mesh_bed_leveling.h | 125 - src/feature/bedlevel/ubl/ubl.cpp | 300 - src/feature/bedlevel/ubl/ubl.h | 316 - src/feature/bedlevel/ubl/ubl_G29.cpp | 1851 --- src/feature/bedlevel/ubl/ubl_motion.cpp | 492 - src/feature/binary_stream.cpp | 36 - src/feature/binary_stream.h | 456 - src/feature/bltouch.cpp | 196 - src/feature/bltouch.h | 118 - src/feature/cancel_object.cpp | 82 - src/feature/cancel_object.h | 41 - src/feature/caselight.cpp | 103 - src/feature/caselight.h | 57 - src/feature/closedloop.cpp | 44 - src/feature/closedloop.h | 32 - src/feature/controllerfan.cpp | 86 - src/feature/controllerfan.h | 72 - src/feature/cooler.cpp | 48 - src/feature/cooler.h | 109 - src/feature/dac/dac_dac084s085.cpp | 97 - src/feature/dac/dac_dac084s085.h | 31 - src/feature/dac/dac_mcp4728.cpp | 154 - src/feature/dac/dac_mcp4728.h | 82 - src/feature/dac/stepper_dac.cpp | 102 - src/feature/dac/stepper_dac.h | 41 - src/feature/digipot/digipot.h | 33 - src/feature/digipot/digipot_mcp4018.cpp | 108 - src/feature/digipot/digipot_mcp4451.cpp | 103 - src/feature/direct_stepping.cpp | 264 - src/feature/direct_stepping.h | 133 - src/feature/e_parser.cpp | 45 - src/feature/e_parser.h | 225 - src/feature/easythreed_ui.cpp | 236 - src/feature/easythreed_ui.h | 35 - src/feature/encoder_i2c.cpp | 1128 -- src/feature/encoder_i2c.h | 320 - src/feature/ethernet.cpp | 175 - src/feature/ethernet.h | 39 - src/feature/fancheck.cpp | 207 - src/feature/fancheck.h | 89 - src/feature/fanmux.cpp | 55 - src/feature/fanmux.h | 29 - src/feature/filwidth.cpp | 49 - src/feature/filwidth.h | 120 - src/feature/fwretract.cpp | 269 - src/feature/fwretract.h | 89 - src/feature/host_actions.cpp | 204 - src/feature/host_actions.h | 114 - src/feature/hotend_idle.cpp | 91 - src/feature/hotend_idle.h | 37 - src/feature/joystick.cpp | 184 - src/feature/joystick.h | 52 - src/feature/leds/blinkm.cpp | 46 - src/feature/leds/blinkm.h | 31 - src/feature/leds/leds.cpp | 219 - src/feature/leds/leds.h | 216 - src/feature/leds/neopixel.cpp | 168 - src/feature/leds/neopixel.h | 187 - src/feature/leds/pca9533.cpp | 127 - src/feature/leds/pca9533.h | 59 - src/feature/leds/pca9632.cpp | 160 - src/feature/leds/pca9632.h | 37 - src/feature/leds/printer_event_leds.cpp | 93 - src/feature/leds/printer_event_leds.h | 86 - src/feature/leds/tempstat.cpp | 55 - src/feature/leds/tempstat.h | 28 - src/feature/max7219.cpp | 698 - src/feature/max7219.h | 161 - src/feature/meatpack.cpp | 218 - src/feature/meatpack.h | 175 - src/feature/mixing.cpp | 210 - src/feature/mixing.h | 262 - src/feature/mmu/mmu.cpp | 46 - src/feature/mmu/mmu.h | 25 - src/feature/mmu/mmu2-serial-protocol.md | 94 - src/feature/mmu/mmu2.cpp | 1046 -- src/feature/mmu/mmu2.h | 111 - src/feature/password/password.cpp | 61 - src/feature/password/password.h | 57 - src/feature/pause.cpp | 726 -- src/feature/pause.h | 129 - src/feature/power.cpp | 252 - src/feature/power.h | 72 - src/feature/power_monitor.cpp | 78 - src/feature/power_monitor.h | 138 - src/feature/powerloss.cpp | 712 - src/feature/powerloss.h | 225 - src/feature/probe_temp_comp.cpp | 257 - src/feature/probe_temp_comp.h | 116 - src/feature/repeat.cpp | 82 - src/feature/repeat.h | 53 - src/feature/runout.cpp | 147 - src/feature/runout.h | 413 - src/feature/solenoid.cpp | 55 - src/feature/solenoid.h | 26 - src/feature/spindle_laser.cpp | 181 - src/feature/spindle_laser.h | 329 - src/feature/spindle_laser_types.h | 83 - src/feature/stepper_driver_safety.cpp | 117 - src/feature/stepper_driver_safety.h | 28 - src/feature/tmc_util.cpp | 1336 -- src/feature/tmc_util.h | 389 - src/feature/tramming.cpp | 69 - src/feature/tramming.h | 78 - src/feature/twibus.cpp | 237 - src/feature/twibus.h | 254 - src/feature/x_twist.cpp | 67 - src/feature/x_twist.h | 40 - src/feature/z_stepper_align.cpp | 121 - src/feature/z_stepper_align.h | 41 - src/gcode/bedlevel/G26.cpp | 876 -- src/gcode/bedlevel/G35.cpp | 175 - src/gcode/bedlevel/G42.cpp | 73 - src/gcode/bedlevel/M420.cpp | 261 - src/gcode/bedlevel/abl/G29.cpp | 923 -- src/gcode/bedlevel/abl/M421.cpp | 74 - src/gcode/bedlevel/mbl/G29.cpp | 229 - src/gcode/bedlevel/mbl/M421.cpp | 59 - src/gcode/bedlevel/ubl/G29.cpp | 47 - src/gcode/bedlevel/ubl/M421.cpp | 76 - src/gcode/calibrate/G28.cpp | 589 - src/gcode/calibrate/G33.cpp | 698 - src/gcode/calibrate/G34.cpp | 160 - src/gcode/calibrate/G34_M422.cpp | 569 - src/gcode/calibrate/G425.cpp | 764 -- src/gcode/calibrate/G76_M871.cpp | 339 - src/gcode/calibrate/M100.cpp | 373 - src/gcode/calibrate/M12.cpp | 40 - src/gcode/calibrate/M425.cpp | 125 - src/gcode/calibrate/M48.cpp | 285 - src/gcode/calibrate/M665.cpp | 188 - src/gcode/calibrate/M666.cpp | 133 - src/gcode/calibrate/M852.cpp | 106 - src/gcode/config/M200-M205.cpp | 330 - src/gcode/config/M217.cpp | 197 - src/gcode/config/M218.cpp | 72 - src/gcode/config/M220.cpp | 51 - src/gcode/config/M221.cpp | 47 - src/gcode/config/M281.cpp | 78 - src/gcode/config/M301.cpp | 109 - src/gcode/config/M302.cpp | 68 - src/gcode/config/M304.cpp | 53 - src/gcode/config/M305.cpp | 79 - src/gcode/config/M309.cpp | 53 - src/gcode/config/M43.cpp | 386 - src/gcode/config/M540.cpp | 40 - src/gcode/config/M575.cpp | 81 - src/gcode/config/M672.cpp | 98 - src/gcode/config/M92.cpp | 120 - src/gcode/control/M10-M11.cpp | 44 - src/gcode/control/M108_M112_M410.cpp | 56 - src/gcode/control/M111.cpp | 77 - src/gcode/control/M120_M121.cpp | 34 - src/gcode/control/M17_M18_M84.cpp | 246 - src/gcode/control/M211.cpp | 54 - src/gcode/control/M226.cpp | 60 - src/gcode/control/M280.cpp | 76 - src/gcode/control/M282.cpp | 45 - src/gcode/control/M3-M5.cpp | 156 - src/gcode/control/M350_M351.cpp | 74 - src/gcode/control/M380_M381.cpp | 56 - src/gcode/control/M400.cpp | 33 - src/gcode/control/M42.cpp | 135 - src/gcode/control/M605.cpp | 189 - src/gcode/control/M7-M9.cpp | 77 - src/gcode/control/M80_M81.cpp | 120 - src/gcode/control/M85.cpp | 42 - src/gcode/control/M993_M994.cpp | 88 - src/gcode/control/M997.cpp | 42 - src/gcode/control/M999.cpp | 45 - src/gcode/control/T.cpp | 70 - src/gcode/eeprom/M500-M504.cpp | 124 - src/gcode/feature/L6470/M122.cpp | 151 - src/gcode/feature/L6470/M906.cpp | 380 - src/gcode/feature/L6470/M916-M918.cpp | 650 - src/gcode/feature/adc/M3426.cpp | 68 - src/gcode/feature/advance/M900.cpp | 159 - src/gcode/feature/baricuda/M126-M129.cpp | 58 - src/gcode/feature/camera/M240.cpp | 195 - src/gcode/feature/cancel/M486.cpp | 57 - src/gcode/feature/caselight/M355.cpp | 73 - src/gcode/feature/clean/G12.cpp | 83 - src/gcode/feature/controllerfan/M710.cpp | 81 - src/gcode/feature/digipot/M907-M910.cpp | 173 - src/gcode/feature/filwidth/M404-M407.cpp | 71 - src/gcode/feature/fwretract/G10_G11.cpp | 42 - src/gcode/feature/fwretract/M207-M209.cpp | 77 - src/gcode/feature/i2c/M260_M261.cpp | 77 - src/gcode/feature/leds/M150.cpp | 91 - src/gcode/feature/leds/M7219.cpp | 93 - src/gcode/feature/macro/M810-M819.cpp | 65 - src/gcode/feature/mixing/M163-M165.cpp | 101 - src/gcode/feature/mixing/M166.cpp | 103 - src/gcode/feature/network/M552-M554.cpp | 132 - src/gcode/feature/password/M510-M512.cpp | 83 - src/gcode/feature/pause/G27.cpp | 40 - src/gcode/feature/pause/G60.cpp | 66 - src/gcode/feature/pause/G61.cpp | 95 - src/gcode/feature/pause/M125.cpp | 100 - src/gcode/feature/pause/M600.cpp | 175 - src/gcode/feature/pause/M603.cpp | 83 - src/gcode/feature/pause/M701_M702.cpp | 240 - src/gcode/feature/power_monitor/M430.cpp | 68 - src/gcode/feature/powerloss/M1000.cpp | 98 - src/gcode/feature/powerloss/M413.cpp | 64 - src/gcode/feature/prusa_MMU2/M403.cpp | 49 - src/gcode/feature/runout/M412.cpp | 81 - src/gcode/feature/trinamic/M122.cpp | 64 - src/gcode/feature/trinamic/M569.cpp | 208 - src/gcode/feature/trinamic/M906.cpp | 302 - src/gcode/feature/trinamic/M911-M914.cpp | 568 - src/gcode/feature/trinamic/M919.cpp | 266 - src/gcode/gcode.cpp | 1221 -- src/gcode/gcode.h | 1251 -- src/gcode/gcode_d.cpp | 302 - src/gcode/geometry/G17-G19.cpp | 53 - src/gcode/geometry/G53-G59.cpp | 99 - src/gcode/geometry/G92.cpp | 132 - src/gcode/geometry/M206_M428.cpp | 103 - src/gcode/host/M110.cpp | 34 - src/gcode/host/M113.cpp | 45 - src/gcode/host/M114.cpp | 231 - src/gcode/host/M115.cpp | 221 - src/gcode/host/M118.cpp | 60 - src/gcode/host/M119.cpp | 33 - src/gcode/host/M154.cpp | 40 - src/gcode/host/M16.cpp | 41 - src/gcode/host/M360.cpp | 193 - src/gcode/host/M876.cpp | 40 - src/gcode/lcd/M0_M1.cpp | 95 - src/gcode/lcd/M117.cpp | 42 - src/gcode/lcd/M145.cpp | 82 - src/gcode/lcd/M250.cpp | 45 - src/gcode/lcd/M255.cpp | 58 - src/gcode/lcd/M256.cpp | 44 - src/gcode/lcd/M300.cpp | 45 - src/gcode/lcd/M414.cpp | 51 - src/gcode/lcd/M73.cpp | 62 - src/gcode/lcd/M995.cpp | 48 - src/gcode/motion/G0_G1.cpp | 132 - src/gcode/motion/G2_G3.cpp | 457 - src/gcode/motion/G4.cpp | 44 - src/gcode/motion/G5.cpp | 69 - src/gcode/motion/G6.cpp | 62 - src/gcode/motion/G80.cpp | 38 - src/gcode/motion/M290.cpp | 134 - src/gcode/parser.cpp | 432 - src/gcode/parser.h | 442 - src/gcode/probe/G30.cpp | 96 - src/gcode/probe/G31_G32.cpp | 40 - src/gcode/probe/G38.cpp | 133 - src/gcode/probe/M401_M402.cpp | 69 - src/gcode/probe/M423.cpp | 99 - src/gcode/probe/M851.cpp | 102 - src/gcode/probe/M951.cpp | 71 - src/gcode/queue.cpp | 729 -- src/gcode/queue.h | 270 - src/gcode/scara/M360-M364.cpp | 81 - src/gcode/sd/M1001.cpp | 118 - src/gcode/sd/M20.cpp | 49 - src/gcode/sd/M21_M22.cpp | 55 - src/gcode/sd/M23.cpp | 44 - src/gcode/sd/M24_M25.cpp | 128 - src/gcode/sd/M26.cpp | 38 - src/gcode/sd/M27.cpp | 52 - src/gcode/sd/M28_M29.cpp | 72 - src/gcode/sd/M30.cpp | 40 - src/gcode/sd/M32.cpp | 59 - src/gcode/sd/M33.cpp | 48 - src/gcode/sd/M34.cpp | 42 - src/gcode/sd/M524.cpp | 54 - src/gcode/sd/M808.cpp | 51 - src/gcode/sd/M928.cpp | 39 - src/gcode/stats/M31.cpp | 39 - src/gcode/stats/M75-M78.cpp | 87 - src/gcode/temp/M104_M109.cpp | 138 - src/gcode/temp/M105.cpp | 47 - src/gcode/temp/M106_M107.cpp | 115 - src/gcode/temp/M123.cpp | 48 - src/gcode/temp/M140_M190.cpp | 99 - src/gcode/temp/M141_M191.cpp | 77 - src/gcode/temp/M143_M193.cpp | 67 - src/gcode/temp/M155.cpp | 40 - src/gcode/temp/M192.cpp | 56 - src/gcode/temp/M303.cpp | 101 - src/gcode/temp/M306.cpp | 82 - src/gcode/units/G20_G21.cpp | 39 - src/gcode/units/M149.cpp | 45 - src/gcode/units/M82_M83.cpp | 39 - src/inc/Conditionals_LCD.h | 1488 --- src/inc/Conditionals_adv.h | 1034 -- src/inc/Conditionals_post.h | 3526 ----- src/inc/MarlinConfig.h | 59 - src/inc/MarlinConfigPre.h | 62 - src/inc/SanityCheck.h | 3980 ------ src/inc/Version.h | 122 - src/inc/Warnings.cpp | 618 - src/lcd/HD44780/lcdprint_hd44780.cpp | 1144 -- src/lcd/HD44780/marlinui_HD44780.cpp | 1595 --- src/lcd/HD44780/marlinui_HD44780.h | 107 - src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp | 1142 -- src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp | 1094 -- src/lcd/TFTGLCD/marlinui_TFTGLCD.h | 72 - src/lcd/buttons.h | 226 - src/lcd/dogm/HAL_LCD_class_defines.h | 136 - src/lcd/dogm/HAL_LCD_com_defines.h | 132 - src/lcd/dogm/dogm_Bootscreen.h | 540 - src/lcd/dogm/dogm_Statusscreen.h | 765 -- src/lcd/dogm/fontdata/fontdata_6x9_marlin.h | 189 - src/lcd/dogm/fontdata/fontdata_ISO10646_1.h | 305 - src/lcd/dogm/fontdata/langdata.h | 23 - src/lcd/dogm/fontdata/langdata_an.h | 10 - src/lcd/dogm/fontdata/langdata_bg.h | 78 - src/lcd/dogm/fontdata/langdata_ca.h | 10 - src/lcd/dogm/fontdata/langdata_cz.h | 55 - src/lcd/dogm/fontdata/langdata_da.h | 10 - src/lcd/dogm/fontdata/langdata_de.h | 10 - src/lcd/dogm/fontdata/langdata_el.h | 91 - src/lcd/dogm/fontdata/langdata_el_CY.h | 91 - src/lcd/dogm/fontdata/langdata_en.h | 10 - src/lcd/dogm/fontdata/langdata_es.h | 10 - src/lcd/dogm/fontdata/langdata_eu.h | 10 - src/lcd/dogm/fontdata/langdata_fi.h | 10 - src/lcd/dogm/fontdata/langdata_fr.h | 10 - src/lcd/dogm/fontdata/langdata_gl.h | 10 - src/lcd/dogm/fontdata/langdata_hr.h | 33 - src/lcd/dogm/fontdata/langdata_hu.h | 16 - src/lcd/dogm/fontdata/langdata_it.h | 10 - src/lcd/dogm/fontdata/langdata_jp_kana.h | 112 - src/lcd/dogm/fontdata/langdata_ko_KR.h | 548 - src/lcd/dogm/fontdata/langdata_nl.h | 10 - src/lcd/dogm/fontdata/langdata_pl.h | 41 - src/lcd/dogm/fontdata/langdata_pt.h | 10 - src/lcd/dogm/fontdata/langdata_pt_br.h | 10 - src/lcd/dogm/fontdata/langdata_ro.h | 10 - src/lcd/dogm/fontdata/langdata_ru.h | 74 - src/lcd/dogm/fontdata/langdata_sk.h | 50 - src/lcd/dogm/fontdata/langdata_test.h | 232 - src/lcd/dogm/fontdata/langdata_tr.h | 28 - src/lcd/dogm/fontdata/langdata_uk.h | 86 - src/lcd/dogm/fontdata/langdata_vi.h | 228 - src/lcd/dogm/fontdata/langdata_zh_CN.h | 1824 --- src/lcd/dogm/fontdata/langdata_zh_TW.h | 1522 --- src/lcd/dogm/lcdprint_u8g.cpp | 56 - src/lcd/dogm/marlinui_DOGM.cpp | 754 -- src/lcd/dogm/marlinui_DOGM.h | 234 - src/lcd/dogm/status/ammeter.h | 68 - src/lcd/dogm/status/bed.h | 138 - src/lcd/dogm/status/chamber.h | 89 - src/lcd/dogm/status/combined.h | 315 - src/lcd/dogm/status/cooler.h | 119 - src/lcd/dogm/status/cutter.h | 123 - src/lcd/dogm/status/fan.h | 443 - src/lcd/dogm/status/hotend.h | 759 -- src/lcd/dogm/status_screen_DOGM.cpp | 1031 -- src/lcd/dogm/status_screen_lite_ST7920.cpp | 920 -- src/lcd/dogm/status_screen_lite_ST7920.h | 106 - .../u8g_dev_ssd1306_sh1106_128x64_I2C.cpp | 302 - src/lcd/dogm/u8g_dev_ssd1309_12864.cpp | 129 - src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp | 241 - src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp | 208 - .../dogm/u8g_dev_tft_upscale_from_128x64.cpp | 559 - src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp | 213 - src/lcd/dogm/u8g_fontutf8.cpp | 315 - src/lcd/dogm/u8g_fontutf8.h | 40 - .../dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp | 196 - src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h | 53 - src/lcd/e3v2/README.md | 7 - src/lcd/e3v2/common/dwin_api.cpp | 471 - src/lcd/e3v2/common/dwin_api.h | 270 - src/lcd/e3v2/common/dwin_color.h | 44 - src/lcd/e3v2/common/dwin_font.h | 40 - src/lcd/e3v2/common/dwin_set.h | 147 - src/lcd/e3v2/common/encoder.cpp | 253 - src/lcd/e3v2/common/encoder.h | 111 - src/lcd/e3v2/creality/dwin.cpp | 4317 ------ src/lcd/e3v2/creality/dwin.h | 249 - src/lcd/e3v2/creality/dwin_lcd.cpp | 84 - src/lcd/e3v2/creality/dwin_lcd.h | 47 - src/lcd/e3v2/jyersui/README.md | 7 - src/lcd/e3v2/jyersui/dwin.cpp | 4848 ------- src/lcd/e3v2/jyersui/dwin.h | 245 - src/lcd/e3v2/jyersui/dwin_lcd.cpp | 64 - src/lcd/e3v2/jyersui/dwin_lcd.h | 34 - src/lcd/e3v2/marlinui/dwin_lcd.cpp | 63 - src/lcd/e3v2/marlinui/dwin_lcd.h | 82 - src/lcd/e3v2/marlinui/dwin_string.cpp | 182 - src/lcd/e3v2/marlinui/dwin_string.h | 1050 -- src/lcd/e3v2/marlinui/lcdprint_dwin.cpp | 190 - src/lcd/e3v2/marlinui/lcdprint_dwin.h | 30 - src/lcd/e3v2/marlinui/marlinui_dwin.h | 146 - src/lcd/e3v2/marlinui/ui_common.cpp | 594 - src/lcd/e3v2/marlinui/ui_status_480x272.cpp | 474 - src/lcd/e3v2/proui/base64.hpp | 208 - src/lcd/e3v2/proui/bedlevel_tools.cpp | 286 - src/lcd/e3v2/proui/bedlevel_tools.h | 77 - src/lcd/e3v2/proui/dwin.cpp | 3875 ------ src/lcd/e3v2/proui/dwin.h | 293 - src/lcd/e3v2/proui/dwin_defines.h | 122 - src/lcd/e3v2/proui/dwin_lcd.cpp | 160 - src/lcd/e3v2/proui/dwin_lcd.h | 76 - src/lcd/e3v2/proui/dwin_popup.cpp | 95 - src/lcd/e3v2/proui/dwin_popup.h | 73 - src/lcd/e3v2/proui/dwinui.cpp | 372 - src/lcd/e3v2/proui/dwinui.h | 562 - src/lcd/e3v2/proui/endstop_diag.cpp | 113 - src/lcd/e3v2/proui/endstop_diag.h | 37 - src/lcd/e3v2/proui/gcode_preview.cpp | 258 - src/lcd/e3v2/proui/gcode_preview.h | 27 - src/lcd/e3v2/proui/lockscreen.cpp | 80 - src/lcd/e3v2/proui/lockscreen.h | 46 - src/lcd/e3v2/proui/menus.cpp | 566 - src/lcd/e3v2/proui/menus.h | 188 - src/lcd/e3v2/proui/meshviewer.cpp | 144 - src/lcd/e3v2/proui/meshviewer.h | 40 - src/lcd/e3v2/proui/plot.cpp | 99 - src/lcd/e3v2/proui/plot.h | 54 - src/lcd/e3v2/proui/printstats.cpp | 82 - src/lcd/e3v2/proui/printstats.h | 39 - .../extui/anycubic_chiron/FileNavigator.cpp | 258 - src/lcd/extui/anycubic_chiron/FileNavigator.h | 61 - src/lcd/extui/anycubic_chiron/Tunes.cpp | 61 - src/lcd/extui/anycubic_chiron/Tunes.h | 224 - .../extui/anycubic_chiron/chiron_extui.cpp | 137 - src/lcd/extui/anycubic_chiron/chiron_tft.cpp | 985 -- src/lcd/extui/anycubic_chiron/chiron_tft.h | 89 - .../extui/anycubic_chiron/chiron_tft_defs.h | 182 - .../extui/anycubic_i3mega/anycubic_extui.cpp | 124 - .../anycubic_i3mega/anycubic_i3mega_lcd.cpp | 1026 -- .../anycubic_i3mega/anycubic_i3mega_lcd.h | 95 - src/lcd/extui/dgus/DGUSDisplay.cpp | 271 - src/lcd/extui/dgus/DGUSDisplay.h | 125 - src/lcd/extui/dgus/DGUSDisplayDef.h | 57 - src/lcd/extui/dgus/DGUSScreenHandler.cpp | 738 -- src/lcd/extui/dgus/DGUSScreenHandler.h | 73 - src/lcd/extui/dgus/DGUSScreenHandlerBase.h | 241 - src/lcd/extui/dgus/DGUSVPVariable.h | 49 - src/lcd/extui/dgus/dgus_extui.cpp | 163 - src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp | 478 - src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h | 296 - .../extui/dgus/fysetc/DGUSScreenHandler.cpp | 423 - src/lcd/extui/dgus/fysetc/DGUSScreenHandler.h | 31 - src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp | 471 - src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h | 292 - .../extui/dgus/hiprecy/DGUSScreenHandler.cpp | 423 - .../extui/dgus/hiprecy/DGUSScreenHandler.h | 31 - src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp | 802 -- src/lcd/extui/dgus/mks/DGUSDisplayDef.h | 712 - src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp | 2028 --- src/lcd/extui/dgus/mks/DGUSScreenHandler.h | 116 - src/lcd/extui/dgus/origin/DGUSDisplayDef.cpp | 279 - src/lcd/extui/dgus/origin/DGUSDisplayDef.h | 282 - .../extui/dgus/origin/DGUSScreenHandler.cpp | 423 - src/lcd/extui/dgus/origin/DGUSScreenHandler.h | 31 - src/lcd/extui/dgus_reloaded/DGUSDisplay.cpp | 409 - src/lcd/extui/dgus_reloaded/DGUSDisplay.h | 174 - src/lcd/extui/dgus_reloaded/DGUSRxHandler.cpp | 1043 -- src/lcd/extui/dgus_reloaded/DGUSRxHandler.h | 122 - .../extui/dgus_reloaded/DGUSScreenHandler.cpp | 517 - .../extui/dgus_reloaded/DGUSScreenHandler.h | 151 - .../extui/dgus_reloaded/DGUSSetupHandler.cpp | 209 - .../extui/dgus_reloaded/DGUSSetupHandler.h | 42 - src/lcd/extui/dgus_reloaded/DGUSTxHandler.cpp | 618 - src/lcd/extui/dgus_reloaded/DGUSTxHandler.h | 126 - .../extui/dgus_reloaded/config/DGUS_Addr.h | 173 - .../dgus_reloaded/config/DGUS_Constants.h | 96 - .../extui/dgus_reloaded/config/DGUS_Control.h | 50 - .../extui/dgus_reloaded/config/DGUS_Data.h | 148 - .../extui/dgus_reloaded/config/DGUS_Screen.h | 52 - .../definition/DGUS_ScreenAddrList.cpp | 240 - .../definition/DGUS_ScreenAddrList.h | 32 - .../definition/DGUS_ScreenSetup.cpp | 57 - .../definition/DGUS_ScreenSetup.h | 31 - .../extui/dgus_reloaded/definition/DGUS_VP.h | 40 - .../dgus_reloaded/definition/DGUS_VPList.cpp | 368 - .../dgus_reloaded/definition/DGUS_VPList.h | 26 - .../dgus_reloaded/dgus_reloaded_extui.cpp | 143 - src/lcd/extui/example/example.cpp | 137 - .../archim2-flash/flash_storage.cpp | 552 - .../archim2-flash/flash_storage.h | 106 - .../archim2-flash/media_file_reader.cpp | 61 - .../archim2-flash/media_file_reader.h | 46 - .../bioprinter/advanced_settings.cpp | 102 - .../bioprinter/advanced_settings.h | 32 - .../bioprinter/confirm_home_e.cpp | 56 - .../bioprinter/confirm_home_e.h | 32 - .../bioprinter/confirm_home_xyz.cpp | 55 - .../bioprinter/confirm_home_xyz.h | 32 - .../bioprinter/main_menu.cpp | 85 - .../ftdi_eve_touch_ui/bioprinter/main_menu.h | 32 - .../bioprinter/printing_dialog_box.cpp | 151 - .../bioprinter/printing_dialog_box.h | 44 - .../ftdi_eve_touch_ui/bioprinter/screens.h | 105 - .../bioprinter/status_screen.cpp | 376 - .../bioprinter/status_screen.h | 56 - .../bioprinter/tune_menu.cpp | 76 - .../ftdi_eve_touch_ui/bioprinter/tune_menu.h | 35 - .../bioprinter/ui_landscape.h | 61 - .../bioprinter/ui_portrait.h | 54 - .../cocoa_press/advanced_settings_menu.cpp | 95 - .../cocoa_press/advanced_settings_menu.h | 32 - .../cocoa_press/cocoa_press_ui.h | 60 - .../cocoa_press/leveling_menu.cpp | 91 - .../cocoa_press/leveling_menu.h | 32 - .../cocoa_press/load_chocolate.cpp | 218 - .../cocoa_press/load_chocolate.h | 47 - .../cocoa_press/main_menu.cpp | 100 - .../ftdi_eve_touch_ui/cocoa_press/main_menu.h | 33 - .../cocoa_press/move_e_screen.cpp | 63 - .../cocoa_press/move_e_screen.h | 33 - .../cocoa_press/move_xyz_screen.cpp | 52 - .../cocoa_press/move_xyz_screen.h | 33 - .../cocoa_press/preheat_menu.cpp | 116 - .../cocoa_press/preheat_menu.h | 31 - .../cocoa_press/preheat_screen.cpp | 161 - .../cocoa_press/preheat_screen.h | 46 - .../ftdi_eve_touch_ui/cocoa_press/screens.h | 134 - .../cocoa_press/status_screen.cpp | 307 - .../cocoa_press/status_screen.h | 57 - src/lcd/extui/ftdi_eve_touch_ui/compat.h | 53 - src/lcd/extui/ftdi_eve_touch_ui/config.h | 30 - .../ftdi_eve_touch_ui/ftdi_eve_extui.cpp | 160 - .../ftdi_eve_lib/LICENSE.txt | 674 - .../ftdi_eve_touch_ui/ftdi_eve_lib/README.md | 28 - .../ftdi_eve_lib/basic/boards.h | 281 - .../ftdi_eve_lib/basic/commands.cpp | 1218 -- .../ftdi_eve_lib/basic/commands.h | 263 - .../ftdi_eve_lib/basic/constants.h | 415 - .../ftdi_eve_lib/basic/display_list.h | 118 - .../ftdi_eve_lib/basic/ftdi_basic.h | 40 - .../ftdi_eve_lib/basic/registers_ft800.h | 150 - .../ftdi_eve_lib/basic/registers_ft810.h | 187 - .../ftdi_eve_lib/basic/resolutions.h | 142 - .../ftdi_eve_lib/basic/spi.cpp | 175 - .../ftdi_eve_lib/basic/spi.h | 136 - .../ftdi_eve_touch_ui/ftdi_eve_lib/compat.h | 330 - .../ftdi_eve_lib/extended/adjuster_widget.cpp | 60 - .../ftdi_eve_lib/extended/adjuster_widget.h | 40 - .../ftdi_eve_lib/extended/arrows.cpp | 52 - .../ftdi_eve_lib/extended/arrows.h | 28 - .../ftdi_eve_lib/extended/bitmap_info.h | 49 - .../extended/circular_progress.cpp | 108 - .../ftdi_eve_lib/extended/circular_progress.h | 27 - .../extended/command_processor.cpp | 41 - .../ftdi_eve_lib/extended/command_processor.h | 452 - .../ftdi_eve_lib/extended/dl_cache.cpp | 174 - .../ftdi_eve_lib/extended/dl_cache.h | 70 - .../ftdi_eve_lib/extended/event_loop.cpp | 226 - .../ftdi_eve_lib/extended/event_loop.h | 74 - .../ftdi_eve_lib/extended/ftdi_extended.h | 56 - .../ftdi_eve_lib/extended/grid_layout.h | 123 - .../ftdi_eve_lib/extended/poly_ui.h | 408 - .../ftdi_eve_lib/extended/polygon.h | 96 - .../ftdi_eve_lib/extended/rgb_t.h | 84 - .../ftdi_eve_lib/extended/screen_types.cpp | 104 - .../ftdi_eve_lib/extended/screen_types.h | 243 - .../ftdi_eve_lib/extended/sound_list.h | 38 - .../ftdi_eve_lib/extended/sound_player.cpp | 108 - .../ftdi_eve_lib/extended/sound_player.h | 70 - .../ftdi_eve_lib/extended/text_box.cpp | 149 - .../ftdi_eve_lib/extended/text_box.h | 32 - .../ftdi_eve_lib/extended/text_ellipsis.cpp | 87 - .../ftdi_eve_lib/extended/text_ellipsis.h | 31 - .../ftdi_eve_lib/extended/tiny_timer.cpp | 39 - .../ftdi_eve_lib/extended/tiny_timer.h | 56 - .../ftdi_eve_lib/extended/unicode/README.txt | 40 - .../extended/unicode/cyrillic_char_set.cpp | 139 - .../extended/unicode/cyrillic_char_set.h | 32 - .../unicode/cyrillic_char_set_bitmap_31.h | 2529 ---- .../extended/unicode/font_bitmaps.cpp | 58 - .../extended/unicode/font_bitmaps.h | 30 - .../cyrillic_char_set_bitmap_31.png | Bin 34122 -> 0 bytes .../cyrillic_char_set_bitmap_31.svg | 535 - .../unicode/font_bitmaps/romfont_31.pbm | Bin 23570 -> 0 bytes .../unicode/font_bitmaps/romfont_31.png | Bin 16643 -> 0 bytes .../western_char_set_bitmap_31.png | Bin 24548 -> 0 bytes .../western_char_set_bitmap_31.svg | 443 - .../extended/unicode/font_size_t.cpp | 46 - .../extended/unicode/font_size_t.h | 55 - .../extended/unicode/standard_char_set.cpp | 107 - .../extended/unicode/standard_char_set.h | 30 - .../ftdi_eve_lib/extended/unicode/unicode.cpp | 247 - .../ftdi_eve_lib/extended/unicode/unicode.h | 112 - .../extended/unicode/western_char_set.cpp | 455 - .../extended/unicode/western_char_set.h | 31 - .../unicode/western_char_set_bitmap_31.h | 1315 -- .../ftdi_eve_lib/ftdi_eve_lib.h | 27 - .../ftdi_eve_lib/scripts/file2cpp.py | 47 - .../ftdi_eve_lib/scripts/font2cpp.py | 108 - .../ftdi_eve_lib/scripts/img2cpp.py | 113 - .../ftdi_eve_lib/scripts/svg2cpp.py | 280 - .../generic/about_screen.cpp | 116 - .../ftdi_eve_touch_ui/generic/about_screen.h | 33 - .../generic/advanced_settings_menu.cpp | 155 - .../generic/advanced_settings_menu.h | 32 - .../generic/alert_dialog_box.cpp | 71 - .../generic/alert_dialog_box.h | 39 - .../generic/backlash_compensation_screen.cpp | 75 - .../generic/backlash_compensation_screen.h | 32 - .../base_numeric_adjustment_screen.cpp | 391 - .../generic/base_numeric_adjustment_screen.h | 87 - .../ftdi_eve_touch_ui/generic/base_screen.cpp | 87 - .../ftdi_eve_touch_ui/generic/base_screen.h | 43 - .../generic/bed_mesh_base.cpp | 224 - .../ftdi_eve_touch_ui/generic/bed_mesh_base.h | 46 - .../generic/bed_mesh_edit_screen.cpp | 200 - .../generic/bed_mesh_edit_screen.h | 50 - .../generic/bed_mesh_view_screen.cpp | 165 - .../generic/bed_mesh_view_screen.h | 47 - .../ftdi_eve_touch_ui/generic/boot_screen.cpp | 130 - .../ftdi_eve_touch_ui/generic/boot_screen.h | 35 - .../generic/case_light_screen.cpp | 61 - .../generic/case_light_screen.h | 31 - .../generic/change_filament_screen.cpp | 331 - .../generic/change_filament_screen.h | 51 - .../confirm_abort_print_dialog_box.cpp | 52 - .../generic/confirm_abort_print_dialog_box.h | 32 - .../confirm_auto_calibration_dialog_box.cpp | 47 - .../confirm_auto_calibration_dialog_box.h | 32 - .../confirm_erase_flash_dialog_box.cpp | 53 - .../generic/confirm_erase_flash_dialog_box.h | 32 - .../confirm_start_print_dialog_box.cpp | 66 - .../generic/confirm_start_print_dialog_box.h | 42 - .../confirm_user_request_alert_box.cpp | 69 - .../generic/confirm_user_request_alert_box.h | 34 - .../generic/custom_user_menus.cpp | 211 - .../generic/custom_user_menus.h | 31 - .../generic/default_acceleration_screen.cpp | 62 - .../generic/default_acceleration_screen.h | 32 - .../generic/developer_menu.cpp | 149 - .../generic/developer_menu.h | 32 - .../generic/dialog_box_base_class.cpp | 83 - .../generic/dialog_box_base_class.h | 42 - .../generic/display_tuning_screen.cpp | 60 - .../generic/display_tuning_screen.h | 32 - .../generic/endstop_state_screen.cpp | 143 - .../generic/endstop_state_screen.h | 35 - .../generic/feedrate_percent_screen.cpp | 51 - .../generic/feedrate_percent_screen.h | 32 - .../generic/filament_menu.cpp | 84 - .../ftdi_eve_touch_ui/generic/filament_menu.h | 32 - .../generic/filament_runout_screen.cpp | 64 - .../generic/filament_runout_screen.h | 32 - .../generic/files_screen.cpp | 287 - .../ftdi_eve_touch_ui/generic/files_screen.h | 68 - .../generic/flow_percent_screen.cpp | 50 - .../generic/flow_percent_screen.h | 31 - .../generic/interface_settings_screen.cpp | 286 - .../generic/interface_settings_screen.h | 67 - .../generic/interface_sounds_screen.cpp | 125 - .../generic/interface_sounds_screen.h | 55 - .../ftdi_eve_touch_ui/generic/jerk_screen.cpp | 64 - .../ftdi_eve_touch_ui/generic/jerk_screen.h | 32 - .../generic/junction_deviation_screen.cpp | 53 - .../generic/junction_deviation_screen.h | 32 - .../ftdi_eve_touch_ui/generic/kill_screen.cpp | 58 - .../ftdi_eve_touch_ui/generic/kill_screen.h | 33 - .../generic/language_menu.cpp | 66 - .../ftdi_eve_touch_ui/generic/language_menu.h | 32 - .../generic/leveling_menu.cpp | 140 - .../ftdi_eve_touch_ui/generic/leveling_menu.h | 32 - .../generic/linear_advance_screen.cpp | 76 - .../generic/linear_advance_screen.h | 32 - .../ftdi_eve_touch_ui/generic/lock_screen.cpp | 197 - .../ftdi_eve_touch_ui/generic/lock_screen.h | 53 - .../ftdi_eve_touch_ui/generic/main_menu.cpp | 130 - .../ftdi_eve_touch_ui/generic/main_menu.h | 33 - .../generic/max_acceleration_screen.cpp | 84 - .../generic/max_acceleration_screen.h | 32 - .../generic/max_velocity_screen.cpp | 88 - .../generic/max_velocity_screen.h | 32 - .../generic/media_player_screen.cpp | 167 - .../generic/media_player_screen.h | 40 - .../generic/move_axis_screen.cpp | 143 - .../generic/move_axis_screen.h | 49 - .../generic/nozzle_offsets_screen.cpp | 72 - .../generic/nozzle_offsets_screen.h | 33 - .../generic/nudge_nozzle_screen.cpp | 124 - .../generic/nudge_nozzle_screen.h | 44 - .../generic/restore_failsafe_dialog_box.cpp | 50 - .../generic/restore_failsafe_dialog_box.h | 32 - .../generic/save_settings_dialog_box.cpp | 67 - .../generic/save_settings_dialog_box.h | 39 - .../extui/ftdi_eve_touch_ui/generic/screens.h | 224 - .../generic/spinner_dialog_box.cpp | 108 - .../generic/spinner_dialog_box.h | 48 - .../generic/statistics_screen.cpp | 77 - .../generic/statistics_screen.h | 32 - .../generic/status_screen.cpp | 466 - .../ftdi_eve_touch_ui/generic/status_screen.h | 47 - .../stepper_bump_sensitivity_screen.cpp | 58 - .../generic/stepper_bump_sensitivity_screen.h | 32 - .../generic/stepper_current_screen.cpp | 126 - .../generic/stepper_current_screen.h | 32 - .../generic/steps_screen.cpp | 85 - .../ftdi_eve_touch_ui/generic/steps_screen.h | 32 - .../generic/stress_test_screen.cpp | 148 - .../generic/stress_test_screen.h | 48 - .../generic/string_format.cpp | 110 - .../ftdi_eve_touch_ui/generic/string_format.h | 29 - .../generic/temperature_screen.cpp | 113 - .../generic/temperature_screen.h | 32 - .../generic/touch_calibration_screen.cpp | 93 - .../generic/touch_calibration_screen.h | 34 - .../generic/touch_registers_screen.cpp | 84 - .../generic/touch_registers_screen.h | 32 - .../ftdi_eve_touch_ui/generic/tune_menu.cpp | 155 - .../ftdi_eve_touch_ui/generic/tune_menu.h | 35 - .../generic/widget_demo_screen.cpp | 157 - .../generic/widget_demo_screen.h | 34 - .../generic/z_offset_screen.cpp | 111 - .../generic/z_offset_screen.h | 43 - .../ftdi_eve_touch_ui/language/language.cpp | 27 - .../ftdi_eve_touch_ui/language/language.h | 25 - .../ftdi_eve_touch_ui/language/language_en.h | 177 - .../extui/ftdi_eve_touch_ui/pin_mappings.h | 144 - src/lcd/extui/ftdi_eve_touch_ui/screen_data.h | 69 - src/lcd/extui/ftdi_eve_touch_ui/screens.cpp | 126 - src/lcd/extui/ftdi_eve_touch_ui/screens.h | 50 - .../extui/ftdi_eve_touch_ui/theme/bitmaps.h | 259 - .../theme/bootscreen_logo_portrait.h | 41 - .../extui/ftdi_eve_touch_ui/theme/colors.h | 193 - src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h | 80 - .../theme/marlin_bootscreen_landscape.h | 38 - .../theme/marlin_bootscreen_portrait.h | 38 - .../extui/ftdi_eve_touch_ui/theme/sounds.cpp | 410 - .../extui/ftdi_eve_touch_ui/theme/sounds.h | 43 - src/lcd/extui/ftdi_eve_touch_ui/theme/theme.h | 28 - src/lcd/extui/malyan/malyan.cpp | 421 - src/lcd/extui/malyan/malyan.h | 53 - src/lcd/extui/malyan/malyan_extui.cpp | 168 - src/lcd/extui/mks_ui/SPIFlashStorage.cpp | 321 - src/lcd/extui/mks_ui/SPIFlashStorage.h | 108 - src/lcd/extui/mks_ui/SPI_TFT.cpp | 86 - src/lcd/extui/mks_ui/SPI_TFT.h | 38 - src/lcd/extui/mks_ui/draw_about.cpp | 65 - src/lcd/extui/mks_ui/draw_about.h | 33 - .../mks_ui/draw_acceleration_settings.cpp | 169 - .../extui/mks_ui/draw_acceleration_settings.h | 33 - .../extui/mks_ui/draw_advance_settings.cpp | 97 - src/lcd/extui/mks_ui/draw_advance_settings.h | 33 - .../draw_auto_level_offset_settings.cpp | 90 - .../mks_ui/draw_auto_level_offset_settings.h | 33 - src/lcd/extui/mks_ui/draw_baby_stepping.cpp | 180 - src/lcd/extui/mks_ui/draw_baby_stepping.h | 35 - src/lcd/extui/mks_ui/draw_change_speed.cpp | 225 - src/lcd/extui/mks_ui/draw_change_speed.h | 39 - src/lcd/extui/mks_ui/draw_cloud_bind.cpp | 205 - src/lcd/extui/mks_ui/draw_cloud_bind.h | 37 - src/lcd/extui/mks_ui/draw_dialog.cpp | 555 - src/lcd/extui/mks_ui/draw_dialog.h | 85 - src/lcd/extui/mks_ui/draw_eeprom_settings.cpp | 83 - src/lcd/extui/mks_ui/draw_eeprom_settings.h | 33 - .../extui/mks_ui/draw_encoder_settings.cpp | 73 - src/lcd/extui/mks_ui/draw_encoder_settings.h | 33 - src/lcd/extui/mks_ui/draw_error_message.cpp | 46 - src/lcd/extui/mks_ui/draw_error_message.h | 37 - src/lcd/extui/mks_ui/draw_extrusion.cpp | 236 - src/lcd/extui/mks_ui/draw_extrusion.h | 38 - src/lcd/extui/mks_ui/draw_fan.cpp | 99 - src/lcd/extui/mks_ui/draw_fan.h | 34 - src/lcd/extui/mks_ui/draw_filament_change.cpp | 172 - src/lcd/extui/mks_ui/draw_filament_change.h | 35 - .../extui/mks_ui/draw_filament_settings.cpp | 127 - src/lcd/extui/mks_ui/draw_filament_settings.h | 33 - src/lcd/extui/mks_ui/draw_gcode.cpp | 108 - src/lcd/extui/mks_ui/draw_gcode.h | 33 - src/lcd/extui/mks_ui/draw_home.cpp | 93 - src/lcd/extui/mks_ui/draw_home.h | 33 - .../draw_homing_sensitivity_settings.cpp | 105 - .../mks_ui/draw_homing_sensitivity_settings.h | 33 - src/lcd/extui/mks_ui/draw_jerk_settings.cpp | 99 - src/lcd/extui/mks_ui/draw_jerk_settings.h | 33 - src/lcd/extui/mks_ui/draw_keyboard.cpp | 272 - src/lcd/extui/mks_ui/draw_keyboard.h | 33 - src/lcd/extui/mks_ui/draw_language.cpp | 209 - src/lcd/extui/mks_ui/draw_language.h | 33 - src/lcd/extui/mks_ui/draw_level_settings.cpp | 90 - src/lcd/extui/mks_ui/draw_level_settings.h | 33 - src/lcd/extui/mks_ui/draw_machine_para.cpp | 85 - src/lcd/extui/mks_ui/draw_machine_para.h | 33 - .../extui/mks_ui/draw_machine_settings.cpp | 75 - src/lcd/extui/mks_ui/draw_machine_settings.h | 33 - src/lcd/extui/mks_ui/draw_manuaLevel.cpp | 88 - src/lcd/extui/mks_ui/draw_manuaLevel.h | 33 - .../mks_ui/draw_max_feedrate_settings.cpp | 118 - .../extui/mks_ui/draw_max_feedrate_settings.h | 33 - src/lcd/extui/mks_ui/draw_media_select.cpp | 73 - src/lcd/extui/mks_ui/draw_media_select.h | 33 - src/lcd/extui/mks_ui/draw_more.cpp | 203 - src/lcd/extui/mks_ui/draw_more.h | 33 - src/lcd/extui/mks_ui/draw_motor_settings.cpp | 99 - src/lcd/extui/mks_ui/draw_motor_settings.h | 33 - src/lcd/extui/mks_ui/draw_move_motor.cpp | 164 - src/lcd/extui/mks_ui/draw_move_motor.h | 34 - src/lcd/extui/mks_ui/draw_number_key.cpp | 539 - src/lcd/extui/mks_ui/draw_number_key.h | 33 - src/lcd/extui/mks_ui/draw_operation.cpp | 229 - src/lcd/extui/mks_ui/draw_operation.h | 33 - src/lcd/extui/mks_ui/draw_pause_message.cpp | 52 - src/lcd/extui/mks_ui/draw_pause_message.h | 32 - src/lcd/extui/mks_ui/draw_pause_position.cpp | 85 - src/lcd/extui/mks_ui/draw_pause_position.h | 33 - src/lcd/extui/mks_ui/draw_preHeat.cpp | 318 - src/lcd/extui/mks_ui/draw_preHeat.h | 38 - src/lcd/extui/mks_ui/draw_print_file.cpp | 555 - src/lcd/extui/mks_ui/draw_print_file.h | 64 - src/lcd/extui/mks_ui/draw_printing.cpp | 327 - src/lcd/extui/mks_ui/draw_printing.h | 53 - src/lcd/extui/mks_ui/draw_ready_print.cpp | 249 - src/lcd/extui/mks_ui/draw_ready_print.h | 39 - src/lcd/extui/mks_ui/draw_set.cpp | 136 - src/lcd/extui/mks_ui/draw_set.h | 33 - src/lcd/extui/mks_ui/draw_step_settings.cpp | 117 - src/lcd/extui/mks_ui/draw_step_settings.h | 33 - .../mks_ui/draw_tmc_current_settings.cpp | 146 - .../extui/mks_ui/draw_tmc_current_settings.h | 33 - .../mks_ui/draw_tmc_step_mode_settings.cpp | 135 - .../mks_ui/draw_tmc_step_mode_settings.h | 33 - src/lcd/extui/mks_ui/draw_tool.cpp | 104 - src/lcd/extui/mks_ui/draw_tool.h | 33 - .../extui/mks_ui/draw_touch_calibration.cpp | 122 - src/lcd/extui/mks_ui/draw_touch_calibration.h | 34 - .../mks_ui/draw_tramming_pos_settings.cpp | 146 - .../extui/mks_ui/draw_tramming_pos_settings.h | 33 - src/lcd/extui/mks_ui/draw_ui.cpp | 1395 -- src/lcd/extui/mks_ui/draw_ui.h | 552 - src/lcd/extui/mks_ui/draw_wifi.cpp | 167 - src/lcd/extui/mks_ui/draw_wifi.h | 35 - src/lcd/extui/mks_ui/draw_wifi_list.cpp | 178 - src/lcd/extui/mks_ui/draw_wifi_list.h | 76 - src/lcd/extui/mks_ui/draw_wifi_settings.cpp | 188 - src/lcd/extui/mks_ui/draw_wifi_settings.h | 36 - src/lcd/extui/mks_ui/draw_wifi_tips.cpp | 69 - src/lcd/extui/mks_ui/draw_wifi_tips.h | 50 - src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp | 228 - src/lcd/extui/mks_ui/draw_z_offset_wizard.h | 36 - src/lcd/extui/mks_ui/gb2312_puhui16.cpp | 106 - src/lcd/extui/mks_ui/irq_overrid.cpp | 60 - src/lcd/extui/mks_ui/mks_hardware.cpp | 736 -- src/lcd/extui/mks_ui/mks_hardware.h | 42 - src/lcd/extui/mks_ui/pic_manager.cpp | 626 - src/lcd/extui/mks_ui/pic_manager.h | 168 - src/lcd/extui/mks_ui/printer_operation.cpp | 214 - src/lcd/extui/mks_ui/printer_operation.h | 36 - src/lcd/extui/mks_ui/tft_Language_en.h | 740 -- src/lcd/extui/mks_ui/tft_Language_fr.h | 268 - src/lcd/extui/mks_ui/tft_Language_it.h | 265 - src/lcd/extui/mks_ui/tft_Language_ru.h | 362 - src/lcd/extui/mks_ui/tft_Language_s_cn.h | 503 - src/lcd/extui/mks_ui/tft_Language_sp.h | 272 - src/lcd/extui/mks_ui/tft_Language_t_cn.h | 501 - .../extui/mks_ui/tft_lvgl_configuration.cpp | 568 - src/lcd/extui/mks_ui/tft_lvgl_configuration.h | 71 - src/lcd/extui/mks_ui/tft_multi_language.cpp | 2852 ---- src/lcd/extui/mks_ui/tft_multi_language.h | 848 -- src/lcd/extui/mks_ui/wifiSerial.h | 44 - src/lcd/extui/mks_ui/wifiSerial_STM32.cpp | 357 - src/lcd/extui/mks_ui/wifiSerial_STM32.h | 63 - src/lcd/extui/mks_ui/wifiSerial_STM32F1.cpp | 142 - src/lcd/extui/mks_ui/wifiSerial_STM32F1.h | 77 - src/lcd/extui/mks_ui/wifi_module.cpp | 2062 --- src/lcd/extui/mks_ui/wifi_module.h | 201 - src/lcd/extui/mks_ui/wifi_upload.cpp | 684 - src/lcd/extui/mks_ui/wifi_upload.h | 74 - src/lcd/extui/nextion/FileNavigator.cpp | 174 - src/lcd/extui/nextion/FileNavigator.h | 53 - src/lcd/extui/nextion/nextion_extui.cpp | 123 - src/lcd/extui/nextion/nextion_tft.cpp | 736 -- src/lcd/extui/nextion/nextion_tft.h | 63 - src/lcd/extui/nextion/nextion_tft_defs.h | 63 - src/lcd/extui/ui_api.cpp | 1176 -- src/lcd/extui/ui_api.h | 452 - src/lcd/fontutils.cpp | 205 - src/lcd/fontutils.h | 79 - src/lcd/language/language_an.h | 235 - src/lcd/language/language_bg.h | 158 - src/lcd/language/language_ca.h | 229 - src/lcd/language/language_cz.h | 588 - src/lcd/language/language_da.h | 199 - src/lcd/language/language_de.h | 814 -- src/lcd/language/language_el.h | 210 - src/lcd/language/language_el_CY.h | 38 - src/lcd/language/language_el_gr.h | 198 - src/lcd/language/language_en.h | 848 -- src/lcd/language/language_es.h | 579 - src/lcd/language/language_eu.h | 318 - src/lcd/language/language_fi.h | 131 - src/lcd/language/language_fr.h | 632 - src/lcd/language/language_gl.h | 595 - src/lcd/language/language_hr.h | 173 - src/lcd/language/language_hu.h | 706 - src/lcd/language/language_it.h | 821 -- src/lcd/language/language_jp_kana.h | 249 - src/lcd/language/language_ko_KR.h | 106 - src/lcd/language/language_nl.h | 230 - src/lcd/language/language_pl.h | 549 - src/lcd/language/language_pt.h | 172 - src/lcd/language/language_pt_br.h | 486 - src/lcd/language/language_ro.h | 617 - src/lcd/language/language_ru.h | 883 -- src/lcd/language/language_sk.h | 820 -- src/lcd/language/language_sv.h | 674 - src/lcd/language/language_test.h | 236 - src/lcd/language/language_tr.h | 579 - src/lcd/language/language_uk.h | 925 -- src/lcd/language/language_vi.h | 441 - src/lcd/language/language_zh_CN.h | 620 - src/lcd/language/language_zh_TW.h | 501 - src/lcd/lcdprint.cpp | 109 - src/lcd/lcdprint.h | 296 - src/lcd/marlinui.cpp | 1879 --- src/lcd/marlinui.h | 791 -- src/lcd/menu/game/brickout.cpp | 207 - src/lcd/menu/game/brickout.h | 38 - src/lcd/menu/game/game.cpp | 66 - src/lcd/menu/game/game.h | 70 - src/lcd/menu/game/invaders.cpp | 438 - src/lcd/menu/game/invaders.h | 62 - src/lcd/menu/game/maze.cpp | 134 - src/lcd/menu/game/maze.h | 30 - src/lcd/menu/game/snake.cpp | 323 - src/lcd/menu/game/snake.h | 38 - src/lcd/menu/game/types.h | 46 - src/lcd/menu/menu.cpp | 377 - src/lcd/menu/menu.h | 272 - src/lcd/menu/menu_addon.h | 33 - src/lcd/menu/menu_advanced.cpp | 704 - src/lcd/menu/menu_backlash.cpp | 78 - src/lcd/menu/menu_bed_corners.cpp | 365 - src/lcd/menu/menu_bed_leveling.cpp | 304 - src/lcd/menu/menu_cancelobject.cpp | 74 - src/lcd/menu/menu_configuration.cpp | 592 - src/lcd/menu/menu_delta_calibrate.cpp | 160 - src/lcd/menu/menu_filament.cpp | 350 - src/lcd/menu/menu_game.cpp | 48 - src/lcd/menu/menu_info.cpp | 320 - src/lcd/menu/menu_item.h | 574 - src/lcd/menu/menu_job_recovery.cpp | 57 - src/lcd/menu/menu_language.cpp | 59 - src/lcd/menu/menu_led.cpp | 172 - src/lcd/menu/menu_main.cpp | 464 - src/lcd/menu/menu_media.cpp | 164 - src/lcd/menu/menu_mixer.cpp | 278 - src/lcd/menu/menu_mmu2.cpp | 170 - src/lcd/menu/menu_mmu2.h | 28 - src/lcd/menu/menu_motion.cpp | 409 - src/lcd/menu/menu_password.cpp | 187 - src/lcd/menu/menu_power_monitor.cpp | 62 - src/lcd/menu/menu_probe_offset.cpp | 164 - src/lcd/menu/menu_spindle_laser.cpp | 88 - src/lcd/menu/menu_temperature.cpp | 310 - src/lcd/menu/menu_tmc.cpp | 181 - src/lcd/menu/menu_touch_screen.cpp | 36 - src/lcd/menu/menu_tramming.cpp | 115 - src/lcd/menu/menu_tune.cpp | 241 - src/lcd/menu/menu_ubl.cpp | 674 - src/lcd/menu/menu_x_twist.cpp | 213 - src/lcd/scaled_tft.h | 55 - src/lcd/tft/bitmaps/back.bmp | Bin 3126 -> 0 bytes src/lcd/tft/bitmaps/bed.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/bed_heated.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/btn_42x39_rounded.bmp | Bin 5046 -> 0 bytes src/lcd/tft/bitmaps/btn_64x52_rounded.bmp | Bin 10040 -> 0 bytes src/lcd/tft/bitmaps/cancel.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/chamber.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/chamber_heated.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/confirm.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/decrease.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/directory.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/down.bmp | Bin 3126 -> 0 bytes src/lcd/tft/bitmaps/fan0.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/fan1.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/fan_fast0.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/fan_fast1.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/fan_slow0.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/fan_slow1.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/feedrate.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/flowrate.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/home.bmp | Bin 12344 -> 0 bytes src/lcd/tft/bitmaps/hotend.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/increase.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/left.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/leveling.bmp | Bin 3126 -> 0 bytes .../bitmaps/marlin-logo/Marlin-1500x319.png | Bin 387923 -> 0 bytes .../tft/bitmaps/marlin-logo/Marlin-195x59.png | Bin 18386 -> 0 bytes .../marlin-logo/Marlin-228x255-greyscale.png | Bin 7940 -> 0 bytes .../bitmaps/marlin-logo/Marlin-228x255.png | Bin 81470 -> 0 bytes .../bitmaps/marlin-logo/Marlin-280x200.png | Bin 46851 -> 0 bytes .../bitmaps/marlin-logo/Marlin-320x240.png | Bin 97523 -> 0 bytes .../bitmaps/marlin-logo/Marlin-480x319.png | Bin 168816 -> 0 bytes .../bitmaps/marlin-logo/Marlin-480x320.png | Bin 168834 -> 0 bytes src/lcd/tft/bitmaps/menu.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/pause.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/refresh.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/right.bmp | Bin 3194 -> 0 bytes src/lcd/tft/bitmaps/sd.bmp | Bin 12410 -> 0 bytes src/lcd/tft/bitmaps/settings.bmp | Bin 12342 -> 0 bytes src/lcd/tft/bitmaps/up.bmp | Bin 3126 -> 0 bytes src/lcd/tft/canvas.cpp | 179 - src/lcd/tft/canvas.h | 57 - src/lcd/tft/fontdata/fontdata_10x20.cpp | 260 - src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp | 317 - src/lcd/tft/fontdata/helvetica_12_bold.cpp | 305 - src/lcd/tft/fontdata/helvetica_14.cpp | 381 - src/lcd/tft/fontdata/helvetica_18.cpp | 492 - src/lcd/tft/fontdata/profont_22.cpp | 426 - src/lcd/tft/images/back_32x32x4.cpp | 62 - src/lcd/tft/images/background_320x30x16.cpp | 60 - src/lcd/tft/images/bootscreen_112x38x1.cpp | 70 - src/lcd/tft/images/bootscreen_195x59x16.cpp | 89 - src/lcd/tft/images/bootscreen_228x255x2.cpp | 285 - src/lcd/tft/images/bootscreen_228x255x4.cpp | 285 - src/lcd/tft/images/bootscreen_320x240x16.cpp | 270 - src/lcd/tft/images/bootscreen_480x320x16.cpp | 350 - src/lcd/tft/images/btn_rounded_42x39x4.cpp | 69 - src/lcd/tft/images/btn_rounded_64x52x4.cpp | 82 - src/lcd/tft/images/cancel_64x64x4.cpp | 94 - src/lcd/tft/images/chamber_64x64x4.cpp | 161 - src/lcd/tft/images/confirm_64x64x4.cpp | 94 - src/lcd/tft/images/decrease_64x64x4.cpp | 94 - src/lcd/tft/images/directory_32x32x4.cpp | 62 - src/lcd/tft/images/down_32x32x4.cpp | 62 - src/lcd/tft/images/fan_64x64x4.cpp | 161 - src/lcd/tft/images/fan_fast_64x64x4.cpp | 161 - src/lcd/tft/images/fan_slow_64x64x4.cpp | 161 - src/lcd/tft/images/feedrate_32x32x4.cpp | 62 - src/lcd/tft/images/flowrate_32x32x4.cpp | 62 - src/lcd/tft/images/heated_bed_64x64x4.cpp | 161 - src/lcd/tft/images/home_64x64x4.cpp | 94 - src/lcd/tft/images/hotend_64x64x4.cpp | 94 - src/lcd/tft/images/increase_64x64x4.cpp | 94 - src/lcd/tft/images/left_32x32x4.cpp | 62 - src/lcd/tft/images/leveling_32x32x4.cpp | 62 - src/lcd/tft/images/menu_64x64x4.cpp | 94 - src/lcd/tft/images/pause_64x64x4.cpp | 94 - src/lcd/tft/images/refresh_32x32x4.cpp | 62 - src/lcd/tft/images/right_32x32x4.cpp | 62 - src/lcd/tft/images/sd_64x64x4.cpp | 94 - src/lcd/tft/images/settings_64x64x4.cpp | 94 - src/lcd/tft/images/slider_8x16x4.cpp | 46 - src/lcd/tft/images/up_32x32x4.cpp | 62 - src/lcd/tft/tft.cpp | 42 - src/lcd/tft/tft.h | 105 - src/lcd/tft/tft_color.h | 180 - src/lcd/tft/tft_image.cpp | 113 - src/lcd/tft/tft_image.h | 178 - src/lcd/tft/tft_queue.cpp | 354 - src/lcd/tft/tft_queue.h | 152 - src/lcd/tft/tft_string.cpp | 176 - src/lcd/tft/tft_string.h | 156 - src/lcd/tft/touch.cpp | 325 - src/lcd/tft/touch.h | 136 - src/lcd/tft/ui_1024x600.cpp | 937 -- src/lcd/tft/ui_1024x600.h | 43 - src/lcd/tft/ui_320x240.cpp | 917 -- src/lcd/tft/ui_320x240.h | 42 - src/lcd/tft/ui_480x320.cpp | 918 -- src/lcd/tft/ui_480x320.h | 49 - src/lcd/tft/ui_common.cpp | 277 - src/lcd/tft/ui_common.h | 88 - src/lcd/tft_io/ili9328.h | 173 - src/lcd/tft_io/ili9341.h | 170 - src/lcd/tft_io/ili9488.h | 164 - src/lcd/tft_io/r65105.h | 176 - src/lcd/tft_io/ssd1963.h | 131 - src/lcd/tft_io/st7735.h | 136 - src/lcd/tft_io/st7789v.h | 156 - src/lcd/tft_io/st7796s.h | 157 - src/lcd/tft_io/tft_ids.h | 34 - src/lcd/tft_io/tft_io.cpp | 258 - src/lcd/tft_io/tft_io.h | 134 - src/lcd/tft_io/touch_calibration.cpp | 115 - src/lcd/tft_io/touch_calibration.h | 95 - src/lcd/thermistornames.h | 154 - src/lcd/touch/touch_buttons.cpp | 143 - src/lcd/touch/touch_buttons.h | 71 - src/libs/BL24CXX.cpp | 285 - src/libs/BL24CXX.h | 72 - src/libs/L64XX/L64XX_Marlin.cpp | 998 -- src/libs/L64XX/L64XX_Marlin.h | 141 - src/libs/L64XX/README.md | 98 - src/libs/MAX31865.cpp | 638 - src/libs/MAX31865.h | 166 - src/libs/W25Qxx.cpp | 383 - src/libs/W25Qxx.h | 74 - src/libs/autoreport.h | 50 - src/libs/bresenham.h | 132 - src/libs/buzzer.cpp | 84 - src/libs/buzzer.h | 135 - src/libs/circularqueue.h | 131 - src/libs/crc16.cpp | 32 - src/libs/crc16.h | 26 - src/libs/duration_t.h | 180 - src/libs/heatshrink/LICENSE | 14 - src/libs/heatshrink/heatshrink_common.h | 20 - src/libs/heatshrink/heatshrink_config.h | 26 - src/libs/heatshrink/heatshrink_decoder.cpp | 384 - src/libs/heatshrink/heatshrink_decoder.h | 119 - src/libs/hex_print.cpp | 90 - src/libs/hex_print.h | 41 - src/libs/least_squares_fit.cpp | 69 - src/libs/least_squares_fit.h | 87 - src/libs/nozzle.cpp | 275 - src/libs/nozzle.h | 92 - src/libs/numtostr.cpp | 417 - src/libs/numtostr.h | 128 - src/libs/private_spi.h | 54 - src/libs/softspi.h | 742 -- src/libs/stopwatch.cpp | 102 - src/libs/stopwatch.h | 120 - src/libs/vector_3.cpp | 151 - src/libs/vector_3.h | 97 - src/module/delta.cpp | 289 - src/module/delta.h | 129 - src/module/endstops.cpp | 1423 -- src/module/endstops.h | 265 - src/module/motion.cpp | 2209 ---- src/module/motion.h | 581 - src/module/planner.cpp | 3353 ----- src/module/planner.h | 1064 -- src/module/planner_bezier.cpp | 211 - src/module/planner_bezier.h | 38 - src/module/polargraph.cpp | 54 - src/module/polargraph.h | 36 - src/module/printcounter.cpp | 359 - src/module/printcounter.h | 204 - src/module/probe.cpp | 941 -- src/module/probe.h | 318 - src/module/scara.cpp | 309 - src/module/scara.h | 53 - src/module/servo.cpp | 58 - src/module/servo.h | 113 - src/module/settings.cpp | 3611 ------ src/module/settings.h | 149 - src/module/stepper.cpp | 3824 ------ src/module/stepper.h | 694 - src/module/stepper/L64xx.cpp | 246 - src/module/stepper/L64xx.h | 424 - src/module/stepper/TMC26X.cpp | 162 - src/module/stepper/TMC26X.h | 188 - src/module/stepper/indirection.cpp | 48 - src/module/stepper/indirection.h | 1059 -- src/module/stepper/speed_lookuptable.h | 168 - src/module/stepper/trinamic.cpp | 988 -- src/module/stepper/trinamic.h | 411 - src/module/temperature.cpp | 4459 ------- src/module/temperature.h | 1115 -- src/module/thermistor/thermistor_1.h | 90 - src/module/thermistor/thermistor_10.h | 57 - src/module/thermistor/thermistor_1010.h | 41 - src/module/thermistor/thermistor_1047.h | 40 - src/module/thermistor/thermistor_11.h | 76 - src/module/thermistor/thermistor_110.h | 36 - src/module/thermistor/thermistor_12.h | 56 - src/module/thermistor/thermistor_13.h | 49 - src/module/thermistor/thermistor_147.h | 36 - src/module/thermistor/thermistor_15.h | 65 - src/module/thermistor/thermistor_17.h | 78 - src/module/thermistor/thermistor_18.h | 59 - src/module/thermistor/thermistor_2.h | 62 - src/module/thermistor/thermistor_20.h | 77 - src/module/thermistor/thermistor_2000.h | 60 - src/module/thermistor/thermistor_201.h | 57 - src/module/thermistor/thermistor_202.h | 69 - src/module/thermistor/thermistor_21.h | 78 - src/module/thermistor/thermistor_22.h | 72 - src/module/thermistor/thermistor_23.h | 128 - src/module/thermistor/thermistor_3.h | 54 - src/module/thermistor/thermistor_30.h | 66 - src/module/thermistor/thermistor_331.h | 92 - src/module/thermistor/thermistor_332.h | 50 - src/module/thermistor/thermistor_4.h | 46 - src/module/thermistor/thermistor_5.h | 62 - src/module/thermistor/thermistor_501.h | 58 - src/module/thermistor/thermistor_502.h | 60 - src/module/thermistor/thermistor_503.h | 57 - src/module/thermistor/thermistor_504.h | 93 - src/module/thermistor/thermistor_505.h | 82 - src/module/thermistor/thermistor_51.h | 83 - src/module/thermistor/thermistor_512.h | 87 - src/module/thermistor/thermistor_52.h | 62 - src/module/thermistor/thermistor_55.h | 62 - src/module/thermistor/thermistor_6.h | 64 - src/module/thermistor/thermistor_60.h | 107 - src/module/thermistor/thermistor_61.h | 116 - src/module/thermistor/thermistor_66.h | 120 - src/module/thermistor/thermistor_666.h | 98 - src/module/thermistor/thermistor_67.h | 81 - src/module/thermistor/thermistor_68.h | 54 - src/module/thermistor/thermistor_7.h | 84 - src/module/thermistor/thermistor_70.h | 46 - src/module/thermistor/thermistor_71.h | 94 - src/module/thermistor/thermistor_75.h | 80 - src/module/thermistor/thermistor_8.h | 46 - src/module/thermistor/thermistor_9.h | 57 - src/module/thermistor/thermistor_99.h | 63 - src/module/thermistor/thermistor_998.h | 33 - src/module/thermistor/thermistor_999.h | 33 - src/module/thermistor/thermistors.h | 546 - src/module/tool_change.cpp | 1510 --- src/module/tool_change.h | 133 - src/pins/esp32/env_validate.h | 26 - src/pins/esp32/pins_E4D.h | 103 - src/pins/esp32/pins_ENWI_ESPNP.h | 118 - src/pins/esp32/pins_ESP32.h | 86 - src/pins/esp32/pins_ESPA_common.h | 81 - src/pins/esp32/pins_FYSETC_E4.h | 72 - src/pins/esp32/pins_MKS_TINYBEE.h | 193 - src/pins/esp32/pins_MRR_ESPA.h | 58 - src/pins/esp32/pins_MRR_ESPE.h | 164 - src/pins/esp32/pins_PANDA_M4.h | 38 - src/pins/esp32/pins_PANDA_ZHU.h | 61 - src/pins/esp32/pins_PANDA_common.h | 128 - src/pins/esp32/pins_RESP32_CUSTOM.h | 37 - src/pins/linux/pins_RAMPS_LINUX.h | 698 - src/pins/lpc1768/env_validate.h | 30 - src/pins/lpc1768/pins_AZSMZ_MINI.h | 159 - src/pins/lpc1768/pins_BIQU_B300_V1.0.h | 180 - src/pins/lpc1768/pins_BIQU_BQ111_A4.h | 149 - src/pins/lpc1768/pins_BTT_SKR_V1_1.h | 255 - src/pins/lpc1768/pins_BTT_SKR_V1_3.h | 486 - src/pins/lpc1768/pins_BTT_SKR_V1_4.h | 512 - src/pins/lpc1768/pins_BTT_SKR_common.h | 209 - src/pins/lpc1768/pins_EMOTRONIC.h | 149 - src/pins/lpc1768/pins_GMARSH_X6_REV1.h | 174 - src/pins/lpc1768/pins_MKS_SBASE.h | 387 - src/pins/lpc1768/pins_MKS_SGEN_L.h | 416 - src/pins/lpc1768/pins_RAMPS_RE_ARM.h | 495 - src/pins/lpc1768/pins_SELENA_COMPACT.h | 116 - src/pins/lpc1769/env_validate.h | 26 - src/pins/lpc1769/pins_AZTEEG_X5_GT.h | 124 - src/pins/lpc1769/pins_AZTEEG_X5_MINI.h | 211 - src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h | 42 - src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h | 291 - src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h | 34 - src/pins/lpc1769/pins_COHESION3D_MINI.h | 175 - src/pins/lpc1769/pins_COHESION3D_REMIX.h | 286 - src/pins/lpc1769/pins_FLY_CDY.h | 183 - src/pins/lpc1769/pins_MKS_SGEN.h | 58 - src/pins/lpc1769/pins_MKS_SGEN_L_V2.h | 453 - src/pins/lpc1769/pins_SMOOTHIEBOARD.h | 179 - src/pins/lpc1769/pins_TH3D_EZBOARD.h | 227 - src/pins/mega/env_validate.h | 32 - src/pins/mega/pins_CHEAPTRONIC.h | 78 - src/pins/mega/pins_CHEAPTRONICv2.h | 138 - src/pins/mega/pins_CNCONTROLS_11.h | 162 - src/pins/mega/pins_CNCONTROLS_12.h | 169 - src/pins/mega/pins_CNCONTROLS_15.h | 126 - src/pins/mega/pins_EINSTART-S.h | 112 - src/pins/mega/pins_ELEFU_3.h | 150 - src/pins/mega/pins_GT2560_REV_A.h | 169 - src/pins/mega/pins_GT2560_REV_A_PLUS.h | 34 - src/pins/mega/pins_GT2560_REV_B.h | 30 - src/pins/mega/pins_GT2560_V3.h | 217 - src/pins/mega/pins_GT2560_V3_A20.h | 41 - src/pins/mega/pins_GT2560_V3_MC2.h | 35 - src/pins/mega/pins_GT2560_V4.h | 30 - src/pins/mega/pins_GT2560_V4_A20.h | 43 - src/pins/mega/pins_HJC2560C_REV2.h | 171 - src/pins/mega/pins_INTAMSYS40.h | 149 - src/pins/mega/pins_LEAPFROG.h | 91 - src/pins/mega/pins_LEAPFROG_XEED2015.h | 113 - src/pins/mega/pins_MALYAN_M180.h | 100 - src/pins/mega/pins_MEGACONTROLLER.h | 164 - src/pins/mega/pins_MEGATRONICS.h | 132 - src/pins/mega/pins_MEGATRONICS_2.h | 153 - src/pins/mega/pins_MEGATRONICS_3.h | 193 - src/pins/mega/pins_MIGHTYBOARD_REVE.h | 278 - src/pins/mega/pins_MINITRONICS.h | 142 - src/pins/mega/pins_OVERLORD.h | 144 - src/pins/mega/pins_PICA.h | 153 - src/pins/mega/pins_PICAOLD.h | 29 - src/pins/mega/pins_PROTONEER_CNC_SHIELD_V3.h | 77 - src/pins/mega/pins_SILVER_GATE.h | 102 - src/pins/mega/pins_WANHAO_ONEPLUS.h | 109 - src/pins/mega/pins_WEEDO_62A.h | 106 - src/pins/pins.h | 903 -- src/pins/pinsDebug.h | 293 - src/pins/pinsDebug_list.h | 1796 --- src/pins/pins_postprocess.h | 1435 -- src/pins/rambo/env_validate.h | 26 - src/pins/rambo/pins_EINSY_RAMBO.h | 216 - src/pins/rambo/pins_EINSY_RETRO.h | 210 - src/pins/rambo/pins_MINIRAMBO.h | 202 - src/pins/rambo/pins_RAMBO.h | 280 - src/pins/rambo/pins_RAMBO_THINKERV2.h | 60 - src/pins/rambo/pins_SCOOVO_X9H.h | 158 - src/pins/ramps/env_validate.h | 35 - src/pins/ramps/pins_3DRAG.h | 173 - src/pins/ramps/pins_AZTEEG_X3.h | 97 - src/pins/ramps/pins_AZTEEG_X3_PRO.h | 178 - src/pins/ramps/pins_BAM_DICE_DUE.h | 47 - src/pins/ramps/pins_BIQU_KFB_2.h | 40 - src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h | 126 - src/pins/ramps/pins_COPYMASTER_3D.h | 34 - src/pins/ramps/pins_DAGOMA_F5.h | 66 - src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h | 183 - src/pins/ramps/pins_FELIX2.h | 63 - src/pins/ramps/pins_FORMBOT_RAPTOR.h | 181 - src/pins/ramps/pins_FORMBOT_RAPTOR2.h | 74 - src/pins/ramps/pins_FORMBOT_TREX2PLUS.h | 189 - src/pins/ramps/pins_FORMBOT_TREX3.h | 187 - src/pins/ramps/pins_FYSETC_F6_13.h | 301 - src/pins/ramps/pins_FYSETC_F6_14.h | 55 - src/pins/ramps/pins_K8200.h | 33 - src/pins/ramps/pins_K8400.h | 66 - src/pins/ramps/pins_K8600.h | 100 - src/pins/ramps/pins_K8800.h | 116 - src/pins/ramps/pins_LONGER3D_LKx_PRO.h | 121 - src/pins/ramps/pins_MAKEBOARD_MINI.h | 33 - src/pins/ramps/pins_MKS_BASE_10.h | 37 - src/pins/ramps/pins_MKS_BASE_14.h | 170 - src/pins/ramps/pins_MKS_BASE_15.h | 35 - src/pins/ramps/pins_MKS_BASE_16.h | 59 - src/pins/ramps/pins_MKS_BASE_HEROIC.h | 36 - src/pins/ramps/pins_MKS_BASE_common.h | 75 - src/pins/ramps/pins_MKS_GEN_13.h | 130 - src/pins/ramps/pins_MKS_GEN_L.h | 59 - src/pins/ramps/pins_MKS_GEN_L_V2.h | 89 - src/pins/ramps/pins_MKS_GEN_L_V21.h | 85 - src/pins/ramps/pins_ORTUR_4.h | 105 - src/pins/ramps/pins_PXMALION_CORE_I3.h | 86 - src/pins/ramps/pins_RAMPS.h | 916 -- src/pins/ramps/pins_RAMPS_13.h | 42 - src/pins/ramps/pins_RAMPS_CREALITY.h | 72 - src/pins/ramps/pins_RAMPS_ENDER_4.h | 41 - src/pins/ramps/pins_RAMPS_OLD.h | 117 - src/pins/ramps/pins_RAMPS_PLUS.h | 94 - src/pins/ramps/pins_RAMPS_S_12.h | 280 - src/pins/ramps/pins_RIGIDBOARD.h | 129 - src/pins/ramps/pins_RIGIDBOARD_V2.h | 52 - src/pins/ramps/pins_RL200.h | 52 - src/pins/ramps/pins_RUMBA.h | 250 - src/pins/ramps/pins_RUMBA_RAISE3D.h | 31 - src/pins/ramps/pins_SAINSMART_2IN1.h | 42 - src/pins/ramps/pins_TANGO.h | 53 - src/pins/ramps/pins_TENLOG_D3_HERO.h | 187 - src/pins/ramps/pins_TRIGORILLA_13.h | 43 - src/pins/ramps/pins_TRIGORILLA_14.h | 147 - src/pins/ramps/pins_TRONXY_V3_1_0.h | 280 - src/pins/ramps/pins_TT_OSCAR.h | 509 - src/pins/ramps/pins_ULTIMAIN_2.h | 141 - src/pins/ramps/pins_ULTIMAKER.h | 166 - src/pins/ramps/pins_ULTIMAKER_OLD.h | 272 - src/pins/ramps/pins_VORON.h | 55 - src/pins/ramps/pins_ZRIB_V20.h | 87 - src/pins/ramps/pins_ZRIB_V52.h | 159 - src/pins/ramps/pins_ZRIB_V53.h | 511 - src/pins/ramps/pins_Z_BOLT_X_SERIES.h | 303 - src/pins/sam/env_validate.h | 33 - src/pins/sam/pins_ADSK.h | 207 - src/pins/sam/pins_ALLIGATOR_R2.h | 157 - src/pins/sam/pins_ARCHIM1.h | 205 - src/pins/sam/pins_ARCHIM2.h | 262 - src/pins/sam/pins_CNCONTROLS_15D.h | 137 - src/pins/sam/pins_DUE3DOM.h | 171 - src/pins/sam/pins_DUE3DOM_MINI.h | 172 - src/pins/sam/pins_KRATOS32.h | 179 - src/pins/sam/pins_PRINTRBOARD_G2.h | 171 - src/pins/sam/pins_RADDS.h | 296 - src/pins/sam/pins_RAMPS4DUE.h | 52 - src/pins/sam/pins_RAMPS_DUO.h | 131 - src/pins/sam/pins_RAMPS_FD_V1.h | 264 - src/pins/sam/pins_RAMPS_FD_V2.h | 52 - src/pins/sam/pins_RAMPS_SMART.h | 142 - src/pins/sam/pins_RURAMPS4D_11.h | 292 - src/pins/sam/pins_RURAMPS4D_13.h | 277 - src/pins/sam/pins_ULTRATRONICS_PRO.h | 176 - src/pins/samd/pins_BRICOLEMON_LITE_V1_0.h | 616 - src/pins/samd/pins_BRICOLEMON_V1_0.h | 676 - src/pins/samd/pins_RAMPS_144.h | 571 - src/pins/sanguino/env_validate.h | 42 - src/pins/sanguino/pins_ANET_10.h | 305 - src/pins/sanguino/pins_AZTEEG_X1.h | 30 - src/pins/sanguino/pins_GEN3_MONOLITHIC.h | 98 - src/pins/sanguino/pins_GEN3_PLUS.h | 98 - src/pins/sanguino/pins_GEN6.h | 120 - src/pins/sanguino/pins_GEN6_DELUXE.h | 54 - src/pins/sanguino/pins_GEN7_12.h | 146 - src/pins/sanguino/pins_GEN7_13.h | 54 - src/pins/sanguino/pins_GEN7_14.h | 119 - src/pins/sanguino/pins_GEN7_CUSTOM.h | 139 - src/pins/sanguino/pins_MELZI.h | 47 - src/pins/sanguino/pins_MELZI_CREALITY.h | 141 - src/pins/sanguino/pins_MELZI_MAKR3D.h | 29 - src/pins/sanguino/pins_MELZI_MALYAN.h | 45 - src/pins/sanguino/pins_MELZI_TRONXY.h | 60 - src/pins/sanguino/pins_MELZI_V2.h | 37 - src/pins/sanguino/pins_OMCA.h | 149 - src/pins/sanguino/pins_OMCA_A.h | 135 - src/pins/sanguino/pins_SANGUINOLOLU_11.h | 316 - src/pins/sanguino/pins_SANGUINOLOLU_12.h | 42 - src/pins/sanguino/pins_SETHI.h | 123 - src/pins/sanguino/pins_STB_11.h | 30 - src/pins/sanguino/pins_ZMIB_V2.h | 232 - src/pins/sensitive_pins.h | 896 -- src/pins/stm32f0/pins_MALYAN_M200_V2.h | 30 - src/pins/stm32f0/pins_MALYAN_M300.h | 90 - src/pins/stm32f1/env_validate.h | 32 - src/pins/stm32f1/pins_BEAST.h | 145 - src/pins/stm32f1/pins_BTT_SKR_CR6.h | 186 - src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h | 292 - src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h | 51 - src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h | 50 - src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h | 84 - .../stm32f1/pins_BTT_SKR_MINI_E3_common.h | 386 - src/pins/stm32f1/pins_BTT_SKR_MINI_MZ_V1_0.h | 26 - src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h | 257 - src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h | 185 - src/pins/stm32f1/pins_CHITU3D.h | 265 - src/pins/stm32f1/pins_CHITU3D_V5.h | 28 - src/pins/stm32f1/pins_CHITU3D_V6.h | 34 - src/pins/stm32f1/pins_CHITU3D_V9.h | 40 - src/pins/stm32f1/pins_CHITU3D_common.h | 177 - src/pins/stm32f1/pins_CREALITY_V24S1.h | 36 - src/pins/stm32f1/pins_CREALITY_V24S1_301.h | 94 - src/pins/stm32f1/pins_CREALITY_V25S1.h | 152 - src/pins/stm32f1/pins_CREALITY_V4.h | 251 - src/pins/stm32f1/pins_CREALITY_V4210.h | 227 - src/pins/stm32f1/pins_CREALITY_V422.h | 31 - src/pins/stm32f1/pins_CREALITY_V423.h | 44 - src/pins/stm32f1/pins_CREALITY_V425.h | 77 - src/pins/stm32f1/pins_CREALITY_V427.h | 45 - src/pins/stm32f1/pins_CREALITY_V431.h | 51 - src/pins/stm32f1/pins_CREALITY_V452.h | 44 - src/pins/stm32f1/pins_CREALITY_V453.h | 44 - src/pins/stm32f1/pins_CREALITY_V45x.h | 114 - src/pins/stm32f1/pins_ERYONE_ERY32_MINI.h | 196 - src/pins/stm32f1/pins_FLSUN_HISPEED.h | 328 - src/pins/stm32f1/pins_FLY_MINI.h | 190 - src/pins/stm32f1/pins_FYSETC_AIO_II.h | 207 - src/pins/stm32f1/pins_FYSETC_CHEETAH.h | 200 - src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h | 59 - src/pins/stm32f1/pins_GTM32_MINI.h | 235 - src/pins/stm32f1/pins_GTM32_MINI_A30.h | 229 - src/pins/stm32f1/pins_GTM32_PRO_VB.h | 240 - src/pins/stm32f1/pins_GTM32_PRO_VD.h | 30 - src/pins/stm32f1/pins_GTM32_REV_B.h | 232 - src/pins/stm32f1/pins_JGAURORA_A5S_A1.h | 147 - src/pins/stm32f1/pins_LONGER3D_LK.h | 212 - src/pins/stm32f1/pins_MALYAN_M200.h | 95 - src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h | 161 - src/pins/stm32f1/pins_MKS_ROBIN.h | 282 - src/pins/stm32f1/pins_MKS_ROBIN_E3.h | 36 - src/pins/stm32f1/pins_MKS_ROBIN_E3D.h | 67 - src/pins/stm32f1/pins_MKS_ROBIN_E3D_V1_1.h | 67 - src/pins/stm32f1/pins_MKS_ROBIN_E3P.h | 395 - src/pins/stm32f1/pins_MKS_ROBIN_E3_V1_1.h | 36 - .../stm32f1/pins_MKS_ROBIN_E3_V1_1_common.h | 39 - src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h | 265 - src/pins/stm32f1/pins_MKS_ROBIN_LITE.h | 175 - src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h | 159 - src/pins/stm32f1/pins_MKS_ROBIN_MINI.h | 206 - src/pins/stm32f1/pins_MKS_ROBIN_NANO.h | 51 - src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h | 395 - src/pins/stm32f1/pins_MKS_ROBIN_NANO_common.h | 211 - src/pins/stm32f1/pins_MKS_ROBIN_PRO.h | 318 - src/pins/stm32f1/pins_MORPHEUS.h | 93 - src/pins/stm32f1/pins_PANDA_PI_V29.h | 224 - src/pins/stm32f1/pins_STM32F1R.h | 138 - src/pins/stm32f1/pins_STM3R_MINI.h | 159 - src/pins/stm32f1/pins_TRIGORILLA_PRO.h | 208 - src/pins/stm32f1/pins_ZM3E2_V1_0.h | 235 - src/pins/stm32f1/pins_ZM3E4_V1_0.h | 356 - src/pins/stm32f1/pins_ZM3E4_V2_0.h | 329 - src/pins/stm32f4/env_validate.h | 28 - src/pins/stm32f4/pins_ANET_ET4.h | 218 - src/pins/stm32f4/pins_ANET_ET4P.h | 33 - src/pins/stm32f4/pins_ARMED.h | 228 - src/pins/stm32f4/pins_ARTILLERY_RUBY.h | 184 - src/pins/stm32f4/pins_BLACK_STM32F407VE.h | 156 - src/pins/stm32f4/pins_BTT_BTT002_V1_0.h | 336 - src/pins/stm32f4/pins_BTT_E3_RRF.h | 420 - src/pins/stm32f4/pins_BTT_GTR_V1_0.h | 494 - src/pins/stm32f4/pins_BTT_OCTOPUS_PRO_V1_0.h | 44 - src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h | 35 - src/pins/stm32f4/pins_BTT_OCTOPUS_V1_1.h | 35 - src/pins/stm32f4/pins_BTT_OCTOPUS_V1_common.h | 545 - src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h | 30 - src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h | 30 - src/pins/stm32f4/pins_BTT_SKR_PRO_common.h | 568 - src/pins/stm32f4/pins_BTT_SKR_V2_0_REV_A.h | 29 - src/pins/stm32f4/pins_BTT_SKR_V2_0_REV_B.h | 26 - src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h | 580 - src/pins/stm32f4/pins_CREALITY_V24S1_301F4.h | 38 - src/pins/stm32f4/pins_FLYF407ZG.h | 312 - src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h | 259 - src/pins/stm32f4/pins_FYSETC_S6.h | 340 - src/pins/stm32f4/pins_FYSETC_S6_V2_0.h | 71 - src/pins/stm32f4/pins_FYSETC_SPIDER.h | 123 - src/pins/stm32f4/pins_FYSETC_SPIDER_V2_2.h | 34 - src/pins/stm32f4/pins_LERDGE_K.h | 272 - src/pins/stm32f4/pins_LERDGE_S.h | 232 - src/pins/stm32f4/pins_LERDGE_X.h | 175 - src/pins/stm32f4/pins_MKS_EAGLE.h | 35 - src/pins/stm32f4/pins_MKS_MONSTER8_V1.h | 51 - src/pins/stm32f4/pins_MKS_MONSTER8_V2.h | 57 - src/pins/stm32f4/pins_MKS_MONSTER8_common.h | 368 - src/pins/stm32f4/pins_MKS_ROBIN2.h | 101 - .../stm32f4/pins_MKS_ROBIN_NANO_V1_3_F4.h | 45 - src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h | 72 - .../stm32f4/pins_MKS_ROBIN_NANO_V3_common.h | 391 - src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h | 378 - src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h | 206 - src/pins/stm32f4/pins_RUMBA32_AUS3D.h | 77 - src/pins/stm32f4/pins_RUMBA32_BTT.h | 67 - src/pins/stm32f4/pins_RUMBA32_MKS.h | 87 - src/pins/stm32f4/pins_RUMBA32_common.h | 179 - src/pins/stm32f4/pins_STEVAL_3DP001V1.h | 325 - src/pins/stm32f4/pins_TH3D_EZBOARD_V2.h | 275 - src/pins/stm32f4/pins_VAKE403D.h | 226 - src/pins/stm32f7/pins_NUCLEO_F767ZI.h | 197 - src/pins/stm32f7/pins_REMRAM_V1.h | 136 - src/pins/stm32g0/pins_BTT_SKR_MINI_E3_V3_0.h | 439 - src/pins/stm32h7/pins_BTT_SKR_SE_BX_V2.h | 28 - src/pins/stm32h7/pins_BTT_SKR_SE_BX_V3.h | 26 - src/pins/stm32h7/pins_BTT_SKR_SE_BX_common.h | 234 - src/pins/stm32h7/pins_BTT_SKR_V3_0.h | 26 - src/pins/stm32h7/pins_BTT_SKR_V3_0_EZ.h | 26 - src/pins/stm32h7/pins_BTT_SKR_V3_0_common.h | 569 - src/pins/teensy2/env_validate.h | 28 - src/pins/teensy2/pins_5DPRINT.h | 146 - src/pins/teensy2/pins_BRAINWAVE.h | 126 - src/pins/teensy2/pins_BRAINWAVE_PRO.h | 136 - src/pins/teensy2/pins_PRINTRBOARD.h | 170 - src/pins/teensy2/pins_PRINTRBOARD_REVF.h | 280 - src/pins/teensy2/pins_SAV_MKI.h | 183 - src/pins/teensy2/pins_TEENSY2.h | 186 - src/pins/teensy2/pins_TEENSYLU.h | 168 - src/pins/teensy3/pins_TEENSY31_32.h | 112 - src/pins/teensy3/pins_TEENSY35_36.h | 152 - src/pins/teensy4/pins_T41U5XBB.h | 126 - src/pins/teensy4/pins_TEENSY41.h | 131 - src/sd/Sd2Card.cpp | 681 - src/sd/Sd2Card.h | 197 - src/sd/Sd2Card_sdio.h | 59 - src/sd/SdBaseFile.cpp | 2236 ---- src/sd/SdBaseFile.h | 402 - src/sd/SdFatConfig.h | 112 - src/sd/SdFatStructs.h | 609 - src/sd/SdFatUtil.cpp | 62 - src/sd/SdFatUtil.h | 42 - src/sd/SdFile.cpp | 102 - src/sd/SdFile.h | 55 - src/sd/SdInfo.h | 265 - src/sd/SdVolume.cpp | 405 - src/sd/SdVolume.h | 201 - src/sd/cardreader.cpp | 1343 -- src/sd/cardreader.h | 388 - src/sd/disk_io_driver.h | 67 - src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp | 328 - src/sd/usb_flashdrive/Sd2Card_FlashDrive.h | 80 - src/sd/usb_flashdrive/lib-uhs2/README.txt | 43 - src/sd/usb_flashdrive/lib-uhs2/Usb.cpp | 795 -- src/sd/usb_flashdrive/lib-uhs2/Usb.h | 53 - src/sd/usb_flashdrive/lib-uhs2/UsbCore.h | 312 - src/sd/usb_flashdrive/lib-uhs2/address.h | 271 - .../usb_flashdrive/lib-uhs2/confdescparser.h | 201 - src/sd/usb_flashdrive/lib-uhs2/hexdump.h | 68 - src/sd/usb_flashdrive/lib-uhs2/macros.h | 86 - src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp | 1209 -- src/sd/usb_flashdrive/lib-uhs2/masstorage.h | 559 - src/sd/usb_flashdrive/lib-uhs2/max3421e.h | 242 - src/sd/usb_flashdrive/lib-uhs2/message.cpp | 128 - src/sd/usb_flashdrive/lib-uhs2/message.h | 85 - src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp | 77 - src/sd/usb_flashdrive/lib-uhs2/parsetools.h | 145 - src/sd/usb_flashdrive/lib-uhs2/printhex.h | 80 - src/sd/usb_flashdrive/lib-uhs2/settings.h | 236 - src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h | 170 - src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp | 206 - src/sd/usb_flashdrive/lib-uhs2/usbhost.h | 58 - src/sd/usb_flashdrive/lib-uhs3/README.txt | 29 - .../UHS_BULK_STORAGE/UHS_BULK_STORAGE.h | 249 - .../UHS_BULK_STORAGE_INLINE.h | 1205 -- .../UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h | 327 - .../lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h | 33 - .../lib-uhs3/UHS_host/UHS_USB_IDs.h | 2993 ----- .../lib-uhs3/UHS_host/UHS_UsbCore.h | 336 - .../lib-uhs3/UHS_host/UHS_address.h | 248 - .../lib-uhs3/UHS_host/UHS_hexdump.h | 70 - .../lib-uhs3/UHS_host/UHS_host.h | 111 - .../lib-uhs3/UHS_host/UHS_host_INLINE.h | 1222 -- .../lib-uhs3/UHS_host/UHS_macros.h | 230 - .../lib-uhs3/UHS_host/UHS_message.h | 91 - .../lib-uhs3/UHS_host/UHS_printf_HELPER.h | 200 - .../lib-uhs3/UHS_host/UHS_printhex.h | 96 - .../lib-uhs3/UHS_host/UHS_settings.h | 141 - .../lib-uhs3/UHS_host/UHS_usb_ch9.h | 222 - .../lib-uhs3/UHS_host/UHS_usbhost.h | 449 - .../lib-uhs3/UHS_host/UHS_util_INLINE.h | 129 - .../UHS_host/USB_HOST_SHIELD/UHS_max3421e.h | 226 - .../USB_HOST_SHIELD/USB_HOST_SHIELD.h | 519 - .../USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h | 1003 -- .../lib-uhs3/UHS_host/macro_logic.h | 152 - .../lib-uhs3/dyn_SWI/SWI_INLINE.h | 244 - .../usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h | 172 - 2087 files changed, 456404 deletions(-) delete mode 100644 Configuration.h delete mode 100644 Configuration_adv.h delete mode 100644 Makefile delete mode 100644 Marlin.ino.mega.hex delete mode 100644 Marlin.ino.with_bootloader.mega.hex delete mode 100644 Marlin/Configuration.h delete mode 100644 Marlin/Configuration_adv.h delete mode 100644 Marlin/Marlin.ino delete mode 100644 Marlin/Version.h delete mode 100644 Version.h delete mode 100644 lib/readme.txt delete mode 100644 src/HAL/AVR/HAL.cpp delete mode 100644 src/HAL/AVR/HAL.h delete mode 100644 src/HAL/AVR/HAL_SPI.cpp delete mode 100644 src/HAL/AVR/MarlinSPI.h delete mode 100644 src/HAL/AVR/MarlinSerial.cpp delete mode 100644 src/HAL/AVR/MarlinSerial.h delete mode 100644 src/HAL/AVR/Servo.cpp delete mode 100644 src/HAL/AVR/ServoTimers.h delete mode 100644 src/HAL/AVR/eeprom.cpp delete mode 100644 src/HAL/AVR/endstop_interrupts.h delete mode 100644 src/HAL/AVR/fast_pwm.cpp delete mode 100644 src/HAL/AVR/fastio.cpp delete mode 100644 src/HAL/AVR/fastio.h delete mode 100644 src/HAL/AVR/fastio/fastio_1280.h delete mode 100644 src/HAL/AVR/fastio/fastio_1281.h delete mode 100644 src/HAL/AVR/fastio/fastio_168.h delete mode 100644 src/HAL/AVR/fastio/fastio_644.h delete mode 100644 src/HAL/AVR/fastio/fastio_AT90USB.h delete mode 100644 src/HAL/AVR/inc/Conditionals_LCD.h delete mode 100644 src/HAL/AVR/inc/Conditionals_adv.h delete mode 100644 src/HAL/AVR/inc/Conditionals_post.h delete mode 100644 src/HAL/AVR/inc/SanityCheck.h delete mode 100644 src/HAL/AVR/math.h delete mode 100644 src/HAL/AVR/pinsDebug.h delete mode 100644 src/HAL/AVR/pinsDebug_Teensyduino.h delete mode 100644 src/HAL/AVR/pinsDebug_plus_70.h delete mode 100644 src/HAL/AVR/spi_pins.h delete mode 100644 src/HAL/AVR/timers.h delete mode 100644 src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp delete mode 100644 src/HAL/DUE/HAL.cpp delete mode 100644 src/HAL/DUE/HAL.h delete mode 100644 src/HAL/DUE/HAL_SPI.cpp delete mode 100644 src/HAL/DUE/InterruptVectors.cpp delete mode 100644 src/HAL/DUE/InterruptVectors.h delete mode 100644 src/HAL/DUE/MarlinSPI.h delete mode 100644 src/HAL/DUE/MarlinSerial.cpp delete mode 100644 src/HAL/DUE/MarlinSerial.h delete mode 100644 src/HAL/DUE/MarlinSerialUSB.cpp delete mode 100644 src/HAL/DUE/MarlinSerialUSB.h delete mode 100644 src/HAL/DUE/MinSerial.cpp delete mode 100644 src/HAL/DUE/Servo.cpp delete mode 100644 src/HAL/DUE/ServoTimers.h delete mode 100644 src/HAL/DUE/Tone.cpp delete mode 100644 src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp delete mode 100644 src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp delete mode 100644 src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp delete mode 100644 src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp delete mode 100644 src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h delete mode 100644 src/HAL/DUE/eeprom_flash.cpp delete mode 100644 src/HAL/DUE/eeprom_wired.cpp delete mode 100644 src/HAL/DUE/endstop_interrupts.h delete mode 100644 src/HAL/DUE/fastio.h delete mode 100644 src/HAL/DUE/fastio/G2_PWM.cpp delete mode 100644 src/HAL/DUE/fastio/G2_PWM.h delete mode 100644 src/HAL/DUE/fastio/G2_pins.h delete mode 100644 src/HAL/DUE/inc/Conditionals_LCD.h delete mode 100644 src/HAL/DUE/inc/Conditionals_adv.h delete mode 100644 src/HAL/DUE/inc/Conditionals_post.h delete mode 100644 src/HAL/DUE/inc/SanityCheck.h delete mode 100644 src/HAL/DUE/pinsDebug.h delete mode 100644 src/HAL/DUE/spi_pins.h delete mode 100644 src/HAL/DUE/timers.cpp delete mode 100644 src/HAL/DUE/timers.h delete mode 100644 src/HAL/DUE/upload_extra_script.py delete mode 100644 src/HAL/DUE/usb/arduino_due_x.h delete mode 100644 src/HAL/DUE/usb/compiler.h delete mode 100644 src/HAL/DUE/usb/conf_access.h delete mode 100644 src/HAL/DUE/usb/conf_clock.h delete mode 100644 src/HAL/DUE/usb/conf_usb.h delete mode 100644 src/HAL/DUE/usb/ctrl_access.c delete mode 100644 src/HAL/DUE/usb/ctrl_access.h delete mode 100644 src/HAL/DUE/usb/genclk.h delete mode 100644 src/HAL/DUE/usb/mrepeat.h delete mode 100644 src/HAL/DUE/usb/osc.h delete mode 100644 src/HAL/DUE/usb/pll.h delete mode 100644 src/HAL/DUE/usb/preprocessor.h delete mode 100644 src/HAL/DUE/usb/sbc_protocol.h delete mode 100644 src/HAL/DUE/usb/sd_mmc_spi_mem.cpp delete mode 100644 src/HAL/DUE/usb/sd_mmc_spi_mem.h delete mode 100644 src/HAL/DUE/usb/spc_protocol.h delete mode 100644 src/HAL/DUE/usb/stringz.h delete mode 100644 src/HAL/DUE/usb/sysclk.c delete mode 100644 src/HAL/DUE/usb/sysclk.h delete mode 100644 src/HAL/DUE/usb/tpaste.h delete mode 100644 src/HAL/DUE/usb/udc.c delete mode 100644 src/HAL/DUE/usb/udc.h delete mode 100644 src/HAL/DUE/usb/udc_desc.h delete mode 100644 src/HAL/DUE/usb/udd.h delete mode 100644 src/HAL/DUE/usb/udi.h delete mode 100644 src/HAL/DUE/usb/udi_cdc.c delete mode 100644 src/HAL/DUE/usb/udi_cdc.h delete mode 100644 src/HAL/DUE/usb/udi_cdc_conf.h delete mode 100644 src/HAL/DUE/usb/udi_cdc_desc.c delete mode 100644 src/HAL/DUE/usb/udi_composite_desc.c delete mode 100644 src/HAL/DUE/usb/udi_msc.c delete mode 100644 src/HAL/DUE/usb/udi_msc.h delete mode 100644 src/HAL/DUE/usb/uotghs_device_due.c delete mode 100644 src/HAL/DUE/usb/uotghs_device_due.h delete mode 100644 src/HAL/DUE/usb/uotghs_otg.h delete mode 100644 src/HAL/DUE/usb/usb_protocol.h delete mode 100644 src/HAL/DUE/usb/usb_protocol_cdc.h delete mode 100644 src/HAL/DUE/usb/usb_protocol_msc.h delete mode 100644 src/HAL/DUE/usb/usb_task.c delete mode 100644 src/HAL/DUE/usb/usb_task.h delete mode 100644 src/HAL/ESP32/FlushableHardwareSerial.cpp delete mode 100644 src/HAL/ESP32/FlushableHardwareSerial.h delete mode 100644 src/HAL/ESP32/HAL.cpp delete mode 100644 src/HAL/ESP32/HAL.h delete mode 100644 src/HAL/ESP32/HAL_SPI.cpp delete mode 100644 src/HAL/ESP32/MarlinSPI.h delete mode 100644 src/HAL/ESP32/Servo.cpp delete mode 100644 src/HAL/ESP32/Servo.h delete mode 100644 src/HAL/ESP32/Tone.cpp delete mode 100644 src/HAL/ESP32/WebSocketSerial.cpp delete mode 100644 src/HAL/ESP32/WebSocketSerial.h delete mode 100644 src/HAL/ESP32/eeprom.cpp delete mode 100644 src/HAL/ESP32/endstop_interrupts.h delete mode 100644 src/HAL/ESP32/esp32.csv delete mode 100644 src/HAL/ESP32/fastio.h delete mode 100644 src/HAL/ESP32/i2s.cpp delete mode 100644 src/HAL/ESP32/i2s.h delete mode 100644 src/HAL/ESP32/inc/Conditionals_LCD.h delete mode 100644 src/HAL/ESP32/inc/Conditionals_adv.h delete mode 100644 src/HAL/ESP32/inc/Conditionals_post.h delete mode 100644 src/HAL/ESP32/inc/SanityCheck.h delete mode 100644 src/HAL/ESP32/ota.cpp delete mode 100644 src/HAL/ESP32/ota.h delete mode 100644 src/HAL/ESP32/servotimers.h delete mode 100644 src/HAL/ESP32/spi_pins.h delete mode 100644 src/HAL/ESP32/spiffs.cpp delete mode 100644 src/HAL/ESP32/spiffs.h delete mode 100644 src/HAL/ESP32/timers.cpp delete mode 100644 src/HAL/ESP32/timers.h delete mode 100644 src/HAL/ESP32/u8g_esp32_spi.cpp delete mode 100644 src/HAL/ESP32/web.cpp delete mode 100644 src/HAL/ESP32/web.h delete mode 100644 src/HAL/ESP32/wifi.cpp delete mode 100644 src/HAL/ESP32/wifi.h delete mode 100644 src/HAL/HAL.h delete mode 100644 src/HAL/LINUX/HAL.cpp delete mode 100644 src/HAL/LINUX/HAL.h delete mode 100644 src/HAL/LINUX/MarlinSPI.h delete mode 100644 src/HAL/LINUX/arduino.cpp delete mode 100644 src/HAL/LINUX/eeprom.cpp delete mode 100644 src/HAL/LINUX/fastio.h delete mode 100644 src/HAL/LINUX/hardware/Clock.cpp delete mode 100644 src/HAL/LINUX/hardware/Clock.h delete mode 100644 src/HAL/LINUX/hardware/Gpio.cpp delete mode 100644 src/HAL/LINUX/hardware/Gpio.h delete mode 100644 src/HAL/LINUX/hardware/Heater.cpp delete mode 100644 src/HAL/LINUX/hardware/Heater.h delete mode 100644 src/HAL/LINUX/hardware/IOLoggerCSV.cpp delete mode 100644 src/HAL/LINUX/hardware/IOLoggerCSV.h delete mode 100644 src/HAL/LINUX/hardware/LinearAxis.cpp delete mode 100644 src/HAL/LINUX/hardware/LinearAxis.h delete mode 100644 src/HAL/LINUX/hardware/Timer.cpp delete mode 100644 src/HAL/LINUX/hardware/Timer.h delete mode 100644 src/HAL/LINUX/inc/Conditionals_LCD.h delete mode 100644 src/HAL/LINUX/inc/Conditionals_adv.h delete mode 100644 src/HAL/LINUX/inc/Conditionals_post.h delete mode 100644 src/HAL/LINUX/inc/SanityCheck.h delete mode 100644 src/HAL/LINUX/include/Arduino.h delete mode 100644 src/HAL/LINUX/include/pinmapping.cpp delete mode 100644 src/HAL/LINUX/include/pinmapping.h delete mode 100644 src/HAL/LINUX/include/serial.h delete mode 100644 src/HAL/LINUX/main.cpp delete mode 100644 src/HAL/LINUX/pinsDebug.h delete mode 100644 src/HAL/LINUX/servo_private.h delete mode 100644 src/HAL/LINUX/spi_pins.h delete mode 100644 src/HAL/LINUX/timers.cpp delete mode 100644 src/HAL/LINUX/timers.h delete mode 100644 src/HAL/LPC1768/HAL.cpp delete mode 100644 src/HAL/LPC1768/HAL.h delete mode 100644 src/HAL/LPC1768/HAL_SPI.cpp delete mode 100644 src/HAL/LPC1768/MarlinSPI.h delete mode 100644 src/HAL/LPC1768/MarlinSerial.cpp delete mode 100644 src/HAL/LPC1768/MarlinSerial.h delete mode 100644 src/HAL/LPC1768/MinSerial.cpp delete mode 100644 src/HAL/LPC1768/Servo.h delete mode 100644 src/HAL/LPC1768/eeprom_flash.cpp delete mode 100644 src/HAL/LPC1768/eeprom_sdcard.cpp delete mode 100644 src/HAL/LPC1768/eeprom_wired.cpp delete mode 100644 src/HAL/LPC1768/endstop_interrupts.h delete mode 100644 src/HAL/LPC1768/fast_pwm.cpp delete mode 100644 src/HAL/LPC1768/fastio.h delete mode 100644 src/HAL/LPC1768/inc/Conditionals_LCD.h delete mode 100644 src/HAL/LPC1768/inc/Conditionals_adv.h delete mode 100644 src/HAL/LPC1768/inc/Conditionals_post.h delete mode 100644 src/HAL/LPC1768/inc/SanityCheck.h delete mode 100644 src/HAL/LPC1768/include/SPI.h delete mode 100644 src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c delete mode 100644 src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h delete mode 100644 src/HAL/LPC1768/include/i2c_util.c delete mode 100644 src/HAL/LPC1768/include/i2c_util.h delete mode 100644 src/HAL/LPC1768/main.cpp delete mode 100644 src/HAL/LPC1768/pinsDebug.h delete mode 100644 src/HAL/LPC1768/spi_pins.h delete mode 100644 src/HAL/LPC1768/tft/tft_spi.cpp delete mode 100644 src/HAL/LPC1768/tft/tft_spi.h delete mode 100644 src/HAL/LPC1768/tft/xpt2046.cpp delete mode 100644 src/HAL/LPC1768/tft/xpt2046.h delete mode 100644 src/HAL/LPC1768/timers.cpp delete mode 100644 src/HAL/LPC1768/timers.h delete mode 100644 src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp delete mode 100644 src/HAL/LPC1768/u8g/LCD_I2C_routines.h delete mode 100644 src/HAL/LPC1768/u8g/LCD_defines.h delete mode 100644 src/HAL/LPC1768/u8g/LCD_delay.h delete mode 100644 src/HAL/LPC1768/u8g/LCD_pin_routines.c delete mode 100644 src/HAL/LPC1768/u8g/LCD_pin_routines.h delete mode 100644 src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp delete mode 100644 src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp delete mode 100644 src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp delete mode 100644 src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp delete mode 100644 src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp delete mode 100644 src/HAL/LPC1768/upload_extra_script.py delete mode 100644 src/HAL/LPC1768/usb_serial.cpp delete mode 100644 src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf delete mode 100644 src/HAL/NATIVE_SIM/HAL.h delete mode 100644 src/HAL/NATIVE_SIM/MarlinSPI.h delete mode 100644 src/HAL/NATIVE_SIM/fastio.h delete mode 100644 src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h delete mode 100644 src/HAL/NATIVE_SIM/inc/Conditionals_adv.h delete mode 100644 src/HAL/NATIVE_SIM/inc/Conditionals_post.h delete mode 100644 src/HAL/NATIVE_SIM/inc/SanityCheck.h delete mode 100644 src/HAL/NATIVE_SIM/pinsDebug.h delete mode 100644 src/HAL/NATIVE_SIM/servo_private.h delete mode 100644 src/HAL/NATIVE_SIM/spi_pins.h delete mode 100644 src/HAL/NATIVE_SIM/tft/tft_spi.h delete mode 100644 src/HAL/NATIVE_SIM/tft/xpt2046.h delete mode 100644 src/HAL/NATIVE_SIM/timers.h delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_defines.h delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_delay.h delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp delete mode 100644 src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h delete mode 100644 src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp delete mode 100644 src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp delete mode 100644 src/HAL/SAMD51/HAL.cpp delete mode 100644 src/HAL/SAMD51/HAL.h delete mode 100644 src/HAL/SAMD51/HAL_SPI.cpp delete mode 100644 src/HAL/SAMD51/MarlinSPI.h delete mode 100644 src/HAL/SAMD51/MarlinSerial_AGCM4.cpp delete mode 100644 src/HAL/SAMD51/MarlinSerial_AGCM4.h delete mode 100644 src/HAL/SAMD51/QSPIFlash.cpp delete mode 100644 src/HAL/SAMD51/QSPIFlash.h delete mode 100644 src/HAL/SAMD51/SAMD51.h delete mode 100644 src/HAL/SAMD51/Servo.cpp delete mode 100644 src/HAL/SAMD51/ServoTimers.h delete mode 100644 src/HAL/SAMD51/eeprom_flash.cpp delete mode 100644 src/HAL/SAMD51/eeprom_qspi.cpp delete mode 100644 src/HAL/SAMD51/eeprom_wired.cpp delete mode 100644 src/HAL/SAMD51/endstop_interrupts.h delete mode 100644 src/HAL/SAMD51/fastio.h delete mode 100644 src/HAL/SAMD51/inc/Conditionals_LCD.h delete mode 100644 src/HAL/SAMD51/inc/Conditionals_adv.h delete mode 100644 src/HAL/SAMD51/inc/Conditionals_post.h delete mode 100644 src/HAL/SAMD51/inc/SanityCheck.h delete mode 100644 src/HAL/SAMD51/pinsDebug.h delete mode 100644 src/HAL/SAMD51/spi_pins.h delete mode 100644 src/HAL/SAMD51/timers.cpp delete mode 100644 src/HAL/SAMD51/timers.h delete mode 100644 src/HAL/STM32/HAL.cpp delete mode 100644 src/HAL/STM32/HAL.h delete mode 100644 src/HAL/STM32/HAL_SPI.cpp delete mode 100644 src/HAL/STM32/MarlinSPI.cpp delete mode 100644 src/HAL/STM32/MarlinSPI.h delete mode 100644 src/HAL/STM32/MarlinSerial.cpp delete mode 100644 src/HAL/STM32/MarlinSerial.h delete mode 100644 src/HAL/STM32/MinSerial.cpp delete mode 100644 src/HAL/STM32/README.md delete mode 100644 src/HAL/STM32/Servo.cpp delete mode 100644 src/HAL/STM32/Servo.h delete mode 100644 src/HAL/STM32/eeprom_bl24cxx.cpp delete mode 100644 src/HAL/STM32/eeprom_flash.cpp delete mode 100644 src/HAL/STM32/eeprom_if_iic.cpp delete mode 100644 src/HAL/STM32/eeprom_sdcard.cpp delete mode 100644 src/HAL/STM32/eeprom_sram.cpp delete mode 100644 src/HAL/STM32/eeprom_wired.cpp delete mode 100644 src/HAL/STM32/endstop_interrupts.h delete mode 100644 src/HAL/STM32/fast_pwm.cpp delete mode 100644 src/HAL/STM32/fastio.cpp delete mode 100644 src/HAL/STM32/fastio.h delete mode 100644 src/HAL/STM32/inc/Conditionals_LCD.h delete mode 100644 src/HAL/STM32/inc/Conditionals_adv.h delete mode 100644 src/HAL/STM32/inc/Conditionals_post.h delete mode 100644 src/HAL/STM32/inc/SanityCheck.h delete mode 100644 src/HAL/STM32/msc_sd.cpp delete mode 100644 src/HAL/STM32/msc_sd.h delete mode 100644 src/HAL/STM32/pinsDebug.h delete mode 100644 src/HAL/STM32/pins_Xref.h delete mode 100644 src/HAL/STM32/sdio.cpp delete mode 100644 src/HAL/STM32/sdio.h delete mode 100644 src/HAL/STM32/spi_pins.h delete mode 100644 src/HAL/STM32/tft/gt911.cpp delete mode 100644 src/HAL/STM32/tft/gt911.h delete mode 100644 src/HAL/STM32/tft/tft_fsmc.cpp delete mode 100644 src/HAL/STM32/tft/tft_fsmc.h delete mode 100644 src/HAL/STM32/tft/tft_ltdc.cpp delete mode 100644 src/HAL/STM32/tft/tft_ltdc.h delete mode 100644 src/HAL/STM32/tft/tft_spi.cpp delete mode 100644 src/HAL/STM32/tft/tft_spi.h delete mode 100644 src/HAL/STM32/tft/xpt2046.cpp delete mode 100644 src/HAL/STM32/tft/xpt2046.h delete mode 100644 src/HAL/STM32/timers.cpp delete mode 100644 src/HAL/STM32/timers.h delete mode 100644 src/HAL/STM32/usb_host.cpp delete mode 100644 src/HAL/STM32/usb_host.h delete mode 100644 src/HAL/STM32/usb_serial.cpp delete mode 100644 src/HAL/STM32/usb_serial.h delete mode 100644 src/HAL/STM32F1/HAL.cpp delete mode 100644 src/HAL/STM32F1/HAL.h delete mode 100644 src/HAL/STM32F1/HAL_SPI.cpp delete mode 100644 src/HAL/STM32F1/MarlinSPI.h delete mode 100644 src/HAL/STM32F1/MarlinSerial.cpp delete mode 100644 src/HAL/STM32F1/MarlinSerial.h delete mode 100644 src/HAL/STM32F1/MinSerial.cpp delete mode 100644 src/HAL/STM32F1/README.md delete mode 100644 src/HAL/STM32F1/SPI.cpp delete mode 100644 src/HAL/STM32F1/SPI.h delete mode 100644 src/HAL/STM32F1/Servo.cpp delete mode 100644 src/HAL/STM32F1/Servo.h delete mode 100644 src/HAL/STM32F1/build_flags.py delete mode 100644 src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp delete mode 100644 src/HAL/STM32F1/eeprom_bl24cxx.cpp delete mode 100644 src/HAL/STM32F1/eeprom_flash.cpp delete mode 100644 src/HAL/STM32F1/eeprom_if_iic.cpp delete mode 100644 src/HAL/STM32F1/eeprom_sdcard.cpp delete mode 100644 src/HAL/STM32F1/eeprom_wired.cpp delete mode 100644 src/HAL/STM32F1/endstop_interrupts.h delete mode 100644 src/HAL/STM32F1/fast_pwm.cpp delete mode 100644 src/HAL/STM32F1/fastio.h delete mode 100644 src/HAL/STM32F1/inc/Conditionals_LCD.h delete mode 100644 src/HAL/STM32F1/inc/Conditionals_adv.h delete mode 100644 src/HAL/STM32F1/inc/Conditionals_post.h delete mode 100644 src/HAL/STM32F1/inc/SanityCheck.h delete mode 100644 src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf delete mode 100644 src/HAL/STM32F1/msc_sd.cpp delete mode 100644 src/HAL/STM32F1/msc_sd.h delete mode 100644 src/HAL/STM32F1/onboard_sd.cpp delete mode 100644 src/HAL/STM32F1/onboard_sd.h delete mode 100644 src/HAL/STM32F1/pinsDebug.h delete mode 100644 src/HAL/STM32F1/sdio.cpp delete mode 100644 src/HAL/STM32F1/sdio.h delete mode 100644 src/HAL/STM32F1/spi_pins.h delete mode 100644 src/HAL/STM32F1/tft/tft_fsmc.cpp delete mode 100644 src/HAL/STM32F1/tft/tft_fsmc.h delete mode 100644 src/HAL/STM32F1/tft/tft_spi.cpp delete mode 100644 src/HAL/STM32F1/tft/tft_spi.h delete mode 100644 src/HAL/STM32F1/tft/xpt2046.cpp delete mode 100644 src/HAL/STM32F1/tft/xpt2046.h delete mode 100644 src/HAL/STM32F1/timers.cpp delete mode 100644 src/HAL/STM32F1/timers.h delete mode 100644 src/HAL/TEENSY31_32/HAL.cpp delete mode 100644 src/HAL/TEENSY31_32/HAL.h delete mode 100644 src/HAL/TEENSY31_32/HAL_SPI.cpp delete mode 100644 src/HAL/TEENSY31_32/MarlinSPI.h delete mode 100644 src/HAL/TEENSY31_32/Servo.cpp delete mode 100644 src/HAL/TEENSY31_32/Servo.h delete mode 100644 src/HAL/TEENSY31_32/eeprom.cpp delete mode 100644 src/HAL/TEENSY31_32/endstop_interrupts.h delete mode 100644 src/HAL/TEENSY31_32/fastio.h delete mode 100644 src/HAL/TEENSY31_32/inc/Conditionals_LCD.h delete mode 100644 src/HAL/TEENSY31_32/inc/Conditionals_adv.h delete mode 100644 src/HAL/TEENSY31_32/inc/Conditionals_post.h delete mode 100644 src/HAL/TEENSY31_32/inc/SanityCheck.h delete mode 100644 src/HAL/TEENSY31_32/pinsDebug.h delete mode 100644 src/HAL/TEENSY31_32/spi_pins.h delete mode 100644 src/HAL/TEENSY31_32/timers.cpp delete mode 100644 src/HAL/TEENSY31_32/timers.h delete mode 100644 src/HAL/TEENSY35_36/HAL.cpp delete mode 100644 src/HAL/TEENSY35_36/HAL.h delete mode 100644 src/HAL/TEENSY35_36/HAL_SPI.cpp delete mode 100644 src/HAL/TEENSY35_36/MarlinSPI.h delete mode 100644 src/HAL/TEENSY35_36/Servo.cpp delete mode 100644 src/HAL/TEENSY35_36/Servo.h delete mode 100644 src/HAL/TEENSY35_36/eeprom.cpp delete mode 100644 src/HAL/TEENSY35_36/endstop_interrupts.h delete mode 100644 src/HAL/TEENSY35_36/fastio.h delete mode 100644 src/HAL/TEENSY35_36/inc/Conditionals_LCD.h delete mode 100644 src/HAL/TEENSY35_36/inc/Conditionals_adv.h delete mode 100644 src/HAL/TEENSY35_36/inc/Conditionals_post.h delete mode 100644 src/HAL/TEENSY35_36/inc/SanityCheck.h delete mode 100644 src/HAL/TEENSY35_36/pinsDebug.h delete mode 100644 src/HAL/TEENSY35_36/spi_pins.h delete mode 100644 src/HAL/TEENSY35_36/timers.cpp delete mode 100644 src/HAL/TEENSY35_36/timers.h delete mode 100644 src/HAL/TEENSY40_41/HAL.cpp delete mode 100644 src/HAL/TEENSY40_41/HAL.h delete mode 100644 src/HAL/TEENSY40_41/HAL_SPI.cpp delete mode 100644 src/HAL/TEENSY40_41/MarlinSPI.h delete mode 100644 src/HAL/TEENSY40_41/Servo.cpp delete mode 100644 src/HAL/TEENSY40_41/Servo.h delete mode 100644 src/HAL/TEENSY40_41/eeprom.cpp delete mode 100644 src/HAL/TEENSY40_41/endstop_interrupts.h delete mode 100644 src/HAL/TEENSY40_41/fastio.h delete mode 100644 src/HAL/TEENSY40_41/inc/Conditionals_LCD.h delete mode 100644 src/HAL/TEENSY40_41/inc/Conditionals_adv.h delete mode 100644 src/HAL/TEENSY40_41/inc/Conditionals_post.h delete mode 100644 src/HAL/TEENSY40_41/inc/SanityCheck.h delete mode 100644 src/HAL/TEENSY40_41/pinsDebug.h delete mode 100644 src/HAL/TEENSY40_41/spi_pins.h delete mode 100644 src/HAL/TEENSY40_41/timers.cpp delete mode 100644 src/HAL/TEENSY40_41/timers.h delete mode 100644 src/HAL/platforms.h delete mode 100644 src/HAL/shared/Delay.cpp delete mode 100644 src/HAL/shared/Delay.h delete mode 100644 src/HAL/shared/HAL.cpp delete mode 100644 src/HAL/shared/HAL_SPI.h delete mode 100644 src/HAL/shared/HAL_ST7920.h delete mode 100644 src/HAL/shared/HAL_spi_L6470.cpp delete mode 100644 src/HAL/shared/Marduino.h delete mode 100644 src/HAL/shared/MinSerial.cpp delete mode 100644 src/HAL/shared/MinSerial.h delete mode 100644 src/HAL/shared/backtrace/backtrace.cpp delete mode 100644 src/HAL/shared/backtrace/backtrace.h delete mode 100644 src/HAL/shared/backtrace/unwarm.cpp delete mode 100644 src/HAL/shared/backtrace/unwarm.h delete mode 100644 src/HAL/shared/backtrace/unwarm_arm.cpp delete mode 100644 src/HAL/shared/backtrace/unwarm_thumb.cpp delete mode 100644 src/HAL/shared/backtrace/unwarmbytab.cpp delete mode 100644 src/HAL/shared/backtrace/unwarmbytab.h delete mode 100644 src/HAL/shared/backtrace/unwarmmem.cpp delete mode 100644 src/HAL/shared/backtrace/unwarmmem.h delete mode 100644 src/HAL/shared/backtrace/unwinder.cpp delete mode 100644 src/HAL/shared/backtrace/unwinder.h delete mode 100644 src/HAL/shared/backtrace/unwmemaccess.cpp delete mode 100644 src/HAL/shared/backtrace/unwmemaccess.h delete mode 100644 src/HAL/shared/cpu_exception/exception_arm.cpp delete mode 100644 src/HAL/shared/cpu_exception/exception_hook.cpp delete mode 100644 src/HAL/shared/cpu_exception/exception_hook.h delete mode 100644 src/HAL/shared/eeprom_api.cpp delete mode 100644 src/HAL/shared/eeprom_api.h delete mode 100644 src/HAL/shared/eeprom_if.h delete mode 100644 src/HAL/shared/eeprom_if_i2c.cpp delete mode 100644 src/HAL/shared/eeprom_if_spi.cpp delete mode 100644 src/HAL/shared/esp_wifi.cpp delete mode 100644 src/HAL/shared/esp_wifi.h delete mode 100644 src/HAL/shared/math_32bit.h delete mode 100644 src/HAL/shared/progmem.h delete mode 100644 src/HAL/shared/servo.cpp delete mode 100644 src/HAL/shared/servo.h delete mode 100644 src/HAL/shared/servo_private.h delete mode 100644 src/MarlinCore.cpp delete mode 100644 src/MarlinCore.h delete mode 100644 src/core/boards.h delete mode 100644 src/core/bug_on.h delete mode 100644 src/core/debug_out.h delete mode 100644 src/core/debug_section.h delete mode 100644 src/core/drivers.h delete mode 100644 src/core/language.h delete mode 100644 src/core/macros.h delete mode 100644 src/core/millis_t.h delete mode 100644 src/core/multi_language.h delete mode 100644 src/core/serial.cpp delete mode 100644 src/core/serial.h delete mode 100644 src/core/serial_base.h delete mode 100644 src/core/serial_hook.h delete mode 100644 src/core/types.h delete mode 100644 src/core/utility.cpp delete mode 100644 src/core/utility.h delete mode 100644 src/feature/adc/adc_mcp3426.cpp delete mode 100644 src/feature/adc/adc_mcp3426.h delete mode 100644 src/feature/ammeter.cpp delete mode 100644 src/feature/ammeter.h delete mode 100644 src/feature/babystep.cpp delete mode 100644 src/feature/babystep.h delete mode 100644 src/feature/backlash.cpp delete mode 100644 src/feature/backlash.h delete mode 100644 src/feature/baricuda.cpp delete mode 100644 src/feature/baricuda.h delete mode 100644 src/feature/bedlevel/abl/bbl.cpp delete mode 100644 src/feature/bedlevel/abl/bbl.h delete mode 100644 src/feature/bedlevel/bedlevel.cpp delete mode 100644 src/feature/bedlevel/bedlevel.h delete mode 100644 src/feature/bedlevel/hilbert_curve.cpp delete mode 100644 src/feature/bedlevel/hilbert_curve.h delete mode 100644 src/feature/bedlevel/mbl/mesh_bed_leveling.cpp delete mode 100644 src/feature/bedlevel/mbl/mesh_bed_leveling.h delete mode 100644 src/feature/bedlevel/ubl/ubl.cpp delete mode 100644 src/feature/bedlevel/ubl/ubl.h delete mode 100644 src/feature/bedlevel/ubl/ubl_G29.cpp delete mode 100644 src/feature/bedlevel/ubl/ubl_motion.cpp delete mode 100644 src/feature/binary_stream.cpp delete mode 100644 src/feature/binary_stream.h delete mode 100644 src/feature/bltouch.cpp delete mode 100644 src/feature/bltouch.h delete mode 100644 src/feature/cancel_object.cpp delete mode 100644 src/feature/cancel_object.h delete mode 100644 src/feature/caselight.cpp delete mode 100644 src/feature/caselight.h delete mode 100644 src/feature/closedloop.cpp delete mode 100644 src/feature/closedloop.h delete mode 100644 src/feature/controllerfan.cpp delete mode 100644 src/feature/controllerfan.h delete mode 100644 src/feature/cooler.cpp delete mode 100644 src/feature/cooler.h delete mode 100644 src/feature/dac/dac_dac084s085.cpp delete mode 100644 src/feature/dac/dac_dac084s085.h delete mode 100644 src/feature/dac/dac_mcp4728.cpp delete mode 100644 src/feature/dac/dac_mcp4728.h delete mode 100644 src/feature/dac/stepper_dac.cpp delete mode 100644 src/feature/dac/stepper_dac.h delete mode 100644 src/feature/digipot/digipot.h delete mode 100644 src/feature/digipot/digipot_mcp4018.cpp delete mode 100644 src/feature/digipot/digipot_mcp4451.cpp delete mode 100644 src/feature/direct_stepping.cpp delete mode 100644 src/feature/direct_stepping.h delete mode 100644 src/feature/e_parser.cpp delete mode 100644 src/feature/e_parser.h delete mode 100644 src/feature/easythreed_ui.cpp delete mode 100644 src/feature/easythreed_ui.h delete mode 100644 src/feature/encoder_i2c.cpp delete mode 100644 src/feature/encoder_i2c.h delete mode 100644 src/feature/ethernet.cpp delete mode 100644 src/feature/ethernet.h delete mode 100644 src/feature/fancheck.cpp delete mode 100644 src/feature/fancheck.h delete mode 100644 src/feature/fanmux.cpp delete mode 100644 src/feature/fanmux.h delete mode 100644 src/feature/filwidth.cpp delete mode 100644 src/feature/filwidth.h delete mode 100644 src/feature/fwretract.cpp delete mode 100644 src/feature/fwretract.h delete mode 100644 src/feature/host_actions.cpp delete mode 100644 src/feature/host_actions.h delete mode 100644 src/feature/hotend_idle.cpp delete mode 100644 src/feature/hotend_idle.h delete mode 100644 src/feature/joystick.cpp delete mode 100644 src/feature/joystick.h delete mode 100644 src/feature/leds/blinkm.cpp delete mode 100644 src/feature/leds/blinkm.h delete mode 100644 src/feature/leds/leds.cpp delete mode 100644 src/feature/leds/leds.h delete mode 100644 src/feature/leds/neopixel.cpp delete mode 100644 src/feature/leds/neopixel.h delete mode 100644 src/feature/leds/pca9533.cpp delete mode 100644 src/feature/leds/pca9533.h delete mode 100644 src/feature/leds/pca9632.cpp delete mode 100644 src/feature/leds/pca9632.h delete mode 100644 src/feature/leds/printer_event_leds.cpp delete mode 100644 src/feature/leds/printer_event_leds.h delete mode 100644 src/feature/leds/tempstat.cpp delete mode 100644 src/feature/leds/tempstat.h delete mode 100644 src/feature/max7219.cpp delete mode 100644 src/feature/max7219.h delete mode 100644 src/feature/meatpack.cpp delete mode 100644 src/feature/meatpack.h delete mode 100644 src/feature/mixing.cpp delete mode 100644 src/feature/mixing.h delete mode 100644 src/feature/mmu/mmu.cpp delete mode 100644 src/feature/mmu/mmu.h delete mode 100644 src/feature/mmu/mmu2-serial-protocol.md delete mode 100644 src/feature/mmu/mmu2.cpp delete mode 100644 src/feature/mmu/mmu2.h delete mode 100644 src/feature/password/password.cpp delete mode 100644 src/feature/password/password.h delete mode 100644 src/feature/pause.cpp delete mode 100644 src/feature/pause.h delete mode 100644 src/feature/power.cpp delete mode 100644 src/feature/power.h delete mode 100644 src/feature/power_monitor.cpp delete mode 100644 src/feature/power_monitor.h delete mode 100644 src/feature/powerloss.cpp delete mode 100644 src/feature/powerloss.h delete mode 100644 src/feature/probe_temp_comp.cpp delete mode 100644 src/feature/probe_temp_comp.h delete mode 100644 src/feature/repeat.cpp delete mode 100644 src/feature/repeat.h delete mode 100644 src/feature/runout.cpp delete mode 100644 src/feature/runout.h delete mode 100644 src/feature/solenoid.cpp delete mode 100644 src/feature/solenoid.h delete mode 100644 src/feature/spindle_laser.cpp delete mode 100644 src/feature/spindle_laser.h delete mode 100644 src/feature/spindle_laser_types.h delete mode 100644 src/feature/stepper_driver_safety.cpp delete mode 100644 src/feature/stepper_driver_safety.h delete mode 100644 src/feature/tmc_util.cpp delete mode 100644 src/feature/tmc_util.h delete mode 100644 src/feature/tramming.cpp delete mode 100644 src/feature/tramming.h delete mode 100644 src/feature/twibus.cpp delete mode 100644 src/feature/twibus.h delete mode 100644 src/feature/x_twist.cpp delete mode 100644 src/feature/x_twist.h delete mode 100644 src/feature/z_stepper_align.cpp delete mode 100644 src/feature/z_stepper_align.h delete mode 100644 src/gcode/bedlevel/G26.cpp delete mode 100644 src/gcode/bedlevel/G35.cpp delete mode 100644 src/gcode/bedlevel/G42.cpp delete mode 100644 src/gcode/bedlevel/M420.cpp delete mode 100644 src/gcode/bedlevel/abl/G29.cpp delete mode 100644 src/gcode/bedlevel/abl/M421.cpp delete mode 100644 src/gcode/bedlevel/mbl/G29.cpp delete mode 100644 src/gcode/bedlevel/mbl/M421.cpp delete mode 100644 src/gcode/bedlevel/ubl/G29.cpp delete mode 100644 src/gcode/bedlevel/ubl/M421.cpp delete mode 100644 src/gcode/calibrate/G28.cpp delete mode 100644 src/gcode/calibrate/G33.cpp delete mode 100644 src/gcode/calibrate/G34.cpp delete mode 100644 src/gcode/calibrate/G34_M422.cpp delete mode 100644 src/gcode/calibrate/G425.cpp delete mode 100644 src/gcode/calibrate/G76_M871.cpp delete mode 100644 src/gcode/calibrate/M100.cpp delete mode 100644 src/gcode/calibrate/M12.cpp delete mode 100644 src/gcode/calibrate/M425.cpp delete mode 100644 src/gcode/calibrate/M48.cpp delete mode 100644 src/gcode/calibrate/M665.cpp delete mode 100644 src/gcode/calibrate/M666.cpp delete mode 100644 src/gcode/calibrate/M852.cpp delete mode 100644 src/gcode/config/M200-M205.cpp delete mode 100644 src/gcode/config/M217.cpp delete mode 100644 src/gcode/config/M218.cpp delete mode 100644 src/gcode/config/M220.cpp delete mode 100644 src/gcode/config/M221.cpp delete mode 100644 src/gcode/config/M281.cpp delete mode 100644 src/gcode/config/M301.cpp delete mode 100644 src/gcode/config/M302.cpp delete mode 100644 src/gcode/config/M304.cpp delete mode 100644 src/gcode/config/M305.cpp delete mode 100644 src/gcode/config/M309.cpp delete mode 100644 src/gcode/config/M43.cpp delete mode 100644 src/gcode/config/M540.cpp delete mode 100644 src/gcode/config/M575.cpp delete mode 100644 src/gcode/config/M672.cpp delete mode 100644 src/gcode/config/M92.cpp delete mode 100644 src/gcode/control/M10-M11.cpp delete mode 100644 src/gcode/control/M108_M112_M410.cpp delete mode 100644 src/gcode/control/M111.cpp delete mode 100644 src/gcode/control/M120_M121.cpp delete mode 100644 src/gcode/control/M17_M18_M84.cpp delete mode 100644 src/gcode/control/M211.cpp delete mode 100644 src/gcode/control/M226.cpp delete mode 100644 src/gcode/control/M280.cpp delete mode 100644 src/gcode/control/M282.cpp delete mode 100644 src/gcode/control/M3-M5.cpp delete mode 100644 src/gcode/control/M350_M351.cpp delete mode 100644 src/gcode/control/M380_M381.cpp delete mode 100644 src/gcode/control/M400.cpp delete mode 100644 src/gcode/control/M42.cpp delete mode 100644 src/gcode/control/M605.cpp delete mode 100644 src/gcode/control/M7-M9.cpp delete mode 100644 src/gcode/control/M80_M81.cpp delete mode 100644 src/gcode/control/M85.cpp delete mode 100644 src/gcode/control/M993_M994.cpp delete mode 100644 src/gcode/control/M997.cpp delete mode 100644 src/gcode/control/M999.cpp delete mode 100644 src/gcode/control/T.cpp delete mode 100644 src/gcode/eeprom/M500-M504.cpp delete mode 100644 src/gcode/feature/L6470/M122.cpp delete mode 100644 src/gcode/feature/L6470/M906.cpp delete mode 100644 src/gcode/feature/L6470/M916-M918.cpp delete mode 100644 src/gcode/feature/adc/M3426.cpp delete mode 100644 src/gcode/feature/advance/M900.cpp delete mode 100644 src/gcode/feature/baricuda/M126-M129.cpp delete mode 100644 src/gcode/feature/camera/M240.cpp delete mode 100644 src/gcode/feature/cancel/M486.cpp delete mode 100644 src/gcode/feature/caselight/M355.cpp delete mode 100644 src/gcode/feature/clean/G12.cpp delete mode 100644 src/gcode/feature/controllerfan/M710.cpp delete mode 100644 src/gcode/feature/digipot/M907-M910.cpp delete mode 100644 src/gcode/feature/filwidth/M404-M407.cpp delete mode 100644 src/gcode/feature/fwretract/G10_G11.cpp delete mode 100644 src/gcode/feature/fwretract/M207-M209.cpp delete mode 100644 src/gcode/feature/i2c/M260_M261.cpp delete mode 100644 src/gcode/feature/leds/M150.cpp delete mode 100644 src/gcode/feature/leds/M7219.cpp delete mode 100644 src/gcode/feature/macro/M810-M819.cpp delete mode 100644 src/gcode/feature/mixing/M163-M165.cpp delete mode 100644 src/gcode/feature/mixing/M166.cpp delete mode 100644 src/gcode/feature/network/M552-M554.cpp delete mode 100644 src/gcode/feature/password/M510-M512.cpp delete mode 100644 src/gcode/feature/pause/G27.cpp delete mode 100644 src/gcode/feature/pause/G60.cpp delete mode 100644 src/gcode/feature/pause/G61.cpp delete mode 100644 src/gcode/feature/pause/M125.cpp delete mode 100644 src/gcode/feature/pause/M600.cpp delete mode 100644 src/gcode/feature/pause/M603.cpp delete mode 100644 src/gcode/feature/pause/M701_M702.cpp delete mode 100644 src/gcode/feature/power_monitor/M430.cpp delete mode 100644 src/gcode/feature/powerloss/M1000.cpp delete mode 100644 src/gcode/feature/powerloss/M413.cpp delete mode 100644 src/gcode/feature/prusa_MMU2/M403.cpp delete mode 100644 src/gcode/feature/runout/M412.cpp delete mode 100644 src/gcode/feature/trinamic/M122.cpp delete mode 100644 src/gcode/feature/trinamic/M569.cpp delete mode 100644 src/gcode/feature/trinamic/M906.cpp delete mode 100644 src/gcode/feature/trinamic/M911-M914.cpp delete mode 100644 src/gcode/feature/trinamic/M919.cpp delete mode 100644 src/gcode/gcode.cpp delete mode 100644 src/gcode/gcode.h delete mode 100644 src/gcode/gcode_d.cpp delete mode 100644 src/gcode/geometry/G17-G19.cpp delete mode 100644 src/gcode/geometry/G53-G59.cpp delete mode 100644 src/gcode/geometry/G92.cpp delete mode 100644 src/gcode/geometry/M206_M428.cpp delete mode 100644 src/gcode/host/M110.cpp delete mode 100644 src/gcode/host/M113.cpp delete mode 100644 src/gcode/host/M114.cpp delete mode 100644 src/gcode/host/M115.cpp delete mode 100644 src/gcode/host/M118.cpp delete mode 100644 src/gcode/host/M119.cpp delete mode 100644 src/gcode/host/M154.cpp delete mode 100644 src/gcode/host/M16.cpp delete mode 100644 src/gcode/host/M360.cpp delete mode 100644 src/gcode/host/M876.cpp delete mode 100644 src/gcode/lcd/M0_M1.cpp delete mode 100644 src/gcode/lcd/M117.cpp delete mode 100644 src/gcode/lcd/M145.cpp delete mode 100644 src/gcode/lcd/M250.cpp delete mode 100644 src/gcode/lcd/M255.cpp delete mode 100644 src/gcode/lcd/M256.cpp delete mode 100644 src/gcode/lcd/M300.cpp delete mode 100644 src/gcode/lcd/M414.cpp delete mode 100644 src/gcode/lcd/M73.cpp delete mode 100644 src/gcode/lcd/M995.cpp delete mode 100644 src/gcode/motion/G0_G1.cpp delete mode 100644 src/gcode/motion/G2_G3.cpp delete mode 100644 src/gcode/motion/G4.cpp delete mode 100644 src/gcode/motion/G5.cpp delete mode 100644 src/gcode/motion/G6.cpp delete mode 100644 src/gcode/motion/G80.cpp delete mode 100644 src/gcode/motion/M290.cpp delete mode 100644 src/gcode/parser.cpp delete mode 100644 src/gcode/parser.h delete mode 100644 src/gcode/probe/G30.cpp delete mode 100644 src/gcode/probe/G31_G32.cpp delete mode 100644 src/gcode/probe/G38.cpp delete mode 100644 src/gcode/probe/M401_M402.cpp delete mode 100644 src/gcode/probe/M423.cpp delete mode 100644 src/gcode/probe/M851.cpp delete mode 100644 src/gcode/probe/M951.cpp delete mode 100644 src/gcode/queue.cpp delete mode 100644 src/gcode/queue.h delete mode 100644 src/gcode/scara/M360-M364.cpp delete mode 100644 src/gcode/sd/M1001.cpp delete mode 100644 src/gcode/sd/M20.cpp delete mode 100644 src/gcode/sd/M21_M22.cpp delete mode 100644 src/gcode/sd/M23.cpp delete mode 100644 src/gcode/sd/M24_M25.cpp delete mode 100644 src/gcode/sd/M26.cpp delete mode 100644 src/gcode/sd/M27.cpp delete mode 100644 src/gcode/sd/M28_M29.cpp delete mode 100644 src/gcode/sd/M30.cpp delete mode 100644 src/gcode/sd/M32.cpp delete mode 100644 src/gcode/sd/M33.cpp delete mode 100644 src/gcode/sd/M34.cpp delete mode 100644 src/gcode/sd/M524.cpp delete mode 100644 src/gcode/sd/M808.cpp delete mode 100644 src/gcode/sd/M928.cpp delete mode 100644 src/gcode/stats/M31.cpp delete mode 100644 src/gcode/stats/M75-M78.cpp delete mode 100644 src/gcode/temp/M104_M109.cpp delete mode 100644 src/gcode/temp/M105.cpp delete mode 100644 src/gcode/temp/M106_M107.cpp delete mode 100644 src/gcode/temp/M123.cpp delete mode 100644 src/gcode/temp/M140_M190.cpp delete mode 100644 src/gcode/temp/M141_M191.cpp delete mode 100644 src/gcode/temp/M143_M193.cpp delete mode 100644 src/gcode/temp/M155.cpp delete mode 100644 src/gcode/temp/M192.cpp delete mode 100644 src/gcode/temp/M303.cpp delete mode 100644 src/gcode/temp/M306.cpp delete mode 100644 src/gcode/units/G20_G21.cpp delete mode 100644 src/gcode/units/M149.cpp delete mode 100644 src/gcode/units/M82_M83.cpp delete mode 100644 src/inc/Conditionals_LCD.h delete mode 100644 src/inc/Conditionals_adv.h delete mode 100644 src/inc/Conditionals_post.h delete mode 100644 src/inc/MarlinConfig.h delete mode 100644 src/inc/MarlinConfigPre.h delete mode 100644 src/inc/SanityCheck.h delete mode 100644 src/inc/Version.h delete mode 100644 src/inc/Warnings.cpp delete mode 100644 src/lcd/HD44780/lcdprint_hd44780.cpp delete mode 100644 src/lcd/HD44780/marlinui_HD44780.cpp delete mode 100644 src/lcd/HD44780/marlinui_HD44780.h delete mode 100644 src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp delete mode 100644 src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp delete mode 100644 src/lcd/TFTGLCD/marlinui_TFTGLCD.h delete mode 100644 src/lcd/buttons.h delete mode 100644 src/lcd/dogm/HAL_LCD_class_defines.h delete mode 100644 src/lcd/dogm/HAL_LCD_com_defines.h delete mode 100644 src/lcd/dogm/dogm_Bootscreen.h delete mode 100644 src/lcd/dogm/dogm_Statusscreen.h delete mode 100644 src/lcd/dogm/fontdata/fontdata_6x9_marlin.h delete mode 100644 src/lcd/dogm/fontdata/fontdata_ISO10646_1.h delete mode 100644 src/lcd/dogm/fontdata/langdata.h delete mode 100644 src/lcd/dogm/fontdata/langdata_an.h delete mode 100644 src/lcd/dogm/fontdata/langdata_bg.h delete mode 100644 src/lcd/dogm/fontdata/langdata_ca.h delete mode 100644 src/lcd/dogm/fontdata/langdata_cz.h delete mode 100644 src/lcd/dogm/fontdata/langdata_da.h delete mode 100644 src/lcd/dogm/fontdata/langdata_de.h delete mode 100644 src/lcd/dogm/fontdata/langdata_el.h delete mode 100644 src/lcd/dogm/fontdata/langdata_el_CY.h delete mode 100644 src/lcd/dogm/fontdata/langdata_en.h delete mode 100644 src/lcd/dogm/fontdata/langdata_es.h delete mode 100644 src/lcd/dogm/fontdata/langdata_eu.h delete mode 100644 src/lcd/dogm/fontdata/langdata_fi.h delete mode 100644 src/lcd/dogm/fontdata/langdata_fr.h delete mode 100644 src/lcd/dogm/fontdata/langdata_gl.h delete mode 100644 src/lcd/dogm/fontdata/langdata_hr.h delete mode 100644 src/lcd/dogm/fontdata/langdata_hu.h delete mode 100644 src/lcd/dogm/fontdata/langdata_it.h delete mode 100644 src/lcd/dogm/fontdata/langdata_jp_kana.h delete mode 100644 src/lcd/dogm/fontdata/langdata_ko_KR.h delete mode 100644 src/lcd/dogm/fontdata/langdata_nl.h delete mode 100644 src/lcd/dogm/fontdata/langdata_pl.h delete mode 100644 src/lcd/dogm/fontdata/langdata_pt.h delete mode 100644 src/lcd/dogm/fontdata/langdata_pt_br.h delete mode 100644 src/lcd/dogm/fontdata/langdata_ro.h delete mode 100644 src/lcd/dogm/fontdata/langdata_ru.h delete mode 100644 src/lcd/dogm/fontdata/langdata_sk.h delete mode 100644 src/lcd/dogm/fontdata/langdata_test.h delete mode 100644 src/lcd/dogm/fontdata/langdata_tr.h delete mode 100644 src/lcd/dogm/fontdata/langdata_uk.h delete mode 100644 src/lcd/dogm/fontdata/langdata_vi.h delete mode 100644 src/lcd/dogm/fontdata/langdata_zh_CN.h delete mode 100644 src/lcd/dogm/fontdata/langdata_zh_TW.h delete mode 100644 src/lcd/dogm/lcdprint_u8g.cpp delete mode 100644 src/lcd/dogm/marlinui_DOGM.cpp delete mode 100644 src/lcd/dogm/marlinui_DOGM.h delete mode 100644 src/lcd/dogm/status/ammeter.h delete mode 100644 src/lcd/dogm/status/bed.h delete mode 100644 src/lcd/dogm/status/chamber.h delete mode 100644 src/lcd/dogm/status/combined.h delete mode 100644 src/lcd/dogm/status/cooler.h delete mode 100644 src/lcd/dogm/status/cutter.h delete mode 100644 src/lcd/dogm/status/fan.h delete mode 100644 src/lcd/dogm/status/hotend.h delete mode 100644 src/lcd/dogm/status_screen_DOGM.cpp delete mode 100644 src/lcd/dogm/status_screen_lite_ST7920.cpp delete mode 100644 src/lcd/dogm/status_screen_lite_ST7920.h delete mode 100644 src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp delete mode 100644 src/lcd/dogm/u8g_dev_ssd1309_12864.cpp delete mode 100644 src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp delete mode 100644 src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp delete mode 100644 src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp delete mode 100644 src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp delete mode 100644 src/lcd/dogm/u8g_fontutf8.cpp delete mode 100644 src/lcd/dogm/u8g_fontutf8.h delete mode 100644 src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp delete mode 100644 src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h delete mode 100644 src/lcd/e3v2/README.md delete mode 100644 src/lcd/e3v2/common/dwin_api.cpp delete mode 100644 src/lcd/e3v2/common/dwin_api.h delete mode 100644 src/lcd/e3v2/common/dwin_color.h delete mode 100644 src/lcd/e3v2/common/dwin_font.h delete mode 100644 src/lcd/e3v2/common/dwin_set.h delete mode 100644 src/lcd/e3v2/common/encoder.cpp delete mode 100644 src/lcd/e3v2/common/encoder.h delete mode 100644 src/lcd/e3v2/creality/dwin.cpp delete mode 100644 src/lcd/e3v2/creality/dwin.h delete mode 100644 src/lcd/e3v2/creality/dwin_lcd.cpp delete mode 100644 src/lcd/e3v2/creality/dwin_lcd.h delete mode 100644 src/lcd/e3v2/jyersui/README.md delete mode 100644 src/lcd/e3v2/jyersui/dwin.cpp delete mode 100644 src/lcd/e3v2/jyersui/dwin.h delete mode 100644 src/lcd/e3v2/jyersui/dwin_lcd.cpp delete mode 100644 src/lcd/e3v2/jyersui/dwin_lcd.h delete mode 100644 src/lcd/e3v2/marlinui/dwin_lcd.cpp delete mode 100644 src/lcd/e3v2/marlinui/dwin_lcd.h delete mode 100644 src/lcd/e3v2/marlinui/dwin_string.cpp delete mode 100644 src/lcd/e3v2/marlinui/dwin_string.h delete mode 100644 src/lcd/e3v2/marlinui/lcdprint_dwin.cpp delete mode 100644 src/lcd/e3v2/marlinui/lcdprint_dwin.h delete mode 100644 src/lcd/e3v2/marlinui/marlinui_dwin.h delete mode 100644 src/lcd/e3v2/marlinui/ui_common.cpp delete mode 100644 src/lcd/e3v2/marlinui/ui_status_480x272.cpp delete mode 100644 src/lcd/e3v2/proui/base64.hpp delete mode 100644 src/lcd/e3v2/proui/bedlevel_tools.cpp delete mode 100644 src/lcd/e3v2/proui/bedlevel_tools.h delete mode 100644 src/lcd/e3v2/proui/dwin.cpp delete mode 100644 src/lcd/e3v2/proui/dwin.h delete mode 100644 src/lcd/e3v2/proui/dwin_defines.h delete mode 100644 src/lcd/e3v2/proui/dwin_lcd.cpp delete mode 100644 src/lcd/e3v2/proui/dwin_lcd.h delete mode 100644 src/lcd/e3v2/proui/dwin_popup.cpp delete mode 100644 src/lcd/e3v2/proui/dwin_popup.h delete mode 100644 src/lcd/e3v2/proui/dwinui.cpp delete mode 100644 src/lcd/e3v2/proui/dwinui.h delete mode 100644 src/lcd/e3v2/proui/endstop_diag.cpp delete mode 100644 src/lcd/e3v2/proui/endstop_diag.h delete mode 100644 src/lcd/e3v2/proui/gcode_preview.cpp delete mode 100644 src/lcd/e3v2/proui/gcode_preview.h delete mode 100644 src/lcd/e3v2/proui/lockscreen.cpp delete mode 100644 src/lcd/e3v2/proui/lockscreen.h delete mode 100644 src/lcd/e3v2/proui/menus.cpp delete mode 100644 src/lcd/e3v2/proui/menus.h delete mode 100644 src/lcd/e3v2/proui/meshviewer.cpp delete mode 100644 src/lcd/e3v2/proui/meshviewer.h delete mode 100644 src/lcd/e3v2/proui/plot.cpp delete mode 100644 src/lcd/e3v2/proui/plot.h delete mode 100644 src/lcd/e3v2/proui/printstats.cpp delete mode 100644 src/lcd/e3v2/proui/printstats.h delete mode 100644 src/lcd/extui/anycubic_chiron/FileNavigator.cpp delete mode 100644 src/lcd/extui/anycubic_chiron/FileNavigator.h delete mode 100644 src/lcd/extui/anycubic_chiron/Tunes.cpp delete mode 100644 src/lcd/extui/anycubic_chiron/Tunes.h delete mode 100644 src/lcd/extui/anycubic_chiron/chiron_extui.cpp delete mode 100644 src/lcd/extui/anycubic_chiron/chiron_tft.cpp delete mode 100644 src/lcd/extui/anycubic_chiron/chiron_tft.h delete mode 100644 src/lcd/extui/anycubic_chiron/chiron_tft_defs.h delete mode 100644 src/lcd/extui/anycubic_i3mega/anycubic_extui.cpp delete mode 100644 src/lcd/extui/anycubic_i3mega/anycubic_i3mega_lcd.cpp delete mode 100644 src/lcd/extui/anycubic_i3mega/anycubic_i3mega_lcd.h delete mode 100644 src/lcd/extui/dgus/DGUSDisplay.cpp delete mode 100644 src/lcd/extui/dgus/DGUSDisplay.h delete mode 100644 src/lcd/extui/dgus/DGUSDisplayDef.h delete mode 100644 src/lcd/extui/dgus/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus/DGUSScreenHandlerBase.h delete mode 100644 src/lcd/extui/dgus/DGUSVPVariable.h delete mode 100644 src/lcd/extui/dgus/dgus_extui.cpp delete mode 100644 src/lcd/extui/dgus/fysetc/DGUSDisplayDef.cpp delete mode 100644 src/lcd/extui/dgus/fysetc/DGUSDisplayDef.h delete mode 100644 src/lcd/extui/dgus/fysetc/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus/fysetc/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.cpp delete mode 100644 src/lcd/extui/dgus/hiprecy/DGUSDisplayDef.h delete mode 100644 src/lcd/extui/dgus/hiprecy/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus/hiprecy/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp delete mode 100644 src/lcd/extui/dgus/mks/DGUSDisplayDef.h delete mode 100644 src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus/mks/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus/origin/DGUSDisplayDef.cpp delete mode 100644 src/lcd/extui/dgus/origin/DGUSDisplayDef.h delete mode 100644 src/lcd/extui/dgus/origin/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus/origin/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSDisplay.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSDisplay.h delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSRxHandler.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSRxHandler.h delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSScreenHandler.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSScreenHandler.h delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSSetupHandler.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSSetupHandler.h delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSTxHandler.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/DGUSTxHandler.h delete mode 100644 src/lcd/extui/dgus_reloaded/config/DGUS_Addr.h delete mode 100644 src/lcd/extui/dgus_reloaded/config/DGUS_Constants.h delete mode 100644 src/lcd/extui/dgus_reloaded/config/DGUS_Control.h delete mode 100644 src/lcd/extui/dgus_reloaded/config/DGUS_Data.h delete mode 100644 src/lcd/extui/dgus_reloaded/config/DGUS_Screen.h delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenAddrList.h delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenSetup.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_ScreenSetup.h delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_VP.h delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_VPList.cpp delete mode 100644 src/lcd/extui/dgus_reloaded/definition/DGUS_VPList.h delete mode 100644 src/lcd/extui/dgus_reloaded/dgus_reloaded_extui.cpp delete mode 100644 src/lcd/extui/example/example.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/flash_storage.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/confirm_home_e.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/confirm_home_e.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/confirm_home_xyz.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/confirm_home_xyz.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/main_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/main_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/printing_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/printing_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/screens.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/status_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/status_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/tune_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/tune_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/ui_landscape.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/bioprinter/ui_portrait.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/cocoa_press_ui.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/leveling_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/load_chocolate.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/load_chocolate.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/main_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/move_e_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/move_e_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/move_xyz_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/move_xyz_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/preheat_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/screens.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/compat.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/config.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_extui.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/LICENSE.txt delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/README.md delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/boards.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/commands.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/constants.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/display_list.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/ftdi_basic.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft800.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/registers_ft810.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/resolutions.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/basic/spi.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/compat.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/adjuster_widget.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/adjuster_widget.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/arrows.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/arrows.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/bitmap_info.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/circular_progress.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/circular_progress.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/dl_cache.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/event_loop.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/ftdi_extended.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/grid_layout.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/polygon.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/rgb_t.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/screen_types.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_list.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/sound_player.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_ellipsis.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/tiny_timer.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/README.txt delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/cyrillic_char_set.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/cyrillic_char_set.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/cyrillic_char_set_bitmap_31.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/cyrillic_char_set_bitmap_31.png delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/cyrillic_char_set_bitmap_31.svg delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.pbm delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/romfont_31.png delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.png delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_bitmaps/western_char_set_bitmap_31.svg delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/font_size_t.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/standard_char_set.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/unicode.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/unicode/western_char_set_bitmap_31.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/ftdi_eve_lib.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/file2cpp.py delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/font2cpp.py delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/img2cpp.py delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/scripts/svg2cpp.py delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/alert_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/alert_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/backlash_compensation_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/backlash_compensation_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/base_numeric_adjustment_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/base_numeric_adjustment_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/base_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_base.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_base.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/boot_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/case_light_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/case_light_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/change_filament_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_abort_print_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_abort_print_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_auto_calibration_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_auto_calibration_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_erase_flash_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_erase_flash_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_start_print_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_start_print_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/confirm_user_request_alert_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/custom_user_menus.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/custom_user_menus.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/default_acceleration_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/default_acceleration_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/developer_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/developer_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/dialog_box_base_class.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/dialog_box_base_class.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/display_tuning_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/display_tuning_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/endstop_state_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/endstop_state_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/feedrate_percent_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/feedrate_percent_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/filament_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/filament_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/filament_runout_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/files_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/files_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/flow_percent_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/flow_percent_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/interface_sounds_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/interface_sounds_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/jerk_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/jerk_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/junction_deviation_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/junction_deviation_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/kill_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/kill_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/language_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/language_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/leveling_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/leveling_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/linear_advance_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/linear_advance_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/lock_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/lock_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/main_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/main_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/max_acceleration_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/max_acceleration_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/media_player_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/media_player_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/move_axis_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/move_axis_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/nozzle_offsets_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/nozzle_offsets_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/nudge_nozzle_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/nudge_nozzle_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/restore_failsafe_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/restore_failsafe_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/screens.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/spinner_dialog_box.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/spinner_dialog_box.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/statistics_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/statistics_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/status_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stepper_bump_sensitivity_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stepper_bump_sensitivity_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stepper_current_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stepper_current_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/steps_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/steps_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stress_test_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/stress_test_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/string_format.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/string_format.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/temperature_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/temperature_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/touch_calibration_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/touch_calibration_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/touch_registers_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/touch_registers_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/tune_menu.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/tune_menu.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/widget_demo_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/widget_demo_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/z_offset_screen.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/generic/z_offset_screen.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/language/language.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/language/language.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/pin_mappings.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/screen_data.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/screens.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/screens.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/bitmaps.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/bootscreen_logo_portrait.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/colors.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/marlin_bootscreen_landscape.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/marlin_bootscreen_portrait.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.cpp delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/sounds.h delete mode 100644 src/lcd/extui/ftdi_eve_touch_ui/theme/theme.h delete mode 100644 src/lcd/extui/malyan/malyan.cpp delete mode 100644 src/lcd/extui/malyan/malyan.h delete mode 100644 src/lcd/extui/malyan/malyan_extui.cpp delete mode 100644 src/lcd/extui/mks_ui/SPIFlashStorage.cpp delete mode 100644 src/lcd/extui/mks_ui/SPIFlashStorage.h delete mode 100644 src/lcd/extui/mks_ui/SPI_TFT.cpp delete mode 100644 src/lcd/extui/mks_ui/SPI_TFT.h delete mode 100644 src/lcd/extui/mks_ui/draw_about.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_about.h delete mode 100644 src/lcd/extui/mks_ui/draw_acceleration_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_acceleration_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_advance_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_advance_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_auto_level_offset_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_auto_level_offset_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_baby_stepping.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_baby_stepping.h delete mode 100644 src/lcd/extui/mks_ui/draw_change_speed.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_change_speed.h delete mode 100644 src/lcd/extui/mks_ui/draw_cloud_bind.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_cloud_bind.h delete mode 100644 src/lcd/extui/mks_ui/draw_dialog.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_dialog.h delete mode 100644 src/lcd/extui/mks_ui/draw_eeprom_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_eeprom_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_encoder_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_encoder_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_error_message.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_error_message.h delete mode 100644 src/lcd/extui/mks_ui/draw_extrusion.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_extrusion.h delete mode 100644 src/lcd/extui/mks_ui/draw_fan.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_fan.h delete mode 100644 src/lcd/extui/mks_ui/draw_filament_change.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_filament_change.h delete mode 100644 src/lcd/extui/mks_ui/draw_filament_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_filament_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_gcode.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_gcode.h delete mode 100644 src/lcd/extui/mks_ui/draw_home.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_home.h delete mode 100644 src/lcd/extui/mks_ui/draw_homing_sensitivity_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_homing_sensitivity_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_jerk_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_jerk_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_keyboard.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_keyboard.h delete mode 100644 src/lcd/extui/mks_ui/draw_language.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_language.h delete mode 100644 src/lcd/extui/mks_ui/draw_level_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_level_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_machine_para.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_machine_para.h delete mode 100644 src/lcd/extui/mks_ui/draw_machine_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_machine_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_manuaLevel.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_manuaLevel.h delete mode 100644 src/lcd/extui/mks_ui/draw_max_feedrate_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_max_feedrate_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_media_select.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_media_select.h delete mode 100644 src/lcd/extui/mks_ui/draw_more.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_more.h delete mode 100644 src/lcd/extui/mks_ui/draw_motor_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_motor_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_move_motor.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_move_motor.h delete mode 100644 src/lcd/extui/mks_ui/draw_number_key.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_number_key.h delete mode 100644 src/lcd/extui/mks_ui/draw_operation.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_operation.h delete mode 100644 src/lcd/extui/mks_ui/draw_pause_message.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_pause_message.h delete mode 100644 src/lcd/extui/mks_ui/draw_pause_position.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_pause_position.h delete mode 100644 src/lcd/extui/mks_ui/draw_preHeat.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_preHeat.h delete mode 100644 src/lcd/extui/mks_ui/draw_print_file.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_print_file.h delete mode 100644 src/lcd/extui/mks_ui/draw_printing.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_printing.h delete mode 100644 src/lcd/extui/mks_ui/draw_ready_print.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_ready_print.h delete mode 100644 src/lcd/extui/mks_ui/draw_set.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_set.h delete mode 100644 src/lcd/extui/mks_ui/draw_step_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_step_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_tmc_current_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_tmc_current_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_tmc_step_mode_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_tmc_step_mode_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_tool.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_tool.h delete mode 100644 src/lcd/extui/mks_ui/draw_touch_calibration.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_touch_calibration.h delete mode 100644 src/lcd/extui/mks_ui/draw_tramming_pos_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_tramming_pos_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_ui.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_ui.h delete mode 100644 src/lcd/extui/mks_ui/draw_wifi.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_wifi.h delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_list.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_list.h delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_settings.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_settings.h delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_tips.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_wifi_tips.h delete mode 100644 src/lcd/extui/mks_ui/draw_z_offset_wizard.cpp delete mode 100644 src/lcd/extui/mks_ui/draw_z_offset_wizard.h delete mode 100644 src/lcd/extui/mks_ui/gb2312_puhui16.cpp delete mode 100644 src/lcd/extui/mks_ui/irq_overrid.cpp delete mode 100644 src/lcd/extui/mks_ui/mks_hardware.cpp delete mode 100644 src/lcd/extui/mks_ui/mks_hardware.h delete mode 100644 src/lcd/extui/mks_ui/pic_manager.cpp delete mode 100644 src/lcd/extui/mks_ui/pic_manager.h delete mode 100644 src/lcd/extui/mks_ui/printer_operation.cpp delete mode 100644 src/lcd/extui/mks_ui/printer_operation.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_en.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_fr.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_it.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_ru.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_s_cn.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_sp.h delete mode 100644 src/lcd/extui/mks_ui/tft_Language_t_cn.h delete mode 100644 src/lcd/extui/mks_ui/tft_lvgl_configuration.cpp delete mode 100644 src/lcd/extui/mks_ui/tft_lvgl_configuration.h delete mode 100644 src/lcd/extui/mks_ui/tft_multi_language.cpp delete mode 100644 src/lcd/extui/mks_ui/tft_multi_language.h delete mode 100644 src/lcd/extui/mks_ui/wifiSerial.h delete mode 100644 src/lcd/extui/mks_ui/wifiSerial_STM32.cpp delete mode 100644 src/lcd/extui/mks_ui/wifiSerial_STM32.h delete mode 100644 src/lcd/extui/mks_ui/wifiSerial_STM32F1.cpp delete mode 100644 src/lcd/extui/mks_ui/wifiSerial_STM32F1.h delete mode 100644 src/lcd/extui/mks_ui/wifi_module.cpp delete mode 100644 src/lcd/extui/mks_ui/wifi_module.h delete mode 100644 src/lcd/extui/mks_ui/wifi_upload.cpp delete mode 100644 src/lcd/extui/mks_ui/wifi_upload.h delete mode 100644 src/lcd/extui/nextion/FileNavigator.cpp delete mode 100644 src/lcd/extui/nextion/FileNavigator.h delete mode 100644 src/lcd/extui/nextion/nextion_extui.cpp delete mode 100644 src/lcd/extui/nextion/nextion_tft.cpp delete mode 100644 src/lcd/extui/nextion/nextion_tft.h delete mode 100644 src/lcd/extui/nextion/nextion_tft_defs.h delete mode 100644 src/lcd/extui/ui_api.cpp delete mode 100644 src/lcd/extui/ui_api.h delete mode 100644 src/lcd/fontutils.cpp delete mode 100644 src/lcd/fontutils.h delete mode 100644 src/lcd/language/language_an.h delete mode 100644 src/lcd/language/language_bg.h delete mode 100644 src/lcd/language/language_ca.h delete mode 100644 src/lcd/language/language_cz.h delete mode 100644 src/lcd/language/language_da.h delete mode 100644 src/lcd/language/language_de.h delete mode 100644 src/lcd/language/language_el.h delete mode 100644 src/lcd/language/language_el_CY.h delete mode 100644 src/lcd/language/language_el_gr.h delete mode 100644 src/lcd/language/language_en.h delete mode 100644 src/lcd/language/language_es.h delete mode 100644 src/lcd/language/language_eu.h delete mode 100644 src/lcd/language/language_fi.h delete mode 100644 src/lcd/language/language_fr.h delete mode 100644 src/lcd/language/language_gl.h delete mode 100644 src/lcd/language/language_hr.h delete mode 100644 src/lcd/language/language_hu.h delete mode 100644 src/lcd/language/language_it.h delete mode 100644 src/lcd/language/language_jp_kana.h delete mode 100644 src/lcd/language/language_ko_KR.h delete mode 100644 src/lcd/language/language_nl.h delete mode 100644 src/lcd/language/language_pl.h delete mode 100644 src/lcd/language/language_pt.h delete mode 100644 src/lcd/language/language_pt_br.h delete mode 100644 src/lcd/language/language_ro.h delete mode 100644 src/lcd/language/language_ru.h delete mode 100644 src/lcd/language/language_sk.h delete mode 100644 src/lcd/language/language_sv.h delete mode 100644 src/lcd/language/language_test.h delete mode 100644 src/lcd/language/language_tr.h delete mode 100644 src/lcd/language/language_uk.h delete mode 100644 src/lcd/language/language_vi.h delete mode 100644 src/lcd/language/language_zh_CN.h delete mode 100644 src/lcd/language/language_zh_TW.h delete mode 100644 src/lcd/lcdprint.cpp delete mode 100644 src/lcd/lcdprint.h delete mode 100644 src/lcd/marlinui.cpp delete mode 100644 src/lcd/marlinui.h delete mode 100644 src/lcd/menu/game/brickout.cpp delete mode 100644 src/lcd/menu/game/brickout.h delete mode 100644 src/lcd/menu/game/game.cpp delete mode 100644 src/lcd/menu/game/game.h delete mode 100644 src/lcd/menu/game/invaders.cpp delete mode 100644 src/lcd/menu/game/invaders.h delete mode 100644 src/lcd/menu/game/maze.cpp delete mode 100644 src/lcd/menu/game/maze.h delete mode 100644 src/lcd/menu/game/snake.cpp delete mode 100644 src/lcd/menu/game/snake.h delete mode 100644 src/lcd/menu/game/types.h delete mode 100644 src/lcd/menu/menu.cpp delete mode 100644 src/lcd/menu/menu.h delete mode 100644 src/lcd/menu/menu_addon.h delete mode 100644 src/lcd/menu/menu_advanced.cpp delete mode 100644 src/lcd/menu/menu_backlash.cpp delete mode 100644 src/lcd/menu/menu_bed_corners.cpp delete mode 100644 src/lcd/menu/menu_bed_leveling.cpp delete mode 100644 src/lcd/menu/menu_cancelobject.cpp delete mode 100644 src/lcd/menu/menu_configuration.cpp delete mode 100644 src/lcd/menu/menu_delta_calibrate.cpp delete mode 100644 src/lcd/menu/menu_filament.cpp delete mode 100644 src/lcd/menu/menu_game.cpp delete mode 100644 src/lcd/menu/menu_info.cpp delete mode 100644 src/lcd/menu/menu_item.h delete mode 100644 src/lcd/menu/menu_job_recovery.cpp delete mode 100644 src/lcd/menu/menu_language.cpp delete mode 100644 src/lcd/menu/menu_led.cpp delete mode 100644 src/lcd/menu/menu_main.cpp delete mode 100644 src/lcd/menu/menu_media.cpp delete mode 100644 src/lcd/menu/menu_mixer.cpp delete mode 100644 src/lcd/menu/menu_mmu2.cpp delete mode 100644 src/lcd/menu/menu_mmu2.h delete mode 100644 src/lcd/menu/menu_motion.cpp delete mode 100644 src/lcd/menu/menu_password.cpp delete mode 100644 src/lcd/menu/menu_power_monitor.cpp delete mode 100644 src/lcd/menu/menu_probe_offset.cpp delete mode 100644 src/lcd/menu/menu_spindle_laser.cpp delete mode 100644 src/lcd/menu/menu_temperature.cpp delete mode 100644 src/lcd/menu/menu_tmc.cpp delete mode 100644 src/lcd/menu/menu_touch_screen.cpp delete mode 100644 src/lcd/menu/menu_tramming.cpp delete mode 100644 src/lcd/menu/menu_tune.cpp delete mode 100644 src/lcd/menu/menu_ubl.cpp delete mode 100644 src/lcd/menu/menu_x_twist.cpp delete mode 100644 src/lcd/scaled_tft.h delete mode 100644 src/lcd/tft/bitmaps/back.bmp delete mode 100644 src/lcd/tft/bitmaps/bed.bmp delete mode 100644 src/lcd/tft/bitmaps/bed_heated.bmp delete mode 100644 src/lcd/tft/bitmaps/btn_42x39_rounded.bmp delete mode 100644 src/lcd/tft/bitmaps/btn_64x52_rounded.bmp delete mode 100644 src/lcd/tft/bitmaps/cancel.bmp delete mode 100644 src/lcd/tft/bitmaps/chamber.bmp delete mode 100644 src/lcd/tft/bitmaps/chamber_heated.bmp delete mode 100644 src/lcd/tft/bitmaps/confirm.bmp delete mode 100644 src/lcd/tft/bitmaps/decrease.bmp delete mode 100644 src/lcd/tft/bitmaps/directory.bmp delete mode 100644 src/lcd/tft/bitmaps/down.bmp delete mode 100644 src/lcd/tft/bitmaps/fan0.bmp delete mode 100644 src/lcd/tft/bitmaps/fan1.bmp delete mode 100644 src/lcd/tft/bitmaps/fan_fast0.bmp delete mode 100644 src/lcd/tft/bitmaps/fan_fast1.bmp delete mode 100644 src/lcd/tft/bitmaps/fan_slow0.bmp delete mode 100644 src/lcd/tft/bitmaps/fan_slow1.bmp delete mode 100644 src/lcd/tft/bitmaps/feedrate.bmp delete mode 100644 src/lcd/tft/bitmaps/flowrate.bmp delete mode 100644 src/lcd/tft/bitmaps/home.bmp delete mode 100644 src/lcd/tft/bitmaps/hotend.bmp delete mode 100644 src/lcd/tft/bitmaps/increase.bmp delete mode 100644 src/lcd/tft/bitmaps/left.bmp delete mode 100644 src/lcd/tft/bitmaps/leveling.bmp delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-1500x319.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-195x59.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255-greyscale.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-228x255.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-280x200.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-320x240.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-480x319.png delete mode 100644 src/lcd/tft/bitmaps/marlin-logo/Marlin-480x320.png delete mode 100644 src/lcd/tft/bitmaps/menu.bmp delete mode 100644 src/lcd/tft/bitmaps/pause.bmp delete mode 100644 src/lcd/tft/bitmaps/refresh.bmp delete mode 100644 src/lcd/tft/bitmaps/right.bmp delete mode 100644 src/lcd/tft/bitmaps/sd.bmp delete mode 100644 src/lcd/tft/bitmaps/settings.bmp delete mode 100644 src/lcd/tft/bitmaps/up.bmp delete mode 100644 src/lcd/tft/canvas.cpp delete mode 100644 src/lcd/tft/canvas.h delete mode 100644 src/lcd/tft/fontdata/fontdata_10x20.cpp delete mode 100644 src/lcd/tft/fontdata/fontdata_ISO10646_1.cpp delete mode 100644 src/lcd/tft/fontdata/helvetica_12_bold.cpp delete mode 100644 src/lcd/tft/fontdata/helvetica_14.cpp delete mode 100644 src/lcd/tft/fontdata/helvetica_18.cpp delete mode 100644 src/lcd/tft/fontdata/profont_22.cpp delete mode 100644 src/lcd/tft/images/back_32x32x4.cpp delete mode 100644 src/lcd/tft/images/background_320x30x16.cpp delete mode 100644 src/lcd/tft/images/bootscreen_112x38x1.cpp delete mode 100644 src/lcd/tft/images/bootscreen_195x59x16.cpp delete mode 100644 src/lcd/tft/images/bootscreen_228x255x2.cpp delete mode 100644 src/lcd/tft/images/bootscreen_228x255x4.cpp delete mode 100644 src/lcd/tft/images/bootscreen_320x240x16.cpp delete mode 100644 src/lcd/tft/images/bootscreen_480x320x16.cpp delete mode 100644 src/lcd/tft/images/btn_rounded_42x39x4.cpp delete mode 100644 src/lcd/tft/images/btn_rounded_64x52x4.cpp delete mode 100644 src/lcd/tft/images/cancel_64x64x4.cpp delete mode 100644 src/lcd/tft/images/chamber_64x64x4.cpp delete mode 100644 src/lcd/tft/images/confirm_64x64x4.cpp delete mode 100644 src/lcd/tft/images/decrease_64x64x4.cpp delete mode 100644 src/lcd/tft/images/directory_32x32x4.cpp delete mode 100644 src/lcd/tft/images/down_32x32x4.cpp delete mode 100644 src/lcd/tft/images/fan_64x64x4.cpp delete mode 100644 src/lcd/tft/images/fan_fast_64x64x4.cpp delete mode 100644 src/lcd/tft/images/fan_slow_64x64x4.cpp delete mode 100644 src/lcd/tft/images/feedrate_32x32x4.cpp delete mode 100644 src/lcd/tft/images/flowrate_32x32x4.cpp delete mode 100644 src/lcd/tft/images/heated_bed_64x64x4.cpp delete mode 100644 src/lcd/tft/images/home_64x64x4.cpp delete mode 100644 src/lcd/tft/images/hotend_64x64x4.cpp delete mode 100644 src/lcd/tft/images/increase_64x64x4.cpp delete mode 100644 src/lcd/tft/images/left_32x32x4.cpp delete mode 100644 src/lcd/tft/images/leveling_32x32x4.cpp delete mode 100644 src/lcd/tft/images/menu_64x64x4.cpp delete mode 100644 src/lcd/tft/images/pause_64x64x4.cpp delete mode 100644 src/lcd/tft/images/refresh_32x32x4.cpp delete mode 100644 src/lcd/tft/images/right_32x32x4.cpp delete mode 100644 src/lcd/tft/images/sd_64x64x4.cpp delete mode 100644 src/lcd/tft/images/settings_64x64x4.cpp delete mode 100644 src/lcd/tft/images/slider_8x16x4.cpp delete mode 100644 src/lcd/tft/images/up_32x32x4.cpp delete mode 100644 src/lcd/tft/tft.cpp delete mode 100644 src/lcd/tft/tft.h delete mode 100644 src/lcd/tft/tft_color.h delete mode 100644 src/lcd/tft/tft_image.cpp delete mode 100644 src/lcd/tft/tft_image.h delete mode 100644 src/lcd/tft/tft_queue.cpp delete mode 100644 src/lcd/tft/tft_queue.h delete mode 100644 src/lcd/tft/tft_string.cpp delete mode 100644 src/lcd/tft/tft_string.h delete mode 100644 src/lcd/tft/touch.cpp delete mode 100644 src/lcd/tft/touch.h delete mode 100644 src/lcd/tft/ui_1024x600.cpp delete mode 100644 src/lcd/tft/ui_1024x600.h delete mode 100644 src/lcd/tft/ui_320x240.cpp delete mode 100644 src/lcd/tft/ui_320x240.h delete mode 100644 src/lcd/tft/ui_480x320.cpp delete mode 100644 src/lcd/tft/ui_480x320.h delete mode 100644 src/lcd/tft/ui_common.cpp delete mode 100644 src/lcd/tft/ui_common.h delete mode 100644 src/lcd/tft_io/ili9328.h delete mode 100644 src/lcd/tft_io/ili9341.h delete mode 100644 src/lcd/tft_io/ili9488.h delete mode 100644 src/lcd/tft_io/r65105.h delete mode 100644 src/lcd/tft_io/ssd1963.h delete mode 100644 src/lcd/tft_io/st7735.h delete mode 100644 src/lcd/tft_io/st7789v.h delete mode 100644 src/lcd/tft_io/st7796s.h delete mode 100644 src/lcd/tft_io/tft_ids.h delete mode 100644 src/lcd/tft_io/tft_io.cpp delete mode 100644 src/lcd/tft_io/tft_io.h delete mode 100644 src/lcd/tft_io/touch_calibration.cpp delete mode 100644 src/lcd/tft_io/touch_calibration.h delete mode 100644 src/lcd/thermistornames.h delete mode 100644 src/lcd/touch/touch_buttons.cpp delete mode 100644 src/lcd/touch/touch_buttons.h delete mode 100644 src/libs/BL24CXX.cpp delete mode 100644 src/libs/BL24CXX.h delete mode 100644 src/libs/L64XX/L64XX_Marlin.cpp delete mode 100644 src/libs/L64XX/L64XX_Marlin.h delete mode 100644 src/libs/L64XX/README.md delete mode 100644 src/libs/MAX31865.cpp delete mode 100644 src/libs/MAX31865.h delete mode 100644 src/libs/W25Qxx.cpp delete mode 100644 src/libs/W25Qxx.h delete mode 100644 src/libs/autoreport.h delete mode 100644 src/libs/bresenham.h delete mode 100644 src/libs/buzzer.cpp delete mode 100644 src/libs/buzzer.h delete mode 100644 src/libs/circularqueue.h delete mode 100644 src/libs/crc16.cpp delete mode 100644 src/libs/crc16.h delete mode 100644 src/libs/duration_t.h delete mode 100644 src/libs/heatshrink/LICENSE delete mode 100644 src/libs/heatshrink/heatshrink_common.h delete mode 100644 src/libs/heatshrink/heatshrink_config.h delete mode 100644 src/libs/heatshrink/heatshrink_decoder.cpp delete mode 100644 src/libs/heatshrink/heatshrink_decoder.h delete mode 100644 src/libs/hex_print.cpp delete mode 100644 src/libs/hex_print.h delete mode 100644 src/libs/least_squares_fit.cpp delete mode 100644 src/libs/least_squares_fit.h delete mode 100644 src/libs/nozzle.cpp delete mode 100644 src/libs/nozzle.h delete mode 100644 src/libs/numtostr.cpp delete mode 100644 src/libs/numtostr.h delete mode 100644 src/libs/private_spi.h delete mode 100644 src/libs/softspi.h delete mode 100644 src/libs/stopwatch.cpp delete mode 100644 src/libs/stopwatch.h delete mode 100644 src/libs/vector_3.cpp delete mode 100644 src/libs/vector_3.h delete mode 100644 src/module/delta.cpp delete mode 100644 src/module/delta.h delete mode 100644 src/module/endstops.cpp delete mode 100644 src/module/endstops.h delete mode 100644 src/module/motion.cpp delete mode 100644 src/module/motion.h delete mode 100644 src/module/planner.cpp delete mode 100644 src/module/planner.h delete mode 100644 src/module/planner_bezier.cpp delete mode 100644 src/module/planner_bezier.h delete mode 100644 src/module/polargraph.cpp delete mode 100644 src/module/polargraph.h delete mode 100644 src/module/printcounter.cpp delete mode 100644 src/module/printcounter.h delete mode 100644 src/module/probe.cpp delete mode 100644 src/module/probe.h delete mode 100644 src/module/scara.cpp delete mode 100644 src/module/scara.h delete mode 100644 src/module/servo.cpp delete mode 100644 src/module/servo.h delete mode 100644 src/module/settings.cpp delete mode 100644 src/module/settings.h delete mode 100644 src/module/stepper.cpp delete mode 100644 src/module/stepper.h delete mode 100644 src/module/stepper/L64xx.cpp delete mode 100644 src/module/stepper/L64xx.h delete mode 100644 src/module/stepper/TMC26X.cpp delete mode 100644 src/module/stepper/TMC26X.h delete mode 100644 src/module/stepper/indirection.cpp delete mode 100644 src/module/stepper/indirection.h delete mode 100644 src/module/stepper/speed_lookuptable.h delete mode 100644 src/module/stepper/trinamic.cpp delete mode 100644 src/module/stepper/trinamic.h delete mode 100644 src/module/temperature.cpp delete mode 100644 src/module/temperature.h delete mode 100644 src/module/thermistor/thermistor_1.h delete mode 100644 src/module/thermistor/thermistor_10.h delete mode 100644 src/module/thermistor/thermistor_1010.h delete mode 100644 src/module/thermistor/thermistor_1047.h delete mode 100644 src/module/thermistor/thermistor_11.h delete mode 100644 src/module/thermistor/thermistor_110.h delete mode 100644 src/module/thermistor/thermistor_12.h delete mode 100644 src/module/thermistor/thermistor_13.h delete mode 100644 src/module/thermistor/thermistor_147.h delete mode 100644 src/module/thermistor/thermistor_15.h delete mode 100644 src/module/thermistor/thermistor_17.h delete mode 100644 src/module/thermistor/thermistor_18.h delete mode 100644 src/module/thermistor/thermistor_2.h delete mode 100644 src/module/thermistor/thermistor_20.h delete mode 100644 src/module/thermistor/thermistor_2000.h delete mode 100644 src/module/thermistor/thermistor_201.h delete mode 100644 src/module/thermistor/thermistor_202.h delete mode 100644 src/module/thermistor/thermistor_21.h delete mode 100644 src/module/thermistor/thermistor_22.h delete mode 100644 src/module/thermistor/thermistor_23.h delete mode 100644 src/module/thermistor/thermistor_3.h delete mode 100644 src/module/thermistor/thermistor_30.h delete mode 100644 src/module/thermistor/thermistor_331.h delete mode 100644 src/module/thermistor/thermistor_332.h delete mode 100644 src/module/thermistor/thermistor_4.h delete mode 100644 src/module/thermistor/thermistor_5.h delete mode 100644 src/module/thermistor/thermistor_501.h delete mode 100644 src/module/thermistor/thermistor_502.h delete mode 100644 src/module/thermistor/thermistor_503.h delete mode 100644 src/module/thermistor/thermistor_504.h delete mode 100644 src/module/thermistor/thermistor_505.h delete mode 100644 src/module/thermistor/thermistor_51.h delete mode 100644 src/module/thermistor/thermistor_512.h delete mode 100644 src/module/thermistor/thermistor_52.h delete mode 100644 src/module/thermistor/thermistor_55.h delete mode 100644 src/module/thermistor/thermistor_6.h delete mode 100644 src/module/thermistor/thermistor_60.h delete mode 100644 src/module/thermistor/thermistor_61.h delete mode 100644 src/module/thermistor/thermistor_66.h delete mode 100644 src/module/thermistor/thermistor_666.h delete mode 100644 src/module/thermistor/thermistor_67.h delete mode 100644 src/module/thermistor/thermistor_68.h delete mode 100644 src/module/thermistor/thermistor_7.h delete mode 100644 src/module/thermistor/thermistor_70.h delete mode 100644 src/module/thermistor/thermistor_71.h delete mode 100644 src/module/thermistor/thermistor_75.h delete mode 100644 src/module/thermistor/thermistor_8.h delete mode 100644 src/module/thermistor/thermistor_9.h delete mode 100644 src/module/thermistor/thermistor_99.h delete mode 100644 src/module/thermistor/thermistor_998.h delete mode 100644 src/module/thermistor/thermistor_999.h delete mode 100644 src/module/thermistor/thermistors.h delete mode 100644 src/module/tool_change.cpp delete mode 100644 src/module/tool_change.h delete mode 100644 src/pins/esp32/env_validate.h delete mode 100644 src/pins/esp32/pins_E4D.h delete mode 100644 src/pins/esp32/pins_ENWI_ESPNP.h delete mode 100644 src/pins/esp32/pins_ESP32.h delete mode 100644 src/pins/esp32/pins_ESPA_common.h delete mode 100644 src/pins/esp32/pins_FYSETC_E4.h delete mode 100644 src/pins/esp32/pins_MKS_TINYBEE.h delete mode 100644 src/pins/esp32/pins_MRR_ESPA.h delete mode 100644 src/pins/esp32/pins_MRR_ESPE.h delete mode 100644 src/pins/esp32/pins_PANDA_M4.h delete mode 100644 src/pins/esp32/pins_PANDA_ZHU.h delete mode 100644 src/pins/esp32/pins_PANDA_common.h delete mode 100644 src/pins/esp32/pins_RESP32_CUSTOM.h delete mode 100644 src/pins/linux/pins_RAMPS_LINUX.h delete mode 100644 src/pins/lpc1768/env_validate.h delete mode 100644 src/pins/lpc1768/pins_AZSMZ_MINI.h delete mode 100644 src/pins/lpc1768/pins_BIQU_B300_V1.0.h delete mode 100644 src/pins/lpc1768/pins_BIQU_BQ111_A4.h delete mode 100644 src/pins/lpc1768/pins_BTT_SKR_V1_1.h delete mode 100644 src/pins/lpc1768/pins_BTT_SKR_V1_3.h delete mode 100644 src/pins/lpc1768/pins_BTT_SKR_V1_4.h delete mode 100644 src/pins/lpc1768/pins_BTT_SKR_common.h delete mode 100644 src/pins/lpc1768/pins_EMOTRONIC.h delete mode 100644 src/pins/lpc1768/pins_GMARSH_X6_REV1.h delete mode 100644 src/pins/lpc1768/pins_MKS_SBASE.h delete mode 100644 src/pins/lpc1768/pins_MKS_SGEN_L.h delete mode 100644 src/pins/lpc1768/pins_RAMPS_RE_ARM.h delete mode 100644 src/pins/lpc1768/pins_SELENA_COMPACT.h delete mode 100644 src/pins/lpc1769/env_validate.h delete mode 100644 src/pins/lpc1769/pins_AZTEEG_X5_GT.h delete mode 100644 src/pins/lpc1769/pins_AZTEEG_X5_MINI.h delete mode 100644 src/pins/lpc1769/pins_AZTEEG_X5_MINI_WIFI.h delete mode 100644 src/pins/lpc1769/pins_BTT_SKR_E3_TURBO.h delete mode 100644 src/pins/lpc1769/pins_BTT_SKR_V1_4_TURBO.h delete mode 100644 src/pins/lpc1769/pins_COHESION3D_MINI.h delete mode 100644 src/pins/lpc1769/pins_COHESION3D_REMIX.h delete mode 100644 src/pins/lpc1769/pins_FLY_CDY.h delete mode 100644 src/pins/lpc1769/pins_MKS_SGEN.h delete mode 100644 src/pins/lpc1769/pins_MKS_SGEN_L_V2.h delete mode 100644 src/pins/lpc1769/pins_SMOOTHIEBOARD.h delete mode 100644 src/pins/lpc1769/pins_TH3D_EZBOARD.h delete mode 100644 src/pins/mega/env_validate.h delete mode 100644 src/pins/mega/pins_CHEAPTRONIC.h delete mode 100644 src/pins/mega/pins_CHEAPTRONICv2.h delete mode 100644 src/pins/mega/pins_CNCONTROLS_11.h delete mode 100644 src/pins/mega/pins_CNCONTROLS_12.h delete mode 100644 src/pins/mega/pins_CNCONTROLS_15.h delete mode 100644 src/pins/mega/pins_EINSTART-S.h delete mode 100644 src/pins/mega/pins_ELEFU_3.h delete mode 100644 src/pins/mega/pins_GT2560_REV_A.h delete mode 100644 src/pins/mega/pins_GT2560_REV_A_PLUS.h delete mode 100644 src/pins/mega/pins_GT2560_REV_B.h delete mode 100644 src/pins/mega/pins_GT2560_V3.h delete mode 100644 src/pins/mega/pins_GT2560_V3_A20.h delete mode 100644 src/pins/mega/pins_GT2560_V3_MC2.h delete mode 100644 src/pins/mega/pins_GT2560_V4.h delete mode 100644 src/pins/mega/pins_GT2560_V4_A20.h delete mode 100644 src/pins/mega/pins_HJC2560C_REV2.h delete mode 100644 src/pins/mega/pins_INTAMSYS40.h delete mode 100644 src/pins/mega/pins_LEAPFROG.h delete mode 100644 src/pins/mega/pins_LEAPFROG_XEED2015.h delete mode 100644 src/pins/mega/pins_MALYAN_M180.h delete mode 100644 src/pins/mega/pins_MEGACONTROLLER.h delete mode 100644 src/pins/mega/pins_MEGATRONICS.h delete mode 100644 src/pins/mega/pins_MEGATRONICS_2.h delete mode 100644 src/pins/mega/pins_MEGATRONICS_3.h delete mode 100644 src/pins/mega/pins_MIGHTYBOARD_REVE.h delete mode 100644 src/pins/mega/pins_MINITRONICS.h delete mode 100644 src/pins/mega/pins_OVERLORD.h delete mode 100644 src/pins/mega/pins_PICA.h delete mode 100644 src/pins/mega/pins_PICAOLD.h delete mode 100644 src/pins/mega/pins_PROTONEER_CNC_SHIELD_V3.h delete mode 100644 src/pins/mega/pins_SILVER_GATE.h delete mode 100644 src/pins/mega/pins_WANHAO_ONEPLUS.h delete mode 100644 src/pins/mega/pins_WEEDO_62A.h delete mode 100644 src/pins/pins.h delete mode 100644 src/pins/pinsDebug.h delete mode 100644 src/pins/pinsDebug_list.h delete mode 100644 src/pins/pins_postprocess.h delete mode 100644 src/pins/rambo/env_validate.h delete mode 100644 src/pins/rambo/pins_EINSY_RAMBO.h delete mode 100644 src/pins/rambo/pins_EINSY_RETRO.h delete mode 100644 src/pins/rambo/pins_MINIRAMBO.h delete mode 100644 src/pins/rambo/pins_RAMBO.h delete mode 100644 src/pins/rambo/pins_RAMBO_THINKERV2.h delete mode 100644 src/pins/rambo/pins_SCOOVO_X9H.h delete mode 100644 src/pins/ramps/env_validate.h delete mode 100644 src/pins/ramps/pins_3DRAG.h delete mode 100644 src/pins/ramps/pins_AZTEEG_X3.h delete mode 100644 src/pins/ramps/pins_AZTEEG_X3_PRO.h delete mode 100644 src/pins/ramps/pins_BAM_DICE_DUE.h delete mode 100644 src/pins/ramps/pins_BIQU_KFB_2.h delete mode 100644 src/pins/ramps/pins_BQ_ZUM_MEGA_3D.h delete mode 100644 src/pins/ramps/pins_COPYMASTER_3D.h delete mode 100644 src/pins/ramps/pins_DAGOMA_F5.h delete mode 100644 src/pins/ramps/pins_DUPLICATOR_I3_PLUS.h delete mode 100644 src/pins/ramps/pins_FELIX2.h delete mode 100644 src/pins/ramps/pins_FORMBOT_RAPTOR.h delete mode 100644 src/pins/ramps/pins_FORMBOT_RAPTOR2.h delete mode 100644 src/pins/ramps/pins_FORMBOT_TREX2PLUS.h delete mode 100644 src/pins/ramps/pins_FORMBOT_TREX3.h delete mode 100644 src/pins/ramps/pins_FYSETC_F6_13.h delete mode 100644 src/pins/ramps/pins_FYSETC_F6_14.h delete mode 100644 src/pins/ramps/pins_K8200.h delete mode 100644 src/pins/ramps/pins_K8400.h delete mode 100644 src/pins/ramps/pins_K8600.h delete mode 100644 src/pins/ramps/pins_K8800.h delete mode 100644 src/pins/ramps/pins_LONGER3D_LKx_PRO.h delete mode 100644 src/pins/ramps/pins_MAKEBOARD_MINI.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_10.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_14.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_15.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_16.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_HEROIC.h delete mode 100644 src/pins/ramps/pins_MKS_BASE_common.h delete mode 100644 src/pins/ramps/pins_MKS_GEN_13.h delete mode 100644 src/pins/ramps/pins_MKS_GEN_L.h delete mode 100644 src/pins/ramps/pins_MKS_GEN_L_V2.h delete mode 100644 src/pins/ramps/pins_MKS_GEN_L_V21.h delete mode 100644 src/pins/ramps/pins_ORTUR_4.h delete mode 100644 src/pins/ramps/pins_PXMALION_CORE_I3.h delete mode 100644 src/pins/ramps/pins_RAMPS.h delete mode 100644 src/pins/ramps/pins_RAMPS_13.h delete mode 100644 src/pins/ramps/pins_RAMPS_CREALITY.h delete mode 100644 src/pins/ramps/pins_RAMPS_ENDER_4.h delete mode 100644 src/pins/ramps/pins_RAMPS_OLD.h delete mode 100644 src/pins/ramps/pins_RAMPS_PLUS.h delete mode 100644 src/pins/ramps/pins_RAMPS_S_12.h delete mode 100644 src/pins/ramps/pins_RIGIDBOARD.h delete mode 100644 src/pins/ramps/pins_RIGIDBOARD_V2.h delete mode 100644 src/pins/ramps/pins_RL200.h delete mode 100644 src/pins/ramps/pins_RUMBA.h delete mode 100644 src/pins/ramps/pins_RUMBA_RAISE3D.h delete mode 100644 src/pins/ramps/pins_SAINSMART_2IN1.h delete mode 100644 src/pins/ramps/pins_TANGO.h delete mode 100644 src/pins/ramps/pins_TENLOG_D3_HERO.h delete mode 100644 src/pins/ramps/pins_TRIGORILLA_13.h delete mode 100644 src/pins/ramps/pins_TRIGORILLA_14.h delete mode 100644 src/pins/ramps/pins_TRONXY_V3_1_0.h delete mode 100644 src/pins/ramps/pins_TT_OSCAR.h delete mode 100644 src/pins/ramps/pins_ULTIMAIN_2.h delete mode 100644 src/pins/ramps/pins_ULTIMAKER.h delete mode 100644 src/pins/ramps/pins_ULTIMAKER_OLD.h delete mode 100644 src/pins/ramps/pins_VORON.h delete mode 100644 src/pins/ramps/pins_ZRIB_V20.h delete mode 100644 src/pins/ramps/pins_ZRIB_V52.h delete mode 100644 src/pins/ramps/pins_ZRIB_V53.h delete mode 100644 src/pins/ramps/pins_Z_BOLT_X_SERIES.h delete mode 100644 src/pins/sam/env_validate.h delete mode 100644 src/pins/sam/pins_ADSK.h delete mode 100644 src/pins/sam/pins_ALLIGATOR_R2.h delete mode 100644 src/pins/sam/pins_ARCHIM1.h delete mode 100644 src/pins/sam/pins_ARCHIM2.h delete mode 100644 src/pins/sam/pins_CNCONTROLS_15D.h delete mode 100644 src/pins/sam/pins_DUE3DOM.h delete mode 100644 src/pins/sam/pins_DUE3DOM_MINI.h delete mode 100644 src/pins/sam/pins_KRATOS32.h delete mode 100644 src/pins/sam/pins_PRINTRBOARD_G2.h delete mode 100644 src/pins/sam/pins_RADDS.h delete mode 100644 src/pins/sam/pins_RAMPS4DUE.h delete mode 100644 src/pins/sam/pins_RAMPS_DUO.h delete mode 100644 src/pins/sam/pins_RAMPS_FD_V1.h delete mode 100644 src/pins/sam/pins_RAMPS_FD_V2.h delete mode 100644 src/pins/sam/pins_RAMPS_SMART.h delete mode 100644 src/pins/sam/pins_RURAMPS4D_11.h delete mode 100644 src/pins/sam/pins_RURAMPS4D_13.h delete mode 100644 src/pins/sam/pins_ULTRATRONICS_PRO.h delete mode 100644 src/pins/samd/pins_BRICOLEMON_LITE_V1_0.h delete mode 100644 src/pins/samd/pins_BRICOLEMON_V1_0.h delete mode 100644 src/pins/samd/pins_RAMPS_144.h delete mode 100644 src/pins/sanguino/env_validate.h delete mode 100644 src/pins/sanguino/pins_ANET_10.h delete mode 100644 src/pins/sanguino/pins_AZTEEG_X1.h delete mode 100644 src/pins/sanguino/pins_GEN3_MONOLITHIC.h delete mode 100644 src/pins/sanguino/pins_GEN3_PLUS.h delete mode 100644 src/pins/sanguino/pins_GEN6.h delete mode 100644 src/pins/sanguino/pins_GEN6_DELUXE.h delete mode 100644 src/pins/sanguino/pins_GEN7_12.h delete mode 100644 src/pins/sanguino/pins_GEN7_13.h delete mode 100644 src/pins/sanguino/pins_GEN7_14.h delete mode 100644 src/pins/sanguino/pins_GEN7_CUSTOM.h delete mode 100644 src/pins/sanguino/pins_MELZI.h delete mode 100644 src/pins/sanguino/pins_MELZI_CREALITY.h delete mode 100644 src/pins/sanguino/pins_MELZI_MAKR3D.h delete mode 100644 src/pins/sanguino/pins_MELZI_MALYAN.h delete mode 100644 src/pins/sanguino/pins_MELZI_TRONXY.h delete mode 100644 src/pins/sanguino/pins_MELZI_V2.h delete mode 100644 src/pins/sanguino/pins_OMCA.h delete mode 100644 src/pins/sanguino/pins_OMCA_A.h delete mode 100644 src/pins/sanguino/pins_SANGUINOLOLU_11.h delete mode 100644 src/pins/sanguino/pins_SANGUINOLOLU_12.h delete mode 100644 src/pins/sanguino/pins_SETHI.h delete mode 100644 src/pins/sanguino/pins_STB_11.h delete mode 100644 src/pins/sanguino/pins_ZMIB_V2.h delete mode 100644 src/pins/sensitive_pins.h delete mode 100644 src/pins/stm32f0/pins_MALYAN_M200_V2.h delete mode 100644 src/pins/stm32f0/pins_MALYAN_M300.h delete mode 100644 src/pins/stm32f1/env_validate.h delete mode 100644 src/pins/stm32f1/pins_BEAST.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_CR6.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_E3_DIP.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_0.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V1_2.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_E3_V2_0.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_E3_common.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_MZ_V1_0.h delete mode 100644 src/pins/stm32f1/pins_BTT_SKR_MINI_V1_1.h delete mode 100644 src/pins/stm32f1/pins_CCROBOT_MEEB_3DP.h delete mode 100644 src/pins/stm32f1/pins_CHITU3D.h delete mode 100644 src/pins/stm32f1/pins_CHITU3D_V5.h delete mode 100644 src/pins/stm32f1/pins_CHITU3D_V6.h delete mode 100644 src/pins/stm32f1/pins_CHITU3D_V9.h delete mode 100644 src/pins/stm32f1/pins_CHITU3D_common.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V24S1.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V24S1_301.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V25S1.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V4.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V4210.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V422.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V423.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V425.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V427.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V431.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V452.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V453.h delete mode 100644 src/pins/stm32f1/pins_CREALITY_V45x.h delete mode 100644 src/pins/stm32f1/pins_ERYONE_ERY32_MINI.h delete mode 100644 src/pins/stm32f1/pins_FLSUN_HISPEED.h delete mode 100644 src/pins/stm32f1/pins_FLY_MINI.h delete mode 100644 src/pins/stm32f1/pins_FYSETC_AIO_II.h delete mode 100644 src/pins/stm32f1/pins_FYSETC_CHEETAH.h delete mode 100644 src/pins/stm32f1/pins_FYSETC_CHEETAH_V12.h delete mode 100644 src/pins/stm32f1/pins_GTM32_MINI.h delete mode 100644 src/pins/stm32f1/pins_GTM32_MINI_A30.h delete mode 100644 src/pins/stm32f1/pins_GTM32_PRO_VB.h delete mode 100644 src/pins/stm32f1/pins_GTM32_PRO_VD.h delete mode 100644 src/pins/stm32f1/pins_GTM32_REV_B.h delete mode 100644 src/pins/stm32f1/pins_JGAURORA_A5S_A1.h delete mode 100644 src/pins/stm32f1/pins_LONGER3D_LK.h delete mode 100644 src/pins/stm32f1/pins_MALYAN_M200.h delete mode 100644 src/pins/stm32f1/pins_MINGDA_MPX_ARM_MINI.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3D.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3D_V1_1.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3P.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3_V1_1.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3_V1_1_common.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_E3_common.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_LITE.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_LITE3.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_MINI.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_NANO.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_NANO_V2.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_NANO_common.h delete mode 100644 src/pins/stm32f1/pins_MKS_ROBIN_PRO.h delete mode 100644 src/pins/stm32f1/pins_MORPHEUS.h delete mode 100644 src/pins/stm32f1/pins_PANDA_PI_V29.h delete mode 100644 src/pins/stm32f1/pins_STM32F1R.h delete mode 100644 src/pins/stm32f1/pins_STM3R_MINI.h delete mode 100644 src/pins/stm32f1/pins_TRIGORILLA_PRO.h delete mode 100644 src/pins/stm32f1/pins_ZM3E2_V1_0.h delete mode 100644 src/pins/stm32f1/pins_ZM3E4_V1_0.h delete mode 100644 src/pins/stm32f1/pins_ZM3E4_V2_0.h delete mode 100644 src/pins/stm32f4/env_validate.h delete mode 100644 src/pins/stm32f4/pins_ANET_ET4.h delete mode 100644 src/pins/stm32f4/pins_ANET_ET4P.h delete mode 100644 src/pins/stm32f4/pins_ARMED.h delete mode 100644 src/pins/stm32f4/pins_ARTILLERY_RUBY.h delete mode 100644 src/pins/stm32f4/pins_BLACK_STM32F407VE.h delete mode 100644 src/pins/stm32f4/pins_BTT_BTT002_V1_0.h delete mode 100644 src/pins/stm32f4/pins_BTT_E3_RRF.h delete mode 100644 src/pins/stm32f4/pins_BTT_GTR_V1_0.h delete mode 100644 src/pins/stm32f4/pins_BTT_OCTOPUS_PRO_V1_0.h delete mode 100644 src/pins/stm32f4/pins_BTT_OCTOPUS_V1_0.h delete mode 100644 src/pins/stm32f4/pins_BTT_OCTOPUS_V1_1.h delete mode 100644 src/pins/stm32f4/pins_BTT_OCTOPUS_V1_common.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_PRO_V1_1.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_PRO_V1_2.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_PRO_common.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_V2_0_REV_A.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_V2_0_REV_B.h delete mode 100644 src/pins/stm32f4/pins_BTT_SKR_V2_0_common.h delete mode 100644 src/pins/stm32f4/pins_CREALITY_V24S1_301F4.h delete mode 100644 src/pins/stm32f4/pins_FLYF407ZG.h delete mode 100644 src/pins/stm32f4/pins_FYSETC_CHEETAH_V20.h delete mode 100644 src/pins/stm32f4/pins_FYSETC_S6.h delete mode 100644 src/pins/stm32f4/pins_FYSETC_S6_V2_0.h delete mode 100644 src/pins/stm32f4/pins_FYSETC_SPIDER.h delete mode 100644 src/pins/stm32f4/pins_FYSETC_SPIDER_V2_2.h delete mode 100644 src/pins/stm32f4/pins_LERDGE_K.h delete mode 100644 src/pins/stm32f4/pins_LERDGE_S.h delete mode 100644 src/pins/stm32f4/pins_LERDGE_X.h delete mode 100644 src/pins/stm32f4/pins_MKS_EAGLE.h delete mode 100644 src/pins/stm32f4/pins_MKS_MONSTER8_V1.h delete mode 100644 src/pins/stm32f4/pins_MKS_MONSTER8_V2.h delete mode 100644 src/pins/stm32f4/pins_MKS_MONSTER8_common.h delete mode 100644 src/pins/stm32f4/pins_MKS_ROBIN2.h delete mode 100644 src/pins/stm32f4/pins_MKS_ROBIN_NANO_V1_3_F4.h delete mode 100644 src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3.h delete mode 100644 src/pins/stm32f4/pins_MKS_ROBIN_NANO_V3_common.h delete mode 100644 src/pins/stm32f4/pins_MKS_ROBIN_PRO_V2.h delete mode 100644 src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h delete mode 100644 src/pins/stm32f4/pins_RUMBA32_AUS3D.h delete mode 100644 src/pins/stm32f4/pins_RUMBA32_BTT.h delete mode 100644 src/pins/stm32f4/pins_RUMBA32_MKS.h delete mode 100644 src/pins/stm32f4/pins_RUMBA32_common.h delete mode 100644 src/pins/stm32f4/pins_STEVAL_3DP001V1.h delete mode 100644 src/pins/stm32f4/pins_TH3D_EZBOARD_V2.h delete mode 100644 src/pins/stm32f4/pins_VAKE403D.h delete mode 100644 src/pins/stm32f7/pins_NUCLEO_F767ZI.h delete mode 100644 src/pins/stm32f7/pins_REMRAM_V1.h delete mode 100644 src/pins/stm32g0/pins_BTT_SKR_MINI_E3_V3_0.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_SE_BX_V2.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_SE_BX_V3.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_SE_BX_common.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_V3_0.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_V3_0_EZ.h delete mode 100644 src/pins/stm32h7/pins_BTT_SKR_V3_0_common.h delete mode 100644 src/pins/teensy2/env_validate.h delete mode 100644 src/pins/teensy2/pins_5DPRINT.h delete mode 100644 src/pins/teensy2/pins_BRAINWAVE.h delete mode 100644 src/pins/teensy2/pins_BRAINWAVE_PRO.h delete mode 100644 src/pins/teensy2/pins_PRINTRBOARD.h delete mode 100644 src/pins/teensy2/pins_PRINTRBOARD_REVF.h delete mode 100644 src/pins/teensy2/pins_SAV_MKI.h delete mode 100644 src/pins/teensy2/pins_TEENSY2.h delete mode 100644 src/pins/teensy2/pins_TEENSYLU.h delete mode 100644 src/pins/teensy3/pins_TEENSY31_32.h delete mode 100644 src/pins/teensy3/pins_TEENSY35_36.h delete mode 100644 src/pins/teensy4/pins_T41U5XBB.h delete mode 100644 src/pins/teensy4/pins_TEENSY41.h delete mode 100644 src/sd/Sd2Card.cpp delete mode 100644 src/sd/Sd2Card.h delete mode 100644 src/sd/Sd2Card_sdio.h delete mode 100644 src/sd/SdBaseFile.cpp delete mode 100644 src/sd/SdBaseFile.h delete mode 100644 src/sd/SdFatConfig.h delete mode 100644 src/sd/SdFatStructs.h delete mode 100644 src/sd/SdFatUtil.cpp delete mode 100644 src/sd/SdFatUtil.h delete mode 100644 src/sd/SdFile.cpp delete mode 100644 src/sd/SdFile.h delete mode 100644 src/sd/SdInfo.h delete mode 100644 src/sd/SdVolume.cpp delete mode 100644 src/sd/SdVolume.h delete mode 100644 src/sd/cardreader.cpp delete mode 100644 src/sd/cardreader.h delete mode 100644 src/sd/disk_io_driver.h delete mode 100644 src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp delete mode 100644 src/sd/usb_flashdrive/Sd2Card_FlashDrive.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/README.txt delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/Usb.cpp delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/Usb.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/UsbCore.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/address.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/confdescparser.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/hexdump.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/macros.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/masstorage.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/max3421e.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/message.cpp delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/message.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/parsetools.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/printhex.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/settings.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp delete mode 100644 src/sd/usb_flashdrive/lib-uhs2/usbhost.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/README.txt delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_USB_IDs.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h delete mode 100644 src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h diff --git a/Configuration.h b/Configuration.h deleted file mode 100644 index fcbdaec..0000000 --- a/Configuration.h +++ /dev/null @@ -1,3166 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CONFIG_EXAMPLES_DIR "FlashForge/CreatorPro" - -/** - * 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 - */ -#define CONFIGURATION_H_VERSION 02000905 - -//=========================================================================== -//============================= Getting Started ============================= -//=========================================================================== - -/** - * Here are some useful links to help get your machine configured and calibrated: - * - * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all - * - * Průša Calculator: https://blog.prusaprinters.org/calculator_3416/ - * - * Calibration Guides: https://reprap.org/wiki/Calibration - * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide - * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap - * https://youtu.be/wAL9d7FgInk - * - * Calibration Objects: https://www.thingiverse.com/thing:5573 - * https://www.thingiverse.com/thing:1278865 - */ - -// @section info - -// Author info of this build printed to the host during boot and M115 -#define STRING_CONFIG_H_AUTHOR "M. Baker" // Who made the changes. -//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) - -/** - * *** VENDORS PLEASE READ *** - * - * Marlin allows you to add a custom boot image for Graphical LCDs. - * With this option Marlin will first show your custom screen followed - * by the standard Marlin logo with version number and web URL. - * - * We encourage you to take advantage of this new feature and we also - * respectfully request that you retain the unmodified Marlin boot screen. - */ - -// Show the Marlin bootscreen on startup. ** ENABLE FOR PRODUCTION ** -#define SHOW_BOOTSCREEN - -// Show the bitmap in Marlin/_Bootscreen.h on startup. -//#define SHOW_CUSTOM_BOOTSCREEN - -// Show the bitmap in Marlin/_Statusscreen.h on the status screen. -//#define CUSTOM_STATUS_SCREEN_IMAGE - -// @section machine - -// Choose the name from boards.h that matches your setup -#ifndef MOTHERBOARD - #define MOTHERBOARD BOARD_MKS_GEN_L_V21 -#endif - -/** - * Select the serial port on the board to use for communication with the host. - * This allows the connection of wireless adapters (for instance) to non-default port pins. - * Serial port -1 is the USB emulated serial port, if available. - * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. - * - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -#define SERIAL_PORT 0 - -/** - * Serial Port Baud Rate - * This is the default communication speed for all serial ports. - * Set the baud rate defaults for additional serial ports below. - * - * 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 9600 -//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate - -/** - * Select a secondary serial port on the board to use for communication with the host. - * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. - * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -//#define SERIAL_PORT_2 -1 -//#define BAUDRATE_2 250000 // Enable to override BAUDRATE - -/** - * Select a third serial port on the board to use for communication with the host. - * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1 - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -//#define SERIAL_PORT_3 1 -//#define BAUDRATE_3 250000 // Enable to override BAUDRATE - -// Enable the Bluetooth serial interface on AT90USB devices -//#define BLUETOOTH - -// Name displayed in the LCD "Ready" message and Info menu -#define CUSTOM_MACHINE_NAME "Makerbot Replicator" - -// Printer's unique ID, used by some programs to differentiate between machines. -// Choose your own or use a service like https://www.uuidgenerator.net/version4 -//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" - -/** - * Stepper Drivers - * - * These settings allow Marlin to tune stepper driver timing and enable advanced options for - * stepper drivers that support them. You may also override timing options in Configuration_adv.h. - * - * Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers. - * - * Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01, - * TB6560, TB6600, TMC2100, - * TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE, - * TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE, - * TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE, - * TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE - * :['A4988', 'A5984', 'DRV8825', 'LV8729', 'L6470', 'L6474', 'POWERSTEP01', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE'] - */ -#define X_DRIVER_TYPE TMC2209_STANDALONE -#define Y_DRIVER_TYPE TMC2209_STANDALONE -#define Z_DRIVER_TYPE TMC2209_STANDALONE -//#define X2_DRIVER_TYPE A4988 -//#define Y2_DRIVER_TYPE A4988 -//#define Z2_DRIVER_TYPE A4988 -//#define Z3_DRIVER_TYPE A4988 -//#define Z4_DRIVER_TYPE A4988 -//#define I_DRIVER_TYPE A4988 -//#define J_DRIVER_TYPE A4988 -//#define K_DRIVER_TYPE A4988 -#define E0_DRIVER_TYPE TMC2209_STANDALONE -#define E1_DRIVER_TYPE TMC2209_STANDALONE -//#define E2_DRIVER_TYPE A4988 -//#define E3_DRIVER_TYPE A4988 -//#define E4_DRIVER_TYPE A4988 -//#define E5_DRIVER_TYPE A4988 -//#define E6_DRIVER_TYPE A4988 -//#define E7_DRIVER_TYPE A4988 - -/** - * Additional Axis Settings - * - * AXISn_NAME defines the letter used to refer to the axis in (most) G-code commands. - * By convention the names and roles are typically: - * 'A' : Rotational axis parallel to X - * 'B' : Rotational axis parallel to Y - * 'C' : Rotational axis parallel to Z - * 'U' : Secondary linear axis parallel to X - * 'V' : Secondary linear axis parallel to Y - * 'W' : Secondary linear axis parallel to Z - * - * Regardless of these settings the axes are internally named I, J, K. - */ -#ifdef I_DRIVER_TYPE - #define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W'] -#endif -#ifdef J_DRIVER_TYPE - #define AXIS5_NAME 'B' // :['B', 'C', 'U', 'V', 'W'] -#endif -#ifdef K_DRIVER_TYPE - #define AXIS6_NAME 'C' // :['C', 'U', 'V', 'W'] -#endif - -// @section extruder - -// This defines the number of extruders -// :[0, 1, 2, 3, 4, 5, 6, 7, 8] -#define EXTRUDERS 2 - -// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 - -// For Cyclops or any "multi-extruder" that shares a single nozzle. -//#define SINGLENOZZLE - -// Save and restore temperature and fan speed on tool-change. -// Set standby for the unselected tool with M104/106/109 T... -#if ENABLED(SINGLENOZZLE) - //#define SINGLENOZZLE_STANDBY_TEMP - //#define SINGLENOZZLE_STANDBY_FAN -#endif - -/** - * Multi-Material Unit - * Set to one of these predefined models: - * - * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version) - * PRUSA_MMU2 : Průša MMU2 - * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5) - * EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) - * EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) - * - * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. - * See additional options in Configuration_adv.h. - */ -//#define MMU_MODEL PRUSA_MMU2 - -// 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 (or both) of the nozzles -//#define SWITCHING_NOZZLE -#if ENABLED(SWITCHING_NOZZLE) - #define SWITCHING_NOZZLE_SERVO_NR 0 - //#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second - #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 (single servo) or lowered/raised (dual servo) -#endif - -/** - * Two separate X-carriages with extruders that connect to a moving part - * via a solenoid docking mechanism. Requires SOL1_PIN and SOL2_PIN. - */ -//#define PARKING_EXTRUDER - -/** - * Two separate X-carriages with extruders that connect to a moving part - * via a magnetic docking mechanism using movements and no solenoid - * - * project : https://www.thingiverse.com/thing:3080893 - * movements : https://youtu.be/0xCEiG9VS3k - * https://youtu.be/Bqbcs0CU2FE - */ -//#define MAGNETIC_PARKING_EXTRUDER - -#if EITHER(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) - - #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders - #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the 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 // (ms) Delay for magnetic field. No delay if 0 or not defined. - //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381 - - #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) - - #define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point - #define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple - #define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point - #define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling - - #endif - -#endif - -/** - * Switching Toolhead - * - * Support for swappable and dockable toolheads, such as - * the E3D Tool Changer. Toolheads are locked with a servo. - */ -//#define SWITCHING_TOOLHEAD - -/** - * Magnetic Switching Toolhead - * - * Support swappable and dockable toolheads with a magnetic - * docking mechanism using movement and no servo. - */ -//#define MAGNETIC_SWITCHING_TOOLHEAD - -/** - * Electromagnetic Switching Toolhead - * - * Parking for CoreXY / HBot kinematics. - * Toolheads are parked at one edge and held with an electromagnet. - * Supports more than 2 Toolheads. See https://youtu.be/JolbsAKTKf4 - */ -//#define ELECTROMAGNETIC_SWITCHING_TOOLHEAD - -#if ANY(SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Y_POS 235 // (mm) Y position of the toolhead dock - #define SWITCHING_TOOLHEAD_Y_SECURITY 10 // (mm) Security distance Y axis - #define SWITCHING_TOOLHEAD_Y_CLEAR 60 // (mm) Minimum distance from dock for unobstructed X axis - #define SWITCHING_TOOLHEAD_X_POS { 215, 0 } // (mm) X positions for parking the extruders - #if ENABLED(SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_SERVO_NR 2 // Index of the servo connector - #define SWITCHING_TOOLHEAD_SERVO_ANGLES { 0, 180 } // (degrees) Angles for Lock, Unlock - #elif ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Y_RELEASE 5 // (mm) Security distance Y axis - #define SWITCHING_TOOLHEAD_X_SECURITY { 90, 150 } // (mm) Security distance X axis (T0,T1) - //#define PRIME_BEFORE_REMOVE // Prime the nozzle before release from the dock - #if ENABLED(PRIME_BEFORE_REMOVE) - #define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length - #define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length - #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate - #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate - #endif - #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching - #endif -#endif - -/** - * "Mixing Extruder" - * - Adds G-codes M163 and M164 to set and "commit" the current mix factors. - * - Extends the stepping routines to move multiple steppers in proportion to the mix. - * - Optional support for Repetier Firmware's 'M164 S' supporting virtual tools. - * - This implementation supports up to two mixing extruders. - * - Enable DIRECT_MIXING_IN_G1 for M165 and mixing in G1 (from 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 - //#define GRADIENT_MIX // Support for gradient mixing with M166 and LCD - //#define MIXING_PRESETS // Assign 8 default V-tool presets for 2 or 3 MIXING_STEPPERS - #if ENABLED(GRADIENT_MIX) - //#define GRADIENT_VTOOL // Add M166 T to use a V-tool index as a Gradient alias - #endif -#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, -34.00 } // (mm) relative X-offset for each nozzle -//#define HOTEND_OFFSET_Y { 0.0, 0.00 } // (mm) relative Y-offset for each nozzle -//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle - -// @section machine - -/** - * Power Supply Control - * - * Enable and connect the power supply to the PS_ON_PIN. - * Specify whether the power supply is active HIGH or active LOW. - */ -//#define PSU_CONTROL -//#define PSU_NAME "Power Supply" - -#if ENABLED(PSU_CONTROL) - //#define MKS_PWC // Using the MKS PWC add-on - //#define PS_OFF_CONFIRM // Confirm dialog when power off - //#define PS_OFF_SOUND // Beep 1s when power off - #define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box - - //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80 - //#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power - //#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay - - //#define POWER_OFF_TIMER // Enable M81 D to power off after a delay - //#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown - - //#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on) - //#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off) - - //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin - #if ENABLED(AUTO_POWER_CONTROL) - #define AUTO_POWER_FANS // Turn on PSU if fans need power - #define AUTO_POWER_E_FANS - #define AUTO_POWER_CONTROLLERFAN - #define AUTO_POWER_CHAMBER_FAN - #define AUTO_POWER_COOLER_FAN - #define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration - //#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time. - #endif - #if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) - //#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature - //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature - //#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature - #endif -#endif - -//=========================================================================== -//============================= Thermal Settings ============================ -//=========================================================================== -// @section temperature - -/** - * --NORMAL IS 4.7kΩ PULLUP!-- 1kΩ pullup can be used on hotend sensor, using correct resistor and table - * - * Temperature sensors available: - * - * SPI RTD/Thermocouple Boards - IMPORTANT: Read the NOTE below! - * ------- - * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-1) - * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below. - * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-1) - * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-1) - * - * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default, - * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN, - * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the - * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported. - * - * Analog Themocouple Boards - * ------- - * -4 : AD8495 with Thermocouple - * -1 : AD595 with Thermocouple - * - * Analog Thermistors - 4.7kΩ pullup - Normal - * ------- - * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors - * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA - * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE - * 2 : 200kΩ ATC Semitec 204GT-2 - * 202 : 200kΩ Copymaster 3D - * 3 : ???Ω Mendel-parts thermistor - * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !! - * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C - * 501 : 100kΩ Zonestar - Tronxy X3A - * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M - * 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor - * 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor - * 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor - * 512 : 100kΩ RPW-Ultra hotend - * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple) - * 7 : 100kΩ Honeywell 135-104LAG-J01 - * 71 : 100kΩ Honeywell 135-104LAF-J01 - * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT - * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1 - * 10 : 100kΩ RS PRO 198-961 - * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1% - * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed - * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1% - * 15 : 100kΩ Calibrated for JGAurora A5 hotend - * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327 - * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input - * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input - * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 - * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 - * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 - * 66 : 4.7MΩ Dyze Design High Temperature Thermistor - * 67 : 500kΩ SliceEngineering 450°C Thermistor - * 68 : PT100 amplifier board from Dyze Design - * 70 : 100kΩ bq Hephestos 2 - * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32 - * 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor - * - * Analog Thermistors - 1kΩ pullup - Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ. - * ------- (but gives greater accuracy and more stable PID) - * 51 : 100kΩ EPCOS (1kΩ pullup) - * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup) - * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup) - * - * Analog Thermistors - 10kΩ pullup - Atypical - * ------- - * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor - * - * Analog RTDs (Pt100/Pt1000) - * ------- - * 110 : Pt100 with 1kΩ pullup (atypical) - * 147 : Pt100 with 4.7kΩ pullup - * 1010 : Pt1000 with 1kΩ pullup (atypical) - * 1047 : Pt1000 with 4.7kΩ pullup (E3D) - * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. - * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. - * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. - * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. - * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x - * - * Custom/Dummy/Other Thermal Sensors - * ------ - * 0 : not used - * 1000 : Custom - Specify parameters in Configuration_adv.h - * - * !!! 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. - * - */ -#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_5 0 -#define TEMP_SENSOR_6 0 -#define TEMP_SENSOR_7 0 -#define TEMP_SENSOR_BED 1 -#define TEMP_SENSOR_PROBE 0 -#define TEMP_SENSOR_CHAMBER 0 -#define TEMP_SENSOR_COOLER 0 -#define TEMP_SENSOR_BOARD 0 -#define TEMP_SENSOR_REDUNDANT 0 - -// Dummy thermistor constant temperature readings, for use with 998 and 999 -#define DUMMY_THERMISTOR_998_VALUE 25 -#define DUMMY_THERMISTOR_999_VALUE 100 - -// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1 -//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000) -//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000 -//#define MAX31865_SENSOR_OHMS_1 100 -//#define MAX31865_CALIBRATION_OHMS_1 430 - -#define TEMP_RESIDENCY_TIME 0 // (seconds) Time to wait for hotend to "settle" in M109 -#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) Time to wait for bed to "settle" in M190 -#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191 -#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -/** - * Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT) - * - * Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another - * sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C), - * the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting - * the Bed sensor (-1) will disable bed heating/monitoring. - * - * For selecting source/target use: COOLER, PROBE, BOARD, CHAMBER, BED, E0, E1, E2, E3, E4, E5, E6, E7 - */ -#if TEMP_SENSOR_REDUNDANT - #define TEMP_SENSOR_REDUNDANT_SOURCE E1 // The sensor that will provide the redundant reading. - #define TEMP_SENSOR_REDUNDANT_TARGET E0 // The sensor that we are providing a redundant reading for. - #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort. -#endif - -// Below this temperature the heater will be switched off -// because it probably indicates a broken thermistor wire. -#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 HEATER_5_MINTEMP 5 -#define HEATER_6_MINTEMP 5 -#define HEATER_7_MINTEMP 5 -#define BED_MINTEMP 5 -#define CHAMBER_MINTEMP 5 - -// Above this temperature the heater will be switched off. -// This can protect components from overheating, but NOT from shorts and failures. -// (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 HEATER_5_MAXTEMP 260 -#define HEATER_6_MAXTEMP 260 -#define HEATER_7_MAXTEMP 260 -#define BED_MAXTEMP 110 -#define CHAMBER_MAXTEMP 60 - -/** - * Thermal Overshoot - * During heatup (and printing) the temperature can often "overshoot" the target by many degrees - * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees - * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP. - */ -#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT -#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT -#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT - -//=========================================================================== -//============================= PID Settings ================================ -//=========================================================================== - -// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model. -// temperature control. Disable both for bang-bang heating. -#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning -//#define MPCTEMP // ** EXPERIMENTAL ** - -#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current -#define PID_K1 0.95 // Smoothing factor within any PID loop - -#if ENABLED(PIDTEMP) - //#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) - // Set/get with G-code: M301 E[extruder number, 0-2] - - #if ENABLED(PID_PARAMS_PER_HOTEND) - // Specify up to one value per hotend here, according to your setup. - // If there are fewer values, the last one applies to the remaining hotends. - #define DEFAULT_Kp_LIST { 20.03, 20.03 } - #define DEFAULT_Ki_LIST { 1.22, 1.22 } - #define DEFAULT_Kd_LIST { 82.05, 82.05 } - #else - #define DEFAULT_Kp 20.03 - #define DEFAULT_Ki 1.22 - #define DEFAULT_Kd 82.05 - #endif -#endif - -/** - * Model Predictive Control for hotend - * - * Use a physical model of the hotend to control temperature. When configured correctly - * this gives better responsiveness and stability than PID and it also removes the need - * for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 T to autotune the model. - */ -#if ENABLED(MPCTEMP) - //#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash) - //#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash) - - #define MPC_MAX BANG_MAX // (0..255) Current to nozzle while MPC is active. - #define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers. - - #define MPC_INCLUDE_FAN // Model the fan speed? - - // Measured physical constants from M306 - #define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities. - #define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block. - #define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off. - #if ENABLED(MPC_INCLUDE_FAN) - #define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full. - #endif - - // For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect. - #if ENABLED(MPC_INCLUDE_FAN) - //#define MPC_FAN_0_ALL_HOTENDS - //#define MPC_FAN_0_ACTIVE_HOTEND - #endif - - #define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA). - //#define FILAMENT_HEAT_CAPACITY_PERMM { 3.6e-3f } // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG). - - // Advanced options - #define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization. - #define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies. - #define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced. - - #define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height. - #define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position. -#endif - -//=========================================================================== -//====================== PID > Bed Temperature Control ====================== -//=========================================================================== - -/** - * PID Bed Heating - * - * If this option is enabled set PID constants below. - * If this option is disabled, bang-bang will be used and BED_LIMIT_SWITCHING will enable hysteresis. - * - * The PID frequency will be the same as the extruder PWM. - * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, - * which is fine for driving a square wave into a resistive load and does not significantly - * impact 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, don't use bed PID until someone else verifies that your hardware works. - */ -//#define PIDTEMPBED - -//#define BED_LIMIT_SWITCHING - -/** - * Max Bed Power - * Applies to all forms of bed control (PID, bang-bang, and bang-bang with hysteresis). - * When set to any value below 255, enables a form of PWM to the bed that acts like a divider - * so don'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 MIN_BED_POWER 0 - //#define PID_BED_DEBUG // Sends debug data to the serial port. - - // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) - // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) - #define DEFAULT_bedKp 10.00 - #define DEFAULT_bedKi .023 - #define DEFAULT_bedKd 305.4 - - // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. -#endif // PIDTEMPBED - -//=========================================================================== -//==================== PID > Chamber Temperature Control ==================== -//=========================================================================== - -/** - * PID Chamber Heating - * - * If this option is enabled set PID constants below. - * If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable - * hysteresis. - * - * The PID frequency will be the same as the extruder PWM. - * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, - * which is fine for driving a square wave into a resistive load and does not significantly - * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W - * heater. If your configuration is significantly different than this and you don't understand - * the issues involved, don't use chamber PID until someone else verifies that your hardware works. - */ -//#define PIDTEMPCHAMBER -//#define CHAMBER_LIMIT_SWITCHING - -/** - * Max Chamber Power - * Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis). - * When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider - * so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER) - */ -#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current - -#if ENABLED(PIDTEMPCHAMBER) - #define MIN_CHAMBER_POWER 0 - //#define PID_CHAMBER_DEBUG // Sends debug data to the serial port. - - // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element - // and placed inside the small Creality printer enclosure tent. - // - #define DEFAULT_chamberKp 37.04 - #define DEFAULT_chamberKi 1.40 - #define DEFAULT_chamberKd 655.17 - // M309 P37.04 I1.04 D655.17 - - // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles. -#endif // PIDTEMPCHAMBER - -#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) - //#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation. - //#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX - //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay - #define PID_FUNCTIONAL_RANGE 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 PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) - //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) -#endif - -// @section extruder - -/** - * Prevent extrusion if the temperature is below EXTRUDE_MINTEMP. - * Add M302 to set the minimum extrusion temperature and/or turn - * cold extrusion prevention on and off. - * - * *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** - */ -#define PREVENT_COLD_EXTRUSION -#define EXTRUDE_MINTEMP 170 - -/** - * Prevent a single extrusion longer than EXTRUDE_MAXLENGTH. - * Note: For Bowden Extruders make this large enough to allow load/unload. - */ -#define PREVENT_LENGTHY_EXTRUDE -#define EXTRUDE_MAXLENGTH 200 - -//=========================================================================== -//======================== Thermal Runaway Protection ======================= -//=========================================================================== - -/** - * Thermal Protection provides additional protection to your printer from damage - * and fire. Marlin always includes safe min and max temperature ranges which - * protect against a broken or disconnected thermistor wire. - * - * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the 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 -#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber -#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling - -//=========================================================================== -//============================= Mechanical Settings ========================= -//=========================================================================== - -// @section machine - -// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, -// either in the usual order or reversed -//#define COREXY -//#define COREXZ -//#define COREYZ -//#define COREYX -//#define COREZX -//#define COREZY -//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042 -//#define MARKFORGED_YX - -// Enable for a belt style printer with endless "Z" motion -//#define BELTPRINTER - -// Enable for Polargraph Kinematics -//#define POLARGRAPH -#if ENABLED(POLARGRAPH) - #define POLARGRAPH_MAX_BELT_LEN 1035.0 - #define POLAR_SEGMENTS_PER_SECOND 5 -#endif - -// Enable for DELTA kinematics and configure below -//#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 EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU) - // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.05 // (mm) - #endif - - // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). - #define DELTA_PRINTABLE_RADIUS 140.0 // (mm) - - // Maximum reachable area - #define DELTA_MAX_RADIUS 140.0 // (mm) - - // Center-to-center distance of the holes in the diagonal push rods. - #define DELTA_DIAGONAL_ROD 250.0 // (mm) - - // Distance between bed and nozzle Z home position - #define DELTA_HEIGHT 250.00 // (mm) Get this value from G33 auto calibrate - - #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // Get these values from G33 auto calibrate - - // Horizontal distance bridged by diagonal push rods when effector is centered. - #define DELTA_RADIUS 124.0 // (mm) Get this value from G33 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 G33 auto calibrate - - // Delta radius and diagonal rod adjustments (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 - -/** - * MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013. - * Implemented and slightly reworked by JCERNY in June, 2014. - * - * Mostly Printed SCARA is an open source design by Tyler Williams. See: - * https://www.thingiverse.com/thing:2487048 - * https://www.thingiverse.com/thing:1241491 - */ -//#define MORGAN_SCARA -//#define MP_SCARA -#if EITHER(MORGAN_SCARA, MP_SCARA) - // 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) - - #if ENABLED(MORGAN_SCARA) - - //#define DEBUG_SCARA_KINEMATICS - #define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly - - // Radius around the center where the arm cannot reach - #define MIDDLE_DEAD_ZONE_R 0 // (mm) - - #define THETA_HOMING_OFFSET 0 // Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - #define PSI_HOMING_OFFSET 0 // Calculated from Calibration Guide and M364 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - - #elif ENABLED(MP_SCARA) - - #define SCARA_OFFSET_THETA1 12 // degrees - #define SCARA_OFFSET_THETA2 131 // degrees - - #endif - -#endif - -// Enable for TPARA kinematics and configure below -//#define AXEL_TPARA -#if ENABLED(AXEL_TPARA) - #define DEBUG_ROBOT_KINEMATICS - #define ROBOT_SEGMENTS_PER_SECOND 200 - - // Length of inner and outer support arms. Measure arm lengths precisely. - #define ROBOT_LINKAGE_1 120 // (mm) - #define ROBOT_LINKAGE_2 120 // (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 ROBOT_OFFSET_X 0 // (mm) - #define ROBOT_OFFSET_Y 0 // (mm) - #define ROBOT_OFFSET_Z 0 // (mm) - - #define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly - - // Radius around the center where the arm cannot reach - #define MIDDLE_DEAD_ZONE_R 0 // (mm) - - // Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - #define THETA_HOMING_OFFSET 0 - #define PSI_HOMING_OFFSET 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_IMIN_PLUG -//#define USE_JMIN_PLUG -//#define USE_KMIN_PLUG -#define USE_XMAX_PLUG -//#define USE_YMAX_PLUG -//#define USE_ZMAX_PLUG -//#define USE_IMAX_PLUG -//#define USE_JMAX_PLUG -//#define USE_KMAX_PLUG - -// Enable pullup for all endstops to prevent a floating state -#define ENDSTOPPULLUPS -#if DISABLED(ENDSTOPPULLUPS) - // Disable ENDSTOPPULLUPS to set pullups individually - //#define ENDSTOPPULLUP_XMIN - //#define ENDSTOPPULLUP_YMIN - //#define ENDSTOPPULLUP_ZMIN - //#define ENDSTOPPULLUP_IMIN - //#define ENDSTOPPULLUP_JMIN - //#define ENDSTOPPULLUP_KMIN - //#define ENDSTOPPULLUP_XMAX - //#define ENDSTOPPULLUP_YMAX - //#define ENDSTOPPULLUP_ZMAX - //#define ENDSTOPPULLUP_IMAX - //#define ENDSTOPPULLUP_JMAX - //#define ENDSTOPPULLUP_KMAX - //#define ENDSTOPPULLUP_ZMIN_PROBE -#endif - -// Enable pulldown for all endstops to prevent a floating state -//#define ENDSTOPPULLDOWNS -#if DISABLED(ENDSTOPPULLDOWNS) - // Disable ENDSTOPPULLDOWNS to set pulldowns individually - //#define ENDSTOPPULLDOWN_XMIN - //#define ENDSTOPPULLDOWN_YMIN - //#define ENDSTOPPULLDOWN_ZMIN - //#define ENDSTOPPULLDOWN_IMIN - //#define ENDSTOPPULLDOWN_JMIN - //#define ENDSTOPPULLDOWN_KMIN - //#define ENDSTOPPULLDOWN_XMAX - //#define ENDSTOPPULLDOWN_YMAX - //#define ENDSTOPPULLDOWN_ZMAX - //#define ENDSTOPPULLDOWN_IMAX - //#define ENDSTOPPULLDOWN_JMAX - //#define ENDSTOPPULLDOWN_KMAX - //#define ENDSTOPPULLDOWN_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 I_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define J_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define K_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 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 I_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define J_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define K_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 - -/** - * Endstop Noise Threshold - * - * Enable if your probe or endstops falsely trigger due to noise. - * - * - Higher values may affect repeatability or accuracy of some bed probes. - * - To fix noise install a 100nF ceramic capacitor in parallel with the switch. - * - This feature is not required for common micro-switches mounted on PCBs - * based on the Makerbot design, which already have the 100nF capacitor. - * - * :[2,3,4,5,6,7] - */ -//#define ENDSTOP_NOISE_THRESHOLD 2 - -// Check for stuck or disconnected endstops during homing moves. -//#define DETECT_BROKEN_ENDSTOP - -//============================================================================= -//============================== 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 [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 94.139704, 94.139704, 400, 96.275201870 } - -/** - * Default Max Feed Rate (mm/s) - * Override with M203 - * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_MAX_FEEDRATE { 250, 250, 20, 100 } - -//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2 -#if ENABLED(LIMITED_MAX_FR_EDITING) - #define MAX_FEEDRATE_EDIT_VALUES { 600, 600, 10, 50 } // ...or, set your own edit limits -#endif - -/** - * Default Max Acceleration (change/s) change = mm/s - * (Maximum start speed for accelerated moves) - * Override with M201 - * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 100, 5000 } - -//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2 -#if ENABLED(LIMITED_MAX_ACCEL_EDITING) - #define MAX_ACCEL_EDIT_VALUES { 6000, 6000, 200, 20000 } // ...or, set your own edit limits -#endif - -/** - * Default Acceleration (change/s) change = mm/s - * Override with M204 - * - * M204 P Acceleration - * M204 R Retract Acceleration - * M204 T Travel Acceleration - */ -#define DEFAULT_ACCELERATION 250 // X, Y, Z ... and E acceleration for printing moves -#define DEFAULT_RETRACT_ACCELERATION 5000 // E acceleration for retracts -#define DEFAULT_TRAVEL_ACCELERATION 500 // X, Y, Z ... acceleration for travel (non printing) moves - -/** - * Default Jerk limits (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 CLASSIC_JERK -#if ENABLED(CLASSIC_JERK) -#define DEFAULT_XJERK 20.0 -#define DEFAULT_YJERK 20.0 -#define DEFAULT_ZJERK 0.4 - //#define DEFAULT_IJERK 0.3 - //#define DEFAULT_JJERK 0.3 - //#define DEFAULT_KJERK 0.3 - - //#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves - - //#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2 - #if ENABLED(LIMITED_JERK_EDITING) - #define MAX_JERK_EDIT_VALUES { 20, 20, 0.6, 10 } // ...or, set your own edit limits - #endif -#endif - -#define DEFAULT_EJERK 2.0 // May be used by Linear Advance - -/** - * Junction Deviation Factor - * - * See: - * https://reprap.org/forum/read.php?1,739819 - * https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html - */ -#if DISABLED(CLASSIC_JERK) - #define JUNCTION_DEVIATION_MM 0.64 // (mm) Distance from real junction edge - #define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle - // for small segments (< 1mm) with large junction angles (> 135°). -#endif - -/** - * S-Curve Acceleration - * - * This option eliminates vibration during printing by fitting a Bézier - * curve to move acceleration, producing much smoother direction changes. - * - * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained - */ -#define S_CURVE_ACCELERATION - -//=========================================================================== -//============================= Z Probe Options ============================= -//=========================================================================== -// @section probes - -// -// See https://marlinfw.org/docs/configuration/probes.html -// - -/** - * Enable this option for a probe connected to the Z-MIN pin. - * The probe replaces the Z-MIN endstop and is used for Z homing. - * (Automatically enables USE_PROBE_FOR_Z_HOMING.) - */ -#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN - -// Force the use of the probe for Z-axis homing -//#define USE_PROBE_FOR_Z_HOMING - -/** - * Z_MIN_PROBE_PIN - * - * Define this pin if the probe is not connected to Z_MIN_PIN. - * If not defined the default pin for the selected MOTHERBOARD - * will be used. Most of the time the default is what you want. - * - * - 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. - */ -//#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default - -/** - * 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 - -/** - * Use the nozzle as the probe, as with a conductive - * nozzle system or a piezo-electric smart effector. - */ -//#define NOZZLE_AS_PROBE - -/** - * Z Servo Probe, such as an endstop switch on a rotating arm. - */ -//#define Z_PROBE_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 - -/** - * MagLev V4 probe by MDD - * - * This probe is deployed and activated by powering a built-in electromagnet. - */ -//#define MAGLEV4 -#if ENABLED(MAGLEV4) - //#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output - #define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil -#endif - -/** - * Touch-MI Probe by hotends.fr - * - * This probe is deployed and activated by moving the X-axis to a magnet at the edge of the bed. - * By default, the magnet is assumed to be on the left and activated by a home. If the magnet is - * on the right, enable and set TOUCH_MI_DEPLOY_XPOS to the deploy position. - * - * Also requires: BABYSTEPPING, BABYSTEP_ZPROBE_OFFSET, Z_SAFE_HOMING, - * and a minimum Z_HOMING_HEIGHT of 10. - */ -//#define TOUCH_MI_PROBE -#if ENABLED(TOUCH_MI_PROBE) - #define TOUCH_MI_RETRACT_Z 0.5 // Height at which the probe retracts - //#define TOUCH_MI_DEPLOY_XPOS (X_MAX_BED + 2) // For a magnet on the right side of the bed - //#define TOUCH_MI_MANUAL_DEPLOY // For manual deploy (LCD menu) -#endif - -// 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. - -// A probe deployed by moving the x-axis, such as the Wilson II's rack-and-pinion probe designed by Marty Rice. -//#define RACK_AND_PINION_PROBE -#if ENABLED(RACK_AND_PINION_PROBE) - #define Z_PROBE_DEPLOY_X X_MIN_POS - #define Z_PROBE_RETRACT_X X_MAX_POS -#endif - -// Duet Smart Effector (for delta printers) - https://bit.ly/2ul5U7J -// When the pin is defined you can use M672 to set/reset the probe sensitivity. -//#define DUET_SMART_EFFECTOR -#if ENABLED(DUET_SMART_EFFECTOR) - #define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin -#endif - -/** - * Use StallGuard2 to probe the bed with the nozzle. - * Requires stallGuard-capable Trinamic stepper drivers. - * CAUTION: This can damage machines with Z lead screws. - * Take extreme care when setting up this feature. - */ -//#define SENSORLESS_PROBING - -/** - * Allen key retractable z-probe as seen on many Kossel delta printers - https://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe - * Deploys by touching z-axis belt. Retracts by pushing the probe down. - */ -//#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 { 30.0, DELTA_PRINTABLE_RADIUS, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_DEPLOY_2 { 0.0, DELTA_PRINTABLE_RADIUS, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 - - #define Z_PROBE_ALLEN_KEY_DEPLOY_3 { 0.0, (DELTA_PRINTABLE_RADIUS) * 0.75, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_1 { -64.0, 56.0, 23.0 } // Move the probe into position - #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_2 { -64.0, 56.0, 3.0 } // Push it down - #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 - - #define Z_PROBE_ALLEN_KEY_STOW_3 { -64.0, 56.0, 50.0 } // Move it up to clear - #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_4 { 0.0, 0.0, 50.0 } - #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_FEEDRATE - -#endif // Z_PROBE_ALLEN_KEY - -/** - * Nozzle-to-Probe offsets { X, Y, Z } - * - * X and Y offset - * Use a caliper or ruler to measure the distance from the tip of - * the Nozzle to the center-point of the Probe in the X and Y axes. - * - * Z offset - * - For the Z offset use your best known value and adjust at runtime. - * - Common probes trigger below the nozzle and have negative values for Z offset. - * - Probes triggering above the nozzle height are uncommon but do exist. When using - * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES - * to avoid collisions during probing. - * - * Tune and Adjust - * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc. - * - PROBE_OFFSET_WIZARD (configuration_adv.h) can be used for setting the Z offset. - * - * Assuming the typical work area orientation: - * - Probe to RIGHT of the Nozzle has a Positive X offset - * - Probe to LEFT of the Nozzle has a Negative X offset - * - Probe in BACK of the Nozzle has a Positive Y offset - * - Probe in FRONT of the Nozzle has a Negative Y offset - * - * Some examples: - * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1" - * #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2" - * #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3" - * #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4" - * - * +-- BACK ---+ - * | [+] | - * L | 1 | R <-- Example "1" (right+, back+) - * E | 2 | I <-- Example "2" ( left-, back+) - * F |[-] N [+]| G <-- Nozzle - * T | 3 | H <-- Example "3" (right+, front-) - * | 4 | T <-- Example "4" ( left-, front-) - * | [-] | - * O-- FRONT --+ - */ -#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } - -// Most probes should stay away from the edges of the bed, but -// with NOZZLE_AS_PROBE this can be negative for a wider probing area. -#define PROBING_MARGIN 10 - -// X and Y axis travel speed (mm/min) between probes -#define XY_PROBE_FEEDRATE (133*60) - -// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2) -#define Z_PROBE_FEEDRATE_FAST (4*60) - -// Feedrate (mm/min) for the "accurate" probe of each point -#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2) - -/** - * Probe Activation Switch - * A switch indicating proper deployment, or an optical - * switch triggered when the carriage is near the bed. - */ -//#define PROBE_ACTIVATION_SWITCH -#if ENABLED(PROBE_ACTIVATION_SWITCH) - #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active - //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin -#endif - -/** - * Tare Probe (determine zero-point) prior to each probe. - * Useful for a strain gauge or piezo sensor that needs to factor out - * elements such as cables pulling on the carriage. - */ -//#define PROBE_TARE -#if ENABLED(PROBE_TARE) - #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin - #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before - #define PROBE_TARE_STATE HIGH // State to write pin for tare - //#define PROBE_TARE_PIN PA5 // Override default pin - #if ENABLED(PROBE_ACTIVATION_SWITCH) - //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active - #endif -#endif - -/** - * Probe Enable / Disable - * The probe only provides a triggered signal when enabled. - */ -//#define PROBE_ENABLE_DISABLE -#if ENABLED(PROBE_ENABLE_DISABLE) - //#define PROBE_ENABLE_PIN -1 // Override the default pin here -#endif - -/** - * Multiple Probing - * - * You may get improved results by probing 2 or more times. - * With EXTRA_PROBING the more atypical reading(s) will be disregarded. - * - * A total of 2 does fast/slow probes with a weighted average. - * A total of 3 or more adds more slow probes, taking the average. - */ -//#define MULTIPLE_PROBING 2 -//#define EXTRA_PROBING 1 - -/** - * 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 NOZZLE_TO_PROBE_OFFSET, 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_MULTI_PROBE 5 // Z Clearance between multiple probes -//#define Z_AFTER_PROBING 5 // Z position after probing is done - -#define Z_PROBE_LOW_POINT -2 // Farthest distance below the trigger-point to go before stopping - -// 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 - -// Before deploy/stow pause for user confirmation -//#define PAUSE_BEFORE_DEPLOY_STOW -#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) - //#define PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED // For Manual Deploy Allenkey Probe -#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 -#if ENABLED(PROBING_HEATERS_OFF) - //#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy) - //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) -#endif -//#define PROBING_FANS_OFF // Turn fans off when probing -//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing -//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders) -//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors - -// Require minimum nozzle and/or bed temperature for probing -//#define PREHEAT_BEFORE_PROBING -#if ENABLED(PREHEAT_BEFORE_PROBING) - #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time - #define PROBING_BED_TEMP 50 -#endif - -// 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 -//#define I_ENABLE_ON 0 -//#define J_ENABLE_ON 0 -//#define K_ENABLE_ON 0 - -// Disable axis steppers immediately when they're not being stepped. -// WARNING: When motors turn off there is a chance of losing position accuracy! -#define DISABLE_X false -#define DISABLE_Y false -#define DISABLE_Z false -//#define DISABLE_I false -//#define DISABLE_J false -//#define DISABLE_K false - -// Turn off the display blinking that warns about possible accuracy reduction -//#define DISABLE_REDUCED_ACCURACY_WARNING - -// @section extruder - -#define DISABLE_E false // Disable the extruder when not stepping -#define DISABLE_INACTIVE_EXTRUDER // 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 -//#define INVERT_I_DIR false -//#define INVERT_J_DIR false -//#define INVERT_K_DIR false - -// @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 -#define INVERT_E5_DIR false -#define INVERT_E6_DIR false -#define INVERT_E7_DIR false - -// @section homing - -//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. -//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety. - -/** - * Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled. - * - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed. - * - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle. - */ -#define Z_IDLE_HEIGHT Z_MAX_POS - -//#define Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ... - // Be sure to have this much clearance over your Z_MAX_POS to prevent grinding. - -//#define Z_AFTER_HOMING 10 // (mm) Height to move to after homing Z - -// 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 I_HOME_DIR -1 -//#define J_HOME_DIR -1 -//#define K_HOME_DIR -1 - -// @section machine - -// these values are used in your slicer -#define X_BED_SIZE 227 -#define Y_BED_SIZE 148 - -// Travel limits (mm) after homing, corresponding to endstop positions. -#define X_MIN_POS -115 -#define Y_MIN_POS -84 -#define Z_MIN_POS 0 -#define X_MAX_POS 152 -#define Y_MAX_POS 77 -#define Z_MAX_POS 150 -//#define I_MIN_POS 0 -//#define I_MAX_POS 50 -//#define J_MIN_POS 0 -//#define J_MAX_POS 50 -//#define K_MIN_POS 0 -//#define K_MAX_POS 50 - -/** - * Software Endstops - * - * - Prevent moves outside the set machine bounds. - * - Individual axes can be disabled, if desired. - * - X and Y only apply to Cartesian robots. - * - Use 'M211' to set software endstops on/off or report current state - */ - -// Min software endstops constrain movement within minimum coordinate bounds -#define MIN_SOFTWARE_ENDSTOPS -#if ENABLED(MIN_SOFTWARE_ENDSTOPS) - #define MIN_SOFTWARE_ENDSTOP_X - #define MIN_SOFTWARE_ENDSTOP_Y - #define MIN_SOFTWARE_ENDSTOP_Z - #define MIN_SOFTWARE_ENDSTOP_I - #define MIN_SOFTWARE_ENDSTOP_J - #define MIN_SOFTWARE_ENDSTOP_K -#endif - -// Max software endstops constrain movement within maximum coordinate bounds -#define MAX_SOFTWARE_ENDSTOPS -#if ENABLED(MAX_SOFTWARE_ENDSTOPS) - #define MAX_SOFTWARE_ENDSTOP_X - #define MAX_SOFTWARE_ENDSTOP_Y - #define MAX_SOFTWARE_ENDSTOP_Z - #define MAX_SOFTWARE_ENDSTOP_I - #define MAX_SOFTWARE_ENDSTOP_J - #define MAX_SOFTWARE_ENDSTOP_K -#endif - -#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) - //#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD -#endif - -/** - * Filament Runout Sensors - * Mechanical or opto endstops are used to check for the presence of filament. - * - * IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running. - * Marlin knows a print job is running when: - * 1. Running a print job from media started with M24. - * 2. The Print Job Timer has been started with M75. - * 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled. - * - * RAMPS-based boards use SERVO3_PIN for the first runout sensor. - * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. - */ -//#define FILAMENT_RUNOUT_SENSOR -#if ENABLED(FILAMENT_RUNOUT_SENSOR) - #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. - #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. - - #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. - #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. - //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. - //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder. - // This is automatically enabled for MIXING_EXTRUDERs. - - // Override individually if the runout sensors vary - //#define FIL_RUNOUT1_STATE LOW - //#define FIL_RUNOUT1_PULLUP - //#define FIL_RUNOUT1_PULLDOWN - - //#define FIL_RUNOUT2_STATE LOW - //#define FIL_RUNOUT2_PULLUP - //#define FIL_RUNOUT2_PULLDOWN - - //#define FIL_RUNOUT3_STATE LOW - //#define FIL_RUNOUT3_PULLUP - //#define FIL_RUNOUT3_PULLDOWN - - //#define FIL_RUNOUT4_STATE LOW - //#define FIL_RUNOUT4_PULLUP - //#define FIL_RUNOUT4_PULLDOWN - - //#define FIL_RUNOUT5_STATE LOW - //#define FIL_RUNOUT5_PULLUP - //#define FIL_RUNOUT5_PULLDOWN - - //#define FIL_RUNOUT6_STATE LOW - //#define FIL_RUNOUT6_PULLUP - //#define FIL_RUNOUT6_PULLDOWN - - //#define FIL_RUNOUT7_STATE LOW - //#define FIL_RUNOUT7_PULLUP - //#define FIL_RUNOUT7_PULLDOWN - - //#define FIL_RUNOUT8_STATE LOW - //#define FIL_RUNOUT8_PULLUP - //#define FIL_RUNOUT8_PULLDOWN - - // Commands to execute on filament runout. - // With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c") - // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply. - #define FILAMENT_RUNOUT_SCRIPT "M600" - - // After a runout is detected, continue printing this length of filament - // before executing the runout script. Useful for a sensor at the end of - // a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead. - //#define FILAMENT_RUNOUT_DISTANCE_MM 25 - - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - // Enable this option to use an encoder disc that toggles the runout pin - // as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM - // large enough to avoid false positives.) - //#define FILAMENT_MOTION_SENSOR - #endif -#endif - -//=========================================================================== -//=============================== Bed Leveling ============================== -//=========================================================================== -// @section calibrate - -/** - * 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. - * - * - 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 - -/** - * Normally G28 leaves leveling disabled on completion. Enable one of - * these options to restore the prior leveling state or to always enable - * leveling immediately after G28. - */ -//#define RESTORE_LEVELING_AFTER_G28 -//#define ENABLE_LEVELING_AFTER_G28 - -/** - * Auto-leveling needs preheating - */ -//#define PREHEAT_BEFORE_LEVELING -#if ENABLED(PREHEAT_BEFORE_LEVELING) - #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time - #define LEVELING_BED_TEMP 50 -#endif - -/** - * 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 ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY) - // Set a height for the start of manual adjustment - #define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height -#endif - -#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, 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 - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. - #endif - - // For Cartesian machines, instead of dividing moves on mesh boundaries, - // split up moves into short segments like a Delta. This follows the - // contours of the bed more closely than edge-to-edge straight moves. - #define SEGMENT_LEVELED_MOVES - #define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one) - - /** - * Enable the G26 Mesh Validation Pattern tool. - */ - //#define G26_MESH_VALIDATION - #if ENABLED(G26_MESH_VALIDATION) - #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. - #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. - #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26. - #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26. - #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves. - #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves. - #define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements. - #endif - -#endif - -#if EITHER(AUTO_BED_LEVELING_LINEAR, 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 - - // 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_UBL) - - //=========================================================================== - //========================= Unified Bed Leveling ============================ - //=========================================================================== - - //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh - - #define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed - #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_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points - - #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle - #define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500 - - //#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used - // as the Z-Height correction value. - - //#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh - -#elif ENABLED(MESH_BED_LEVELING) - - //=========================================================================== - //=================================== Mesh ================================== - //=========================================================================== - - #define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed - #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 - -/** - * Add a bed leveling sub-menu for ABL or MBL. - * Include a guided procedure if manual probing is enabled. - */ -//#define LCD_BED_LEVELING - -#if ENABLED(LCD_BED_LEVELING) - #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. - #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment - //#define MESH_EDIT_MENU // Add a menu to edit mesh points -#endif - -// Add a menu item to move between bed corners for manual bed adjustment -//#define LCD_BED_TRAMMING - -#if ENABLED(LCD_BED_TRAMMING) - #define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets - #define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points - #define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points - //#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner - //#define BED_TRAMMING_USE_PROBE - #if ENABLED(BED_TRAMMING_USE_PROBE) - #define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm) - #define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify - //#define BED_TRAMMING_AUDIO_FEEDBACK - #endif - - /** - * Corner Leveling Order - * - * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge. - * - * LF Left-Front RF Right-Front - * LB Left-Back RB Right-Back - * - * Examples: - * - * Default {LF,RB,LB,RF} {LF,RF} {LB,LF} - * LB --------- RB LB --------- RB LB --------- RB LB --------- RB - * | 4 3 | | 3 2 | | <3> | | 1 | - * | | | | | | | <3>| - * | 1 2 | | 1 4 | | 1 2 | | 2 | - * LF --------- RF LF --------- RF LF --------- RF LF --------- RF - */ - #define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB } -#endif - -/** - * 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 -//#define MANUAL_I_HOME_POS 0 -//#define MANUAL_J_HOME_POS 0 -//#define MANUAL_K_HOME_POS 0 - -/** - * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. - * - * - Moves the Z probe (or nozzle) to a defined XY point before Z homing. - * - Allows Z homing only when XY positions are known and trusted. - * - If stepper drivers sleep, XY homing may be required again before Z homing. - */ -//#define Z_SAFE_HOMING - -#if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT X_CENTER // X point for Z homing - #define Z_SAFE_HOMING_Y_POINT Y_CENTER // Y point for Z homing -#endif - -// Homing speeds (mm/min) -#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) } - -// Validate that endstops are triggered on homing moves -#define VALIDATE_HOMING_ENDSTOPS - -// @section calibrate - -/** - * Bed Skew Compensation - * - * This feature corrects for misalignment in the XYZ axes. - * - * Take the following steps to get the bed skew in the XY plane: - * 1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185) - * 2. For XY_DIAG_AC measure the diagonal A to C - * 3. For XY_DIAG_BD measure the diagonal B to D - * 4. For XY_SIDE_AD measure the edge A to D - * - * Marlin automatically computes skew factors from these measurements. - * Skew factors may also be computed and set manually: - * - * - Compute AB : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2 - * - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD))) - * - * If desired, follow the same procedure for XZ and YZ. - * Use these diagrams for reference: - * - * Y Z Z - * ^ B-------C ^ B-------C ^ B-------C - * | / / | / / | / / - * | / / | / / | / / - * | A-------D | A-------D | A-------D - * +-------------->X +-------------->X +-------------->Y - * XY_SKEW_FACTOR XZ_SKEW_FACTOR YZ_SKEW_FACTOR - */ -//#define SKEW_CORRECTION - -#if ENABLED(SKEW_CORRECTION) - // Input all length measurements here: - #define XY_DIAG_AC 282.8427124746 - #define XY_DIAG_BD 282.8427124746 - #define XY_SIDE_AD 200 - - // Or, set the default skew factors directly here - // to override the above measurements: - #define XY_SKEW_FACTOR 0.0 - - //#define SKEW_CORRECTION_FOR_Z - #if ENABLED(SKEW_CORRECTION_FOR_Z) - #define XZ_DIAG_AC 282.8427124746 - #define XZ_DIAG_BD 282.8427124746 - #define YZ_DIAG_AC 282.8427124746 - #define YZ_DIAG_BD 282.8427124746 - #define YZ_SIDE_AD 200 - #define XZ_SKEW_FACTOR 0.0 - #define YZ_SKEW_FACTOR 0.0 - #endif - - // Enable this option for M852 to set skew at runtime - //#define SKEW_CORRECTION_GCODE -#endif - -//============================================================================= -//============================= Additional Features =========================== -//============================================================================= - -// @section extras - -/** - * EEPROM - * - * Persistent storage to preserve configurable settings across reboots. - * - * M500 - Store settings to EEPROM. - * M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes) - * M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.) - */ -#define EEPROM_SETTINGS // Persistent storage with M500 and M501 -//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release! -#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. -#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load -#if ENABLED(EEPROM_SETTINGS) - #define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. - //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build. -#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. -#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating - -// -// G20/G21 Inch mode support -// -//#define INCH_MODE_SUPPORT - -// -// M149 Set temperature units support -// -//#define TEMPERATURE_UNITS_SUPPORT - -// @section temperature - -// -// Preheat Constants - Up to 6 are supported without changes -// -#define PREHEAT_1_LABEL "PLA" -#define PREHEAT_1_TEMP_HOTEND 200 -#define PREHEAT_1_TEMP_BED 50 -#define PREHEAT_1_TEMP_CHAMBER 35 -#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 - -#define PREHEAT_2_LABEL "ABS" -#define PREHEAT_2_TEMP_HOTEND 220 -#define PREHEAT_2_TEMP_BED 100 -#define PREHEAT_2_TEMP_CHAMBER 35 -#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 - -/** - * Nozzle Park - * - * 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_raise } - #define NOZZLE_PARK_POINT { (X_MAX_POS - 2), (Y_MAX_POS - 2), 20 } - #define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X - #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance - #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) - #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) -#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 for each tool as { { X, Y, Z }, { X, Y, Z } } - // Dual hotend system may use { { -20, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }, { 420, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }} - #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 - - // Move the nozzle to the initial position after cleaning - #define NOZZLE_CLEAN_GOBACK - - // For a purge/clean station that's always at the gantry height (thus no Z move) - //#define NOZZLE_CLEAN_NO_Z - - // For a purge/clean station mounted on the X axis - //#define NOZZLE_CLEAN_NO_Y - - // Require a minimum hotend temperature for cleaning - #define NOZZLE_CLEAN_MIN_TEMP 170 - //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe - - // Explicit wipe G-code script applies to a G12 with no arguments. - //#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0" - -#endif - -/** - * Print Job Timer - * - * Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191. - * The print job timer will only be stopped if the bed/chamber target temp is - * below BED_MINTEMP/CHAMBER_MINTEMP. - * - * M104 (hotend, no wait) - high temp = none, low temp = stop timer - * M109 (hotend, wait) - high temp = start timer, low temp = stop timer - * M140 (bed, no wait) - high temp = none, low temp = stop timer - * M190 (bed, wait) - high temp = start timer, low temp = none - * M141 (chamber, no wait) - high temp = none, low temp = stop timer - * M191 (chamber, wait) - high temp = start timer, low temp = none - * - * For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2. - * For M140/M190, high temp is anything over BED_MINTEMP. - * For M141/M191, high temp is anything over CHAMBER_MINTEMP. - * - * 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 -#if ENABLED(PRINTCOUNTER) - #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print -#endif - -/** - * Password - * - * Set a numerical password for the printer which can be requested: - * - * - When the printer boots up - * - Upon opening the 'Print from Media' Menu - * - When SD printing is completed or aborted - * - * The following G-codes can be used: - * - * M510 - Lock Printer. Blocks all commands except M511. - * M511 - Unlock Printer. - * M512 - Set, Change and Remove Password. - * - * If you forget the password and get locked out you'll need to re-flash - * the firmware with the feature disabled, reset EEPROM, and (optionally) - * re-flash the firmware again with this feature enabled. - */ -//#define PASSWORD_FEATURE -#if ENABLED(PASSWORD_FEATURE) - #define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended - #define PASSWORD_ON_STARTUP - #define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P command. Disable to prevent brute-force attack. - #define PASSWORD_CHANGE_GCODE // Change the password with M512 P S. - //#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent gcodes from running - //#define PASSWORD_AFTER_SD_PRINT_END - //#define PASSWORD_AFTER_SD_PRINT_ABORT - //#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE -#endif - -//============================================================================= -//============================= LCD and SD support ============================ -//============================================================================= - -// @section lcd - -/** - * LCD LANGUAGE - * - * Select the language to display on the LCD. These languages are available: - * - * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it, - * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW - * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek (Greece)', 'el_CY':'Greek (Cyprus)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' } - */ -#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 https://marlinfw.org/docs/development/lcd_language.html - * - * :['JAPANESE', 'WESTERN', 'CYRILLIC'] - */ -#define DISPLAY_CHARSET_HD44780 JAPANESE - -/** - * Info Screen Style (0:Classic, 1:Průša) - * - * :[0:'Classic', 1:'Průša'] - */ -#define LCD_INFO_SCREEN_STYLE 0 - -/** - * 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: ENABLE CRC - * - * Use CRC checks and retries on the SD communication. - */ -#define SD_CHECK_AND_RETRY - -/** - * LCD Menu Items - * - * Disable all menus and only display the Status Screen, or - * just remove some extraneous menu items to recover space. - */ -//#define NO_LCD_MENUS -//#define SLIM_LCD_MENUS - -// -// 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 - -// -// This option reverses the encoder direction for Select Screen. -// -// If CLOCKWISE normally moves LEFT this makes it go RIGHT. -// If CLOCKWISE normally moves RIGHT this makes it go LEFT. -// -//#define REVERSE_SELECT_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 -//#define INDIVIDUAL_AXIS_HOMING_SUBMENU - -// -// 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 2 -//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 - -//============================================================================= -//======================== LCD / Controller Selection ========================= -//======================== (Character-based LCDs) ========================= -//============================================================================= - -// -// RepRapDiscount Smart Controller. -// https://reprap.org/wiki/RepRapDiscount_Smart_Controller -// -// Note: Usually sold with a white PCB. -// -//#define REPRAP_DISCOUNT_SMART_CONTROLLER - -// -// GT2560 (YHCB2004) LCD Display -// -// Requires Testato, Koepel softwarewire library and -// Andriy Golovnya's LiquidCrystal_AIP31068 library. -// -//#define YHCB2004 - -// -// Original RADDS LCD Display+Encoder+SDCardReader -// http://doku.radds.org/dokumentation/lcd-display/ -// -//#define RADDS_DISPLAY - -// -// ULTIMAKER Controller. -// -//#define ULTIMAKERCONTROLLER - -// -// ULTIPANEL as seen on Thingiverse. -// -//#define ULTIPANEL - -// -// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) -// https://reprap.org/wiki/PanelOne -// -//#define PANEL_ONE - -// -// GADGETS3D G3D LCD/SD Controller -// https://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel -// -// Note: Usually sold with a blue PCB. -// -//#define G3D_PANEL - -// -// RigidBot Panel V1.0 -// http://www.inventapart.com/ -// -//#define RIGIDBOT_PANEL - -// -// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller -// https://www.aliexpress.com/item/32765887917.html -// -//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 - -// -// ANET and Tronxy 20x4 Controller -// -//#define ZONESTAR_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. - // This is a LCD2004 display with 5 analog buttons. - -// -// Generic 16x2, 16x4, 20x2, or 20x4 character-based LCD. -// -//#define ULTRA_LCD - -//============================================================================= -//======================== LCD / Controller Selection ========================= -//===================== (I2C and Shift-Register LCDs) ===================== -//============================================================================= - -// -// 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 (YwRobot) LCD Displays -// -// These require F.Malpartida's LiquidCrystal_I2C library -// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home -// -//#define LCD_SAINSMART_I2C_1602 -//#define LCD_SAINSMART_I2C_2004 - -// -// 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 - -// -// CONTROLLER TYPE: Shift register panels -// - -// -// 2-wire Non-latching LCD SR from https://goo.gl/aJJ4sH -// LCD configuration: https://reprap.org/wiki/SAV_3D_LCD -// -//#define SAV_3DLCD - -// -// 3-wire SR LCD with strobe using 74HC4094 -// https://github.com/mikeshub/SailfishLCD -// Uses the code directly from Sailfish -// -//#define FF_INTERFACEBOARD - -// -// TFT GLCD Panel with Marlin UI -// Panel connected to main board by SPI or I2C interface. -// See https://github.com/Serhiy-K/TFTGLCDAdapter -// -//#define TFTGLCD_PANEL_SPI -//#define TFTGLCD_PANEL_I2C - -//============================================================================= -//======================= LCD / Controller Selection ======================= -//========================= (Graphical LCDs) ======================== -//============================================================================= - -// -// CONTROLLER TYPE: Graphical 128x64 (DOGM) -// -// IMPORTANT: The U8glib library is required for Graphical Display! -// https://github.com/olikraus/U8glib_Arduino -// -// NOTE: If the LCD is unresponsive you may need to reverse the plugs. -// - -// -// RepRapDiscount FULL GRAPHIC Smart Controller -// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller -// -//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER - -// -// K.3D Full Graphic Smart Controller -// -//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER - -// -// 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 -// https://www.panucatt.com -// -//#define VIKI2 -//#define miniVIKI - -// -// Alfawise Ex8 printer LCD marked as WYH L12864 COG -// -//#define WYH_L12864 - -// -// MakerLab Mini Panel with graphic -// controller and SD support - https://reprap.org/wiki/Mini_panel -// -//#define MINIPANEL - -// -// MaKr3d Makr-Panel with graphic controller and SD support. -// https://reprap.org/wiki/MaKr3d_MaKrPanel -// -//#define MAKRPANEL - -// -// Adafruit ST7565 Full Graphic Controller. -// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ -// -//#define ELB_FULL_GRAPHIC_CONTROLLER - -// -// 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 - -// -// LCD for Melzi Card with Graphical LCD -// -//#define LCD_FOR_MELZI - -// -// Original Ulticontroller from Ultimaker 2 printer with SSD1309 I2C display and encoder -// https://github.com/Ultimaker/Ultimaker2/tree/master/1249_Ulticontroller_Board_(x1) -// -//#define ULTI_CONTROLLER - -// -// MKS MINI12864 with graphic controller and SD support -// https://reprap.org/wiki/MKS_MINI_12864 -// -//#define MKS_MINI_12864 - -// -// MKS MINI12864 V3 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. -// -#define MKS_MINI_12864_V3 - -// -// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout. -// https://www.aliexpress.com/item/33018110072.html -// -//#define MKS_LCD12864A -//#define MKS_LCD12864B - -// -// FYSETC variant of the MINI12864 graphic controller with SD support -// https://wiki.fysetc.com/Mini12864_Panel/ -// -//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default -//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on) -//#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight -//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight -//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight. - -// -// BigTreeTech Mini 12864 V1.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. -// -//#define BTT_MINI_12864_V1 - -// -// Factory display for Creality CR-10 -// https://www.aliexpress.com/item/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 - -// -// Ender-2 OEM display, a variant of the MKS_MINI_12864 -// -//#define ENDER2_STOCKDISPLAY - -// -// ANET and Tronxy Graphical Controller -// -// 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). Enable one of these. -// -//#define ANET_FULL_GRAPHICS_LCD -//#define ANET_FULL_GRAPHICS_LCD_ALT_WIRING - -// -// AZSMZ 12864 LCD with SD -// https://www.aliexpress.com/item/32837222770.html -// -//#define AZSMZ_12864 - -// -// Silvergate GLCD controller -// https://github.com/android444/Silvergate -// -//#define SILVER_GATE_GLCD_CONTROLLER - -//============================================================================= -//============================== OLED Displays ============================== -//============================================================================= - -// -// 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 - -// -// TinyBoy2 128x64 OLED / Encoder Panel -// -//#define OLED_PANEL_TINYBOY2 - -// -// MKS OLED 1.3" 128×64 Full Graphics Controller -// https://reprap.org/wiki/MKS_12864OLED -// -// Tiny, but very sharp OLED display -// -//#define MKS_12864OLED // Uses the SH1106 controller (default) -//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller - -// -// Zonestar OLED 128×64 Full Graphics Controller -// -//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller -//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default) -//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller - -// -// Einstart S OLED SSD1306 -// -//#define U8GLIB_SH1106_EINSTART - -// -// Overlord OLED display/controller with i2c buzzer and LEDs -// -//#define OVERLORD_OLED - -// -// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB -// Where to find : https://www.aliexpress.com/item/4000345255731.html -//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller - -// -// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller -// -//#define K3D_242_OLED_CONTROLLER // Software SPI - -//============================================================================= -//========================== Extensible UI Displays =========================== -//============================================================================= - -/** - * DGUS Touch Display with DWIN OS. (Choose one.) - * ORIGIN : https://www.aliexpress.com/item/32993409517.html - * FYSETC : https://www.aliexpress.com/item/32961471929.html - * MKS : https://www.aliexpress.com/item/1005002008179262.html - * - * Flash display with DGUS Displays for Marlin: - * - Format the SD card to FAT32 with an allocation size of 4kb. - * - Download files as specified for your type of display. - * - Plug the microSD card into the back of the display. - * - Boot the display and wait for the update to complete. - * - * ORIGIN (Marlin DWIN_SET) - * - Download https://github.com/coldtobi/Marlin_DGUS_Resources - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * FYSETC (Supplier default) - * - Download https://github.com/FYSETC/FYSTLCD-2.0 - * - Copy the downloaded SCREEN folder to the SD card. - * - * HIPRECY (Supplier default) - * - Download https://github.com/HiPrecy/Touch-Lcd-LEO - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * MKS (MKS-H43) (Supplier default) - * - Download https://github.com/makerbase-mks/MKS-H43 - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * RELOADED (T5UID1) - * - Download https://github.com/Desuuuu/DGUS-reloaded/releases - * - Copy the downloaded DWIN_SET folder to the SD card. - */ -//#define DGUS_LCD_UI_ORIGIN -//#define DGUS_LCD_UI_FYSETC -//#define DGUS_LCD_UI_HIPRECY -//#define DGUS_LCD_UI_MKS -//#define DGUS_LCD_UI_RELOADED -#if ENABLED(DGUS_LCD_UI_MKS) - #define USE_MKS_GREEN_UI -#endif - -// -// Touch-screen LCD for Malyan M200/M300 printers -// -//#define MALYAN_LCD - -// -// Touch UI for FTDI EVE (FT800/FT810) displays -// See Configuration_adv.h for all configuration options. -// -//#define TOUCH_UI_FTDI_EVE - -// -// Touch-screen LCD for Anycubic printers -// -//#define ANYCUBIC_LCD_I3MEGA -//#define ANYCUBIC_LCD_CHIRON -#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) - //#define ANYCUBIC_LCD_DEBUG -#endif - -// -// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028 -// -//#define NEXTION_TFT - -// -// Third-party or vendor-customized controller interfaces. -// Sources should be installed in 'src/lcd/extui'. -// -//#define EXTENSIBLE_UI - -#if ENABLED(EXTENSIBLE_UI) - //#define EXTUI_LOCAL_BEEPER // Enables use of local Beeper pin with external display -#endif - -//============================================================================= -//=============================== Graphical TFTs ============================== -//============================================================================= - -/** - * Specific TFT Model Presets. Enable one of the following options - * or enable TFT_GENERIC and set sub-options. - */ - -// -// 480x320, 3.5", SPI Display with Rotary Encoder from MKS -// Usually paired with MKS Robin Nano V2 & V3 -// -//#define MKS_TS35_V2_0 - -// -// 320x240, 2.4", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT24 - -// -// 320x240, 2.8", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT28 - -// -// 320x240, 3.2", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT32 - -// -// 480x320, 3.5", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT35 - -// -// 480x272, 4.3", FSMC Display From MKS -// -//#define MKS_ROBIN_TFT43 - -// -// 320x240, 3.2", FSMC Display From MKS -// Usually paired with MKS Robin -// -//#define MKS_ROBIN_TFT_V1_1R - -// -// 480x320, 3.5", FSMC Stock Display from TronxXY -// -//#define TFT_TRONXY_X5SA - -// -// 480x320, 3.5", FSMC Stock Display from AnyCubic -// -//#define ANYCUBIC_TFT35 - -// -// 320x240, 2.8", FSMC Stock Display from Longer/Alfawise -// -//#define LONGER_LK_TFT28 - -// -// 320x240, 2.8", FSMC Stock Display from ET4 -// -//#define ANET_ET4_TFT28 - -// -// 480x320, 3.5", FSMC Stock Display from ET5 -// -//#define ANET_ET5_TFT35 - -// -// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU-BX -// -//#define BIQU_BX_TFT70 - -// -// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series -// -//#define BTT_TFT35_SPI_V1_0 - -// -// Generic TFT with detailed options -// -//#define TFT_GENERIC -#if ENABLED(TFT_GENERIC) - // :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ] - #define TFT_DRIVER AUTO - - // Interface. Enable one of the following options: - //#define TFT_INTERFACE_FSMC - //#define TFT_INTERFACE_SPI - - // TFT Resolution. Enable one of the following options: - //#define TFT_RES_320x240 - //#define TFT_RES_480x272 - //#define TFT_RES_480x320 - //#define TFT_RES_1024x600 -#endif - -/** - * TFT UI - User Interface Selection. Enable one of the following options: - * - * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled - * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities - * TFT_LVGL_UI - A Modern UI using LVGL - * - * For LVGL_UI also copy the 'assets' folder from the build directory to the - * root of your SD card, together with the compiled firmware. - */ -//#define TFT_CLASSIC_UI -//#define TFT_COLOR_UI -//#define TFT_LVGL_UI - -#if ENABLED(TFT_LVGL_UI) - //#define MKS_WIFI_MODULE // MKS WiFi module -#endif - -/** - * TFT Rotation. Set to one of the following values: - * - * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y, - * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y, - * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y, - * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION - */ -//#define TFT_ROTATION TFT_NO_ROTATION - -//============================================================================= -//============================ Other Controllers ============================ -//============================================================================= - -// -// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder. -// -//#define DWIN_CREALITY_LCD // Creality UI -//#define DWIN_LCD_PROUI // Pro UI by MRiscoC -//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers -//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation) -//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation) - -// -// Touch Screen Settings -// -//#define TOUCH_SCREEN -#if ENABLED(TOUCH_SCREEN) - #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens - #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus - - //#define TOUCH_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn) - - #define TOUCH_SCREEN_CALIBRATION - - //#define TOUCH_CALIBRATION_X 12316 - //#define TOUCH_CALIBRATION_Y -8981 - //#define TOUCH_OFFSET_X -43 - //#define TOUCH_OFFSET_Y 257 - //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE - - #if BOTH(TOUCH_SCREEN_CALIBRATION, EEPROM_SETTINGS) - #define TOUCH_CALIBRATION_AUTO_SAVE // Auto save successful calibration values to EEPROM - #endif - - #if ENABLED(TFT_COLOR_UI) - //#define SINGLE_TOUCH_NAVIGATION - #endif -#endif - -// -// RepRapWorld REPRAPWORLD_KEYPAD v1.1 -// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/ -// -//#define REPRAPWORLD_KEYPAD -//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press - -// -// EasyThreeD ET-4000+ with button input and status LED -// -//#define EASYTHREED_UI - -//============================================================================= -//=============================== Extra Features ============================== -//============================================================================= - -// @section extras - -// Set number of user-controlled fans. Disable to use all board-defined fans. -// :[1,2,3,4,5,6,7,8] -//#define NUM_M106_FANS 1 - -// 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. -// :[0,1,2,3,4,5,6,7] -#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 - -// Support for the BariCUDA Paste Extruder -//#define BARICUDA - -// Support for BlinkM/CyzRgb -//#define BLINKM - -// Support for PCA9632 PWM LED driver -//#define PCA9632 - -// Support for PCA9533 PWM LED driver -#define PCA9533 - -/** - * 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 an overall brightness parameter is also available. - * - * *** CAUTION *** - * LED Strips require a MOSFET Chip between PWM lines and LEDs, - * as the Arduino cannot handle the current the LEDs will require. - * Failure to follow this precaution can destroy your Arduino! - * NOTE: A separate 5V power supply is required! The NeoPixel LED needs - * more current than the Arduino 5V linear regulator can produce. - * *** CAUTION *** - * - * LED Type. Enable only one of the following two options. - */ -//#define RGB_LED -//#define RGBW_LED - -#if EITHER(RGB_LED, 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_RGBW, NEO_GRB, NEO_RBG, etc. - // See https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h - //#define NEOPIXEL_PIN 4 // LED driving pin - //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE - //#define NEOPIXEL2_PIN 5 - #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.) - #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) - //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup - - // Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ... - //#define NEOPIXEL2_SEPARATE - #if ENABLED(NEOPIXEL2_SEPARATE) - #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip - #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) - #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup - #else - //#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel - #endif - - // Use some of the NeoPixel LEDs for static (background) lighting - //#define NEOPIXEL_BKGD_INDEX_FIRST 0 // Index of the first background LED - //#define NEOPIXEL_BKGD_INDEX_LAST 5 // Index of the last background LED - //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W - //#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off -#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 ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) - #define PRINTER_EVENT_LEDS -#endif - -/** - * Number of servos - * - * For some servo-related options NUM_SERVOS will be set automatically. - * Set this manually if there are extra servos needing manual control. - * Set to 0 to turn off servo support. - */ -//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands - -// (ms) Delay 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 } - -// Only power servos during movement, otherwise leave off to prevent jitter -//#define DEACTIVATE_SERVOS_AFTER_MOVE - -// Edit servo angles with M281 and save to EEPROM with M500 -//#define EDITABLE_SERVO_ANGLES - -// Disable servo with M282 to reduce power consumption, noise, and heat when not in use -//#define SERVO_DETACH_GCODE diff --git a/Configuration_adv.h b/Configuration_adv.h deleted file mode 100644 index 87ad426..0000000 --- a/Configuration_adv.h +++ /dev/null @@ -1,4354 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CONFIG_EXAMPLES_DIR "FlashForge/CreatorPro" - -/** - * 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 - */ -#define CONFIGURATION_ADV_H_VERSION 02000905 - -//=========================================================================== -//============================= Thermal Settings ============================ -//=========================================================================== -// @section temperature - -/** - * Thermocouple sensors are quite sensitive to noise. Any noise induced in - * the sensor wires, such as by stepper motor wires run in parallel to them, - * may result in the thermocouple sensor reporting spurious errors. This - * value is the number of errors which can occur in a row before the error - * is reported. This allows us to ignore intermittent error conditions while - * still detecting an actual failure, which should result in a continuous - * stream of errors from the sensor. - * - * Set this value to 0 to fail on the first error to occur. - */ -#define THERMOCOUPLE_MAX_ERRORS 15 - -// -// Custom Thermistor 1000 parameters -// -#if TEMP_SENSOR_0 == 1000 - #define HOTEND0_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND0_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND0_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_1 == 1000 - #define HOTEND1_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND1_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND1_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_2 == 1000 - #define HOTEND2_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND2_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND2_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_3 == 1000 - #define HOTEND3_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND3_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND3_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_4 == 1000 - #define HOTEND4_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND4_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND4_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_5 == 1000 - #define HOTEND5_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND5_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND5_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_6 == 1000 - #define HOTEND6_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND6_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND6_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_7 == 1000 - #define HOTEND7_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND7_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND7_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_BED == 1000 - #define BED_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define BED_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define BED_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_CHAMBER == 1000 - #define CHAMBER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define CHAMBER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define CHAMBER_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_COOLER == 1000 - #define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define COOLER_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_PROBE == 1000 - #define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define PROBE_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_BOARD == 1000 - #define BOARD_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define BOARD_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define BOARD_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_REDUNDANT == 1000 - #define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define REDUNDANT_BETA 3950 // Beta value -#endif - -/** - * Thermocouple Options — for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5). - */ -//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. -//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. -//#define MAX31865_SENSOR_WIRES_1 2 - -//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. -//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. - -//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature. -//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals. -//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439). - -//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. -//#define MAX31865_WIRE_OHMS_1 0.0f - -/** - * Hephestos 2 24V heated bed upgrade kit. - * https://store.bq.com/en/heated-bed-kit-hephestos2 - */ -//#define HEPHESTOS2_HEATED_BED_KIT -#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) - #undef TEMP_SENSOR_BED - #define TEMP_SENSOR_BED 70 - #define HEATER_BED_INVERTING true -#endif - -// -// Heated Bed Bang-Bang options -// -#if DISABLED(PIDTEMPBED) - #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control - #if ENABLED(BED_LIMIT_SWITCHING) - #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS - #endif -#endif - -// -// Heated Chamber options -// -#if DISABLED(PIDTEMPCHAMBER) - #define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control - #if ENABLED(CHAMBER_LIMIT_SWITCHING) - #define CHAMBER_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS - #endif -#endif - -#if TEMP_SENSOR_CHAMBER - //#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug) - //#define HEATER_CHAMBER_INVERTING false - //#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug) - - //#define CHAMBER_FAN // Enable a fan on the chamber - #if ENABLED(CHAMBER_FAN) - //#define CHAMBER_FAN_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan) - #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on. - #if CHAMBER_FAN_MODE == 0 - #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) - #elif CHAMBER_FAN_MODE == 1 - #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target - #elif CHAMBER_FAN_MODE == 2 - #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target - #elif CHAMBER_FAN_MODE == 3 - #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255) - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target - #endif - #endif - - //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber - #if ENABLED(CHAMBER_VENT) - #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo - #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber - #define LOW_EXCESS_HEAT_LIMIT 3 - #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 - #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 - #endif -#endif - -// -// Laser Cooler options -// -#if TEMP_SENSOR_COOLER - #define COOLER_MINTEMP 8 // (°C) - #define COOLER_MAXTEMP 26 // (°C) - #define COOLER_DEFAULT_TEMP 16 // (°C) - #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target - #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay) - #define COOLER_INVERTING false - #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required. - #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc. - #define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g. - #if ENABLED(COOLER_FAN) - #define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target - #define COOLER_FAN_FACTOR 25 // PWM increase per °C above target - #endif -#endif - -// -// Motherboard Sensor options -// -#if TEMP_SENSOR_BOARD - #define THERMAL_PROTECTION_BOARD // Halt the printer if the board sensor leaves the temp range below. - #define BOARD_MINTEMP 8 // (°C) - #define BOARD_MAXTEMP 70 // (°C) - #ifndef TEMP_BOARD_PIN - //#define TEMP_BOARD_PIN -1 // Board temp sensor pin, if not set in pins file. - #endif -#endif - -/** - * Thermal Protection provides additional protection to your printer from damage - * and fire. Marlin always includes safe min and max temperature ranges which - * protect against a broken or disconnected thermistor wire. - * - * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the 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 - - //#define ADAPTIVE_FAN_SLOWING // Slow part cooling fan if temperature drops - #if BOTH(ADAPTIVE_FAN_SLOWING, PIDTEMP) - //#define NO_FAN_SLOWING_IN_PID_TUNING // Don't slow fan speed during M303 - #endif - - /** - * Whenever an M104, M109, or M303 increases the target temperature, the - * firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature - * hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and - * requires a hard reset. This test restarts with any M104/M109/M303, 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 set - * 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 - - /** - * As described above, except for the bed (M140/M190/M303). - */ - #define WATCH_BED_TEMP_PERIOD 60 // Seconds - #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius -#endif - -/** - * Thermal Protection parameters for the heated chamber. - */ -#if ENABLED(THERMAL_PROTECTION_CHAMBER) - #define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // Seconds - #define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // Degrees Celsius - - /** - * Heated chamber watch settings (M141/M191). - */ - #define WATCH_CHAMBER_TEMP_PERIOD 60 // Seconds - #define WATCH_CHAMBER_TEMP_INCREASE 2 // Degrees Celsius -#endif - -/** - * Thermal Protection parameters for the laser cooler. - */ -#if ENABLED(THERMAL_PROTECTION_COOLER) - #define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds - #define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius - - /** - * Laser cooling watch settings (M143/M193). - */ - #define WATCH_COOLER_TEMP_PERIOD 60 // Seconds - #define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius -#endif - -#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) - /** - * Thermal Protection Variance Monitor - EXPERIMENTAL. - * Kill the machine on a stuck temperature sensor. Disable if you get false positives. - */ - //#define THERMAL_PROTECTION_VARIANCE_MONITOR // Detect a sensor malfunction preventing temperature updates -#endif - -#if ENABLED(PIDTEMP) - // Add an experimental additional term to the heater power, proportional to the extrusion speed. - // A well-chosen Kc value should add just enough power to melt the increased material volume. - //#define PID_EXTRUSION_SCALING - #if ENABLED(PID_EXTRUSION_SCALING) - #define DEFAULT_Kc (100) // heating power = Kc * e_speed - #define LPQ_MAX_LEN 50 - #endif - - /** - * Add an experimental additional term to the heater power, proportional to the fan speed. - * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan. - * You can either just add a constant compensation with the DEFAULT_Kf value - * or follow the instruction below to get speed-dependent compensation. - * - * Constant compensation (use only with fanspeeds of 0% and 100%) - * --------------------------------------------------------------------- - * A good starting point for the Kf-value comes from the calculation: - * kf = (power_fan * eff_fan) / power_heater * 255 - * where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater. - * - * Example: - * Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8 - * Kf = (2.4W * 0.8) / 40W * 255 = 12.24 - * - * Fan-speed dependent compensation - * -------------------------------- - * 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%). - * Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled. - * If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature - * drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big. - * 2. Note the Kf-value for fan-speed at 100% - * 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving. - * 4. Repeat step 1. and 2. for this fan speed. - * 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in - * PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED - */ - //#define PID_FAN_SCALING - #if ENABLED(PID_FAN_SCALING) - //#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION - #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION) - // The alternative definition is used for an easier configuration. - // Just figure out Kf at fullspeed (255) and PID_FAN_SCALING_MIN_SPEED. - // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. - - #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf - #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf - #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING - - #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) - #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0 - - #else - #define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed) - #define DEFAULT_Kf 10 // A constant value added to the PID-tuner - #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING - #endif - #endif -#endif - -/** - * Automatic Temperature Mode - * - * Dynamically adjust the hotend target temperature based on planned E moves. - * - * (Contrast with PID_EXTRUSION_SCALING, which tracks E movement and adjusts PID - * behavior using an additional kC value.) - * - * Autotemp is calculated by (mintemp + factor * mm_per_sec), capped to maxtemp. - * - * Enable Autotemp Mode with M104/M109 F S B. - * Disable by sending M104/M109 with no F parameter (or F0 with AUTOTEMP_PROPORTIONAL). - */ -#define AUTOTEMP -#if ENABLED(AUTOTEMP) - #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0) - // Turn on AUTOTEMP on M104/M109 by default using proportions set here - //#define AUTOTEMP_PROPORTIONAL - #if ENABLED(AUTOTEMP_PROPORTIONAL) - #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature - #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature - #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) - #endif -#endif - -// Show 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 TEMP_SENSOR_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/min) - #define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm) -#endif - -/** - * Hotend Idle Timeout - * Prevent filament in the nozzle from charring and causing a critical jam. - */ -//#define HOTEND_IDLE_TIMEOUT -#if ENABLED(HOTEND_IDLE_TIMEOUT) - #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection - #define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection - #define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout - #define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout -#endif - -// @section temperature - -// Calibration for AD595 / AD8495 sensor to adjust temperature measurements. -// The final temperature is calculated as (measuredTemp * GAIN) + OFFSET. -#define TEMP_SENSOR_AD595_OFFSET 0.0 -#define TEMP_SENSOR_AD595_GAIN 1.0 -#define TEMP_SENSOR_AD8495_OFFSET 0.0 -#define TEMP_SENSOR_AD8495_GAIN 1.0 - -/** - * Controller Fan - * To cool down the stepper drivers and MOSFETs. - * - * The fan turns on automatically whenever any driver is enabled and turns - * off (or reduces to idle speed) shortly after drivers are turned off. - */ -//#define USE_CONTROLLER_FAN -#if ENABLED(USE_CONTROLLER_FAN) - //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan - //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered - //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. - #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) - #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled - #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled - #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors - - // Use TEMP_SENSOR_BOARD as a trigger for enabling the controller fan - //#define CONTROLLER_FAN_MIN_BOARD_TEMP 40 // (°C) Turn on the fan if the board reaches this temperature - - //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings - #if ENABLED(CONTROLLER_FAN_EDITABLE) - #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu - #endif -#endif - -// When first starting the main fan, run it at full speed for the -// 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 - -// Some coolers may require a non-zero "off" state. -//#define FAN_OFF_PWM 1 - -/** - * PWM Fan Scaling - * - * Define the min/max speeds for PWM fans (as set with M106). - * - * With these options the M106 0-255 value range is scaled to a subset - * to ensure that the fan has enough power to spin, or to run lower - * current fans with higher current. (e.g., 5V/12V fans with 12V/24V) - * Value 0 always turns off the fan. - * - * Define one or both of these to override the default 0-255 range. - */ -//#define FAN_MIN_PWM 50 -//#define FAN_MAX_PWM 128 - -/** - * Fan Fast PWM - * - * Combinations of PWM Modes, prescale values and TOP resolutions are used internally - * to produce a frequency as close as possible to the desired frequency. - * - * FAST_PWM_FAN_FREQUENCY - * Set this to your desired frequency. - * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1) - * i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers. - * For non AVR, if left undefined this defaults to F = 1Khz. - * This F value is only to protect the hardware from an absence of configuration - * and not to complete it when users are not aware that the frequency must be specifically set to support the target board. - * - * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior. - * Setting very high frequencies can damage your hardware. - * - * USE_OCR2A_AS_TOP [undefined by default] - * Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2: - * 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz] - * 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz] - * A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of - * PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.) - * USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies. - */ -//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino -#if ENABLED(FAST_PWM_FAN) - //#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below - //#define USE_OCR2A_AS_TOP - #ifndef FAST_PWM_FAN_FREQUENCY - #ifdef __AVR__ - #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) - #else - #define FAST_PWM_FAN_FREQUENCY 1000U - #endif - #endif -#endif - -/** - * Use one of the PWM fans as a redundant part-cooling fan - */ -//#define REDUNDANT_PART_COOLING_FAN 2 // Index of the fan to sync with FAN 0. - -// @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 E5_AUTO_FAN_PIN -1 -#define E6_AUTO_FAN_PIN -1 -#define E7_AUTO_FAN_PIN -1 -#define CHAMBER_AUTO_FAN_PIN -1 -#define COOLER_AUTO_FAN_PIN -1 - -#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 -#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed -#define CHAMBER_AUTO_FAN_TEMPERATURE 30 -#define CHAMBER_AUTO_FAN_SPEED 255 -#define COOLER_AUTO_FAN_TEMPERATURE 18 -#define COOLER_AUTO_FAN_SPEED 255 - -/** - * Hotend Cooling Fans tachometers - * - * Define one or more tachometer pins to enable fan speed - * monitoring, and reporting of fan speeds with M123. - * - * NOTE: Only works with fans up to 7000 RPM. - */ -//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed -//#define E0_FAN_TACHO_PIN -1 -//#define E0_FAN_TACHO_PULLUP -//#define E0_FAN_TACHO_PULLDOWN -//#define E1_FAN_TACHO_PIN -1 -//#define E1_FAN_TACHO_PULLUP -//#define E1_FAN_TACHO_PULLDOWN -//#define E2_FAN_TACHO_PIN -1 -//#define E2_FAN_TACHO_PULLUP -//#define E2_FAN_TACHO_PULLDOWN -//#define E3_FAN_TACHO_PIN -1 -//#define E3_FAN_TACHO_PULLUP -//#define E3_FAN_TACHO_PULLDOWN -//#define E4_FAN_TACHO_PIN -1 -//#define E4_FAN_TACHO_PULLUP -//#define E4_FAN_TACHO_PULLDOWN -//#define E5_FAN_TACHO_PIN -1 -//#define E5_FAN_TACHO_PULLUP -//#define E5_FAN_TACHO_PULLDOWN -//#define E6_FAN_TACHO_PIN -1 -//#define E6_FAN_TACHO_PULLUP -//#define E6_FAN_TACHO_PULLDOWN -//#define E7_FAN_TACHO_PIN -1 -//#define E7_FAN_TACHO_PULLUP -//#define E7_FAN_TACHO_PULLDOWN - -/** - * 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 CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. - //#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255) - //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu - #if ENABLED(NEOPIXEL_LED) - //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light - #endif - #if EITHER(RGB_LED, RGBW_LED) - //#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light - #endif - #if EITHER(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) - #define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } - #endif -#endif - -// @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. - -// Employ an external closed loop controller. Override pins here if needed. -//#define EXTERNAL_CLOSED_LOOP_CONTROLLER -#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - //#define CLOSED_LOOP_ENABLE_PIN -1 - //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1 -#endif - -/** - * Dual X Carriage - * - * This setup has two X carriages that can move independently, each with its own hotend. - * The carriages can be used to print an object with two colors or materials, or in - * "duplication mode" it can print two identical or X-mirrored objects simultaneously. - * The inactive carriage is parked automatically to prevent oozing. - * X1 is the left carriage, X2 the right. They park and home at opposite ends of the X axis. - * By default the X2 stepper is assigned to the first unused E plug on the board. - * - * The following Dual X Carriage modes can be selected with M605 S: - * - * 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) - * - * 1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so - * that additional slicer support is not required. (M605 S1) - * - * 2 : (DUPLICATION) The firmware moves the second X-carriage and extruder in synchronization with - * the first X-carriage and extruder, to print 2 copies of the same object at the same time. - * Set the constant X-offset and temperature differential with M605 S2 X[offs] R[deg] and - * follow with M605 S2 to initiate duplicated movement. - * - * 3 : (MIRRORED) Formbot/Vivedino-inspired mirrored mode in which the second extruder duplicates - * the movement of the first except the second extruder is reversed in the X axis. - * Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and - * follow with M605 S3 to initiate mirrored movement. - */ -//#define DUAL_X_CARRIAGE -#if ENABLED(DUAL_X_CARRIAGE) - #define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS - #define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage - #define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage - #define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position - #define X2_HOME_DIR 1 // Set to 1. The X2 carriage always homes to the max endstop position - #define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS. - // NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS. - // This allows recalibration of endstops distance without a rebuild. - // Remember to set the second extruder's X-offset to 0 in your slicer. - - // This is the default power-up mode which can be changed later using M605 S. - #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE - - // Default x offset in duplication mode (typically set to half print bed width) - #define DEFAULT_DUPLICATION_X_OFFSET 100 - - // Default action to execute following M605 mode change commands. Typically G28X to apply new mode. - //#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X" -#endif - -/** - * Multi-Stepper / Multi-Endstop - * - * When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem. - * The following explanations for X also apply to Y and Z multi-stepper setups. - * Endstop offsets may be changed by 'M666 X Y Z' and stored to EEPROM. - * - * - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X. - * - * - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset. - * - * - Extra endstops are included in the output of 'M119'. - * - * - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop. - * Applied to the X2 motor on 'G28' / 'G28 X'. - * Get the offset by homing X and measuring the error. - * Also set with 'M666 X' and stored to EEPROM with 'M500'. - * - * - Use X2_USE_ENDSTOP to set the endstop plug by name. (_XMIN_, _XMAX_, _YMIN_, _YMAX_, _ZMIN_, _ZMAX_) - */ -#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE) - //#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X - //#define X_DUAL_ENDSTOPS // X2 has its own endstop - #if ENABLED(X_DUAL_ENDSTOPS) - #define X2_USE_ENDSTOP _XMAX_ // X2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop - #endif -#endif - -#if HAS_DUAL_Y_STEPPERS - //#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y - //#define Y_DUAL_ENDSTOPS // Y2 has its own endstop - #if ENABLED(Y_DUAL_ENDSTOPS) - #define Y2_USE_ENDSTOP _YMAX_ // Y2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop - #endif -#endif - -// -// Multi-Z steppers -// -#ifdef Z2_DRIVER_TYPE - //#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z - - //#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z2_USE_ENDSTOP _XMAX_ // Z2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Y endstop - #endif - #ifdef Z3_DRIVER_TYPE - //#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z3_USE_ENDSTOP _YMAX_ // Z3 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Y endstop - #endif - #endif - #ifdef Z4_DRIVER_TYPE - //#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z4_USE_ENDSTOP _ZMAX_ // Z4 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Y endstop - #endif - #endif -#endif - -// Drive the E axis with two synchronized steppers -//#define E_DUAL_STEPPER_DRIVERS -#if ENABLED(E_DUAL_STEPPER_DRIVERS) - //#define INVERT_E1_VS_E0_DIR // E direction signals are opposites -#endif - -// Activate a solenoid on the active extruder with M380. Disable all with M381. -// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid. -//#define EXT_SOLENOID - -// @section homing - -/** - * Homing Procedure - * Homing (G28) does an indefinite move towards the endstops to establish - * the position of the toolhead relative to the workspace. - */ - -//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (mm) Backoff from endstops before sensorless homing - -#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump -#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) - -//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (mm) Backoff from endstops after homing - -#define QUICK_HOME // If G28 contains XY do a diagonal move first -//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X -//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe). -//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first - -// @section bltouch - -#if ENABLED(BLTOUCH) - /** - * Either: Use the defaults (recommended) or: For special purposes, use the following DEFINES - * Do not activate settings that the probe might not understand. Clones might misunderstand - * advanced commands. - * - * Note: If the probe is not deploying, do a "Reset" and "Self-Test" and then check the - * wiring of the BROWN, RED and ORANGE wires. - * - * Note: If the trigger signal of your probe is not being recognized, it has been very often - * because the BLACK and WHITE wires needed to be swapped. They are not "interchangeable" - * like they would be with a real switch. So please check the wiring first. - * - * Settings for all BLTouch and clone probes: - */ - - // Safety: The probe needs time to recognize the command. - // Minimum command delay (ms). Enable and increase if needed. - //#define BLTOUCH_DELAY 500 - - /** - * Settings for BLTOUCH Classic 1.2, 1.3 or BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1, and most clones: - */ - - // Feature: Switch into SW mode after a deploy. It makes the output pulse longer. Can be useful - // in special cases, like noisy or filtered input configurations. - //#define BLTOUCH_FORCE_SW_MODE - - /** - * Settings for BLTouch Smart 3.0 and 3.1 - * Summary: - * - Voltage modes: 5V and OD (open drain - "logic voltage free") output modes - * - High-Speed mode - * - Disable LCD voltage options - */ - - /** - * Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller! - * V3.0 or 3.1: Set default mode to 5V mode at Marlin startup. - * If disabled, OD mode is the hard-coded default on 3.0 - * On startup, Marlin will compare its eeprom to this value. If the selected mode - * differs, a mode set eeprom write will be completed at initialization. - * Use the option below to force an eeprom write to a V3.1 probe regardless. - */ - //#define BLTOUCH_SET_5V_MODE - - /** - * Safety: Activate if connecting a probe with an unknown voltage mode. - * V3.0: Set a probe into mode selected above at Marlin startup. Required for 5V mode on 3.0 - * V3.1: Force a probe with unknown mode into selected mode at Marlin startup ( = Probe EEPROM write ) - * To preserve the life of the probe, use this once then turn it off and re-flash. - */ - //#define BLTOUCH_FORCE_MODE_SET - - /** - * Enable "HIGH SPEED" option for probing. - * Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems. - * This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians - * might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM. - * - * Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset. - */ - //#define BLTOUCH_HS_MODE true - - // Safety: Enable voltage mode settings in the LCD menu. - //#define BLTOUCH_LCD_VOLTAGE_MENU - -#endif // BLTOUCH - -// @section extras - -/** - * Z Steppers Auto-Alignment - * Add the G34 command to align multiple Z steppers using a bed probe. - */ -//#define Z_STEPPER_AUTO_ALIGN -#if ENABLED(Z_STEPPER_AUTO_ALIGN) - /** - * Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]] - * These positions are machine-relative and do not shift with the M206 home offset! - * If not defined, probe limits will be used. - * Override with 'M422 S X Y'. - */ - //#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } } - - /** - * Orientation for the automatically-calculated probe positions. - * Override Z stepper align points with 'M422 S X Y' - * - * 2 Steppers: (0) (1) - * | | 2 | - * | 1 2 | | - * | | 1 | - * - * 3 Steppers: (0) (1) (2) (3) - * | 3 | 1 | 2 1 | 2 | - * | | 3 | | 3 | - * | 1 2 | 2 | 3 | 1 | - * - * 4 Steppers: (0) (1) (2) (3) - * | 4 3 | 1 4 | 2 1 | 3 2 | - * | | | | | - * | 1 2 | 2 3 | 3 4 | 4 1 | - */ - #ifndef Z_STEPPER_ALIGN_XY - //#define Z_STEPPERS_ORIENTATION 0 - #endif - - /** - * Z Stepper positions for more rapid convergence in bed alignment. - * Requires 3 or 4 Z steppers. - * - * Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw - * positions in the bed carriage, with one position per Z stepper in stepper - * driver order. - */ - //#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } } - - #ifndef Z_STEPPER_ALIGN_STEPPER_XY - // Amplification factor. Used to scale the correction step up or down in case - // the stepper (spindle) position is farther out than the test point. - #define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability! - #endif - - // On a 300mm bed a 5% grade would give a misalignment of ~1.5cm - #define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle - #define Z_STEPPER_ALIGN_ITERATIONS 3 // Number of iterations to apply during alignment - #define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this - #define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done? - // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights? - // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed. - #define HOME_AFTER_G34 -#endif - -// -// Add the G35 command to read bed corners to help adjust screws. Requires a bed probe. -// -//#define ASSISTED_TRAMMING -#if ENABLED(ASSISTED_TRAMMING) - - // Define positions for probe points. - #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } } - - // Define position names for probe points. - #define TRAMMING_POINT_NAME_1 "Front-Left" - #define TRAMMING_POINT_NAME_2 "Front-Right" - #define TRAMMING_POINT_NAME_3 "Back-Right" - #define TRAMMING_POINT_NAME_4 "Back-Left" - - #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation - //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first - - //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu - - //#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment - - /** - * Screw thread: - * M3: 30 = Clockwise, 31 = Counter-Clockwise - * M4: 40 = Clockwise, 41 = Counter-Clockwise - * M5: 50 = Clockwise, 51 = Counter-Clockwise - */ - #define TRAMMING_SCREW_THREAD 30 - -#endif - -// @section motion - -#define AXIS_RELATIVE_MODES { false, false, false, false } - -// Add a Duplicate option for well-separated conjoined nozzles -//#define MULTI_NOZZLE_DUPLICATION - -// 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_I_STEP_PIN false -#define INVERT_J_STEP_PIN false -#define INVERT_K_STEP_PIN false -#define INVERT_E_STEP_PIN false - -/** - * Idle Stepper Shutdown - * Set DISABLE_INACTIVE_? 'true' to shut down axis steppers after an idle period. - * The Deactive Time can be overridden with M18 and M84. Set to 0 for No Timeout. - */ -#define DEFAULT_STEPPER_DEACTIVE_TIME 120 -#define DISABLE_INACTIVE_X true -#define DISABLE_INACTIVE_Y true -#define DISABLE_INACTIVE_Z false // Set 'false' if the nozzle could fall onto your printed part! -#define DISABLE_INACTIVE_I true -#define DISABLE_INACTIVE_J true -#define DISABLE_INACTIVE_K true -#define DISABLE_INACTIVE_E true - -// Default Minimum Feedrates for printing and travel moves -#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S. -#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T. - -// Minimum time that a segment needs to take as the buffer gets emptied -#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B. - -// Slow down the machine if the lookahead buffer is (by default) half full. -// Increase the slowdown divisor for larger buffer sizes. -#define SLOWDOWN -#if ENABLED(SLOWDOWN) - #define SLOWDOWN_DIVISOR 2 -#endif - -/** - * XY Frequency limit - * Reduce resonance by limiting the frequency of small zigzag infill moves. - * See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html - * Use M201 F G to change limits at runtime. - */ -//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F. -#ifdef XY_FREQUENCY_LIMIT - #define XY_FREQUENCY_MIN_PERCENT 5 // (percent) Minimum FR percentage to apply. Set with M201 G. -#endif - -// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end -// of the buffer and all stops. This should not be much greater than zero and should only be changed -// if unwanted behavior is observed on a user's machine when running at very slow speeds. -#define MINIMUM_PLANNER_SPEED 0.05 // (mm/s) - -// -// Backlash Compensation -// Adds extra movement to axes on direction-changes to account for backlash. -// -//#define BACKLASH_COMPENSATION -#if ENABLED(BACKLASH_COMPENSATION) - // Define values for backlash distance and correction. - // If BACKLASH_GCODE is enabled these values are the defaults. - #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm) One value for each linear axis - #define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction - - // Add steps for motor direction changes on CORE kinematics - //#define CORE_BACKLASH - - // Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments - // to reduce print artifacts. (Enabling this is costly in memory and computation!) - //#define BACKLASH_SMOOTHING_MM 3 // (mm) - - // Add runtime configuration and tuning of backlash values (M425) - //#define BACKLASH_GCODE - - #if ENABLED(BACKLASH_GCODE) - // Measure the Z backlash when probing (G29) and set with "M425 Z" - #define MEASURE_BACKLASH_WHEN_PROBING - - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - // When measuring, the probe will move up to BACKLASH_MEASUREMENT_LIMIT - // mm away from point of contact in BACKLASH_MEASUREMENT_RESOLUTION - // increments while checking for the contact to be broken. - #define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm) - #define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm) - #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min) - #endif - #endif -#endif - -/** - * Automatic backlash, position and hotend offset calibration - * - * Enable G425 to run automatic calibration using an electrically- - * conductive cube, bolt, or washer mounted on the bed. - * - * G425 uses the probe to touch the top and sides of the calibration object - * on the bed and measures and/or correct positional offsets, axis backlash - * and hotend offsets. - * - * Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within - * ±5mm of true values for G425 to succeed. - */ -//#define CALIBRATION_GCODE -#if ENABLED(CALIBRATION_GCODE) - - //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." - //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" - - #define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm - - #define CALIBRATION_FEEDRATE_SLOW 60 // mm/min - #define CALIBRATION_FEEDRATE_FAST 1200 // mm/min - #define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min - - // The following parameters refer to the conical section of the nozzle tip. - #define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm - #define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // mm - - // Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM). - //#define CALIBRATION_REPORTING - - // The true location and dimension the cube/bolt/washer on the bed. - #define CALIBRATION_OBJECT_CENTER { 264.0, -22.0, -2.0 } // mm - #define CALIBRATION_OBJECT_DIMENSIONS { 10.0, 10.0, 10.0 } // mm - - // Comment out any sides which are unreachable by the probe. For best - // auto-calibration results, all sides must be reachable. - #define CALIBRATION_MEASURE_RIGHT - #define CALIBRATION_MEASURE_FRONT - #define CALIBRATION_MEASURE_LEFT - #define CALIBRATION_MEASURE_BACK - - //#define CALIBRATION_MEASURE_IMIN - //#define CALIBRATION_MEASURE_IMAX - //#define CALIBRATION_MEASURE_JMIN - //#define CALIBRATION_MEASURE_JMAX - //#define CALIBRATION_MEASURE_KMIN - //#define CALIBRATION_MEASURE_KMAX - - // Probing at the exact top center only works if the center is flat. If - // probing on a screwhead or hollow washer, probe near the edges. - //#define CALIBRATION_MEASURE_AT_TOP_EDGES - - // Define the pin to read during calibration - #ifndef CALIBRATION_PIN - //#define CALIBRATION_PIN -1 // Define here to override the default pin - #define CALIBRATION_PIN_INVERTING false // Set to true to invert the custom pin - //#define CALIBRATION_PIN_PULLDOWN - #define CALIBRATION_PIN_PULLUP - #endif -#endif - -/** - * Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies - * below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible - * vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the - * lowest stepping frequencies. - */ -//#define ADAPTIVE_STEP_SMOOTHING - -/** - * Custom Microstepping - * Override as-needed for your setup. Up to 3 MS pins are supported. - */ -//#define MICROSTEP1 LOW,LOW,LOW -//#define MICROSTEP2 HIGH,LOW,LOW -//#define MICROSTEP4 LOW,HIGH,LOW -//#define MICROSTEP8 HIGH,HIGH,LOW -//#define MICROSTEP16 LOW,LOW,HIGH -//#define MICROSTEP32 HIGH,LOW,HIGH - -// Microstep settings (Requires a board with pins named X_MS1, X_MS2, etc.) -#define MICROSTEP_MODES { 16, 16, 16, 16, 16, 16 } // [1,2,4,8,16] - -/** - * @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, AZTEEG_X5_MINI_WIFI, 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 - -/** - * I2C-based DIGIPOTs (e.g., Azteeg X3 Pro) - */ -//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster -//#define DIGIPOT_MCP4451 -#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) - #define DIGIPOT_I2C_NUM_CHANNELS 5 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5 - - // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS - #define DIGIPOT_I2C_MOTOR_CURRENTS { 0.84, 0.84, 0.4, 1.0, 1.0 } // AZTEEG_X3_PRO - - //#define DIGIPOT_USE_RAW_VALUES // Use DIGIPOT_MOTOR_CURRENT raw wiper values (instead of A4988 motor currents) - - /** - * Common slave addresses: - * - * A (A shifted) B (B shifted) IC - * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 - * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (0x5C) MCP4451 - * AZTEEG_X5_MINI 0x2C (0x58) 0x2E (0x5C) MCP4451 - * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 - * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 - */ - //#define DIGIPOT_I2C_ADDRESS_A 0x2C // Unshifted slave address for first DIGIPOT - //#define DIGIPOT_I2C_ADDRESS_B 0x2D // Unshifted slave address for second DIGIPOT -#endif - -//=========================================================================== -//=============================Additional Features=========================== -//=========================================================================== - -// @section lcd - -#if HAS_MANUAL_MOVE_MENU - #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel - #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines - #if IS_ULTIPANEL - #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" - //#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen - #endif -#endif - -// Change values more rapidly when the encoder is rotated faster -#define ENCODER_RATE_MULTIPLIER -#if ENABLED(ENCODER_RATE_MULTIPLIER) - #define ENCODER_10X_STEPS_PER_SEC 30 // (steps/s) Encoder rate for 10x speed - #define ENCODER_100X_STEPS_PER_SEC 80 // (steps/s) Encoder rate for 100x speed -#endif - -// Play a beep when the feedrate is changed from the Status Screen -//#define BEEP_ON_FEEDRATE_CHANGE -#if ENABLED(BEEP_ON_FEEDRATE_CHANGE) - #define FEEDRATE_CHANGE_BEEP_DURATION 10 - #define FEEDRATE_CHANGE_BEEP_FREQUENCY 440 -#endif - -// -// LCD Backlight Timeout -// -//#define LCD_BACKLIGHT_TIMEOUT 30 // (s) Timeout before turning off the backlight - -#if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI) - //#define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu - #if ENABLED(PROBE_OFFSET_WIZARD) - /** - * Enable to init the Probe Z-Offset when starting the Wizard. - * Use a height slightly above the estimated nozzle-to-probe Z offset. - * For example, with an offset of -5, consider a starting height of -4. - */ - //#define PROBE_OFFSET_WIZARD_START_Z -4.0 - - // Set a convenient position to do the calibration (probing point and nozzle/bed-distance) - //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER } - #endif -#endif - -#if HAS_MARLINUI_MENU - - #if HAS_BED_PROBE - // Add calibration in the Probe Offsets menu to compensate for X-axis twist. - //#define X_AXIS_TWIST_COMPENSATION - #if ENABLED(X_AXIS_TWIST_COMPENSATION) - /** - * Enable to init the Probe Z-Offset when starting the Wizard. - * Use a height slightly above the estimated nozzle-to-probe Z offset. - * For example, with an offset of -5, consider a starting height of -4. - */ - #define XATC_START_Z 0.0 - #define XATC_MAX_POINTS 3 // Number of points to probe in the wizard - #define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe - #define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points - #endif - #endif - - // Include a page of printer information in the LCD Main Menu - //#define LCD_INFO_MENU - #if ENABLED(LCD_INFO_MENU) - //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages - #endif - - // BACK menu items keep the highlight at the top - //#define TURBO_BACK_MENU_ITEM - - // Insert a menu for preheating at the top level to allow for quick access - //#define PREHEAT_SHORTCUT_MENU_ITEM - -#endif // HAS_MARLINUI_MENU - -#if ANY(HAS_DISPLAY, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) - //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu - #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state -#endif - -#if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI) - // The timeout to return to the status screen from sub-menus - //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) - - #if ENABLED(SHOW_BOOTSCREEN) - #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s) - #if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI) - #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash) - #endif - #endif - - // Scroll a longer status message into view - //#define STATUS_MESSAGE_SCROLLING - - // Apply a timeout to low-priority status messages - //#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds) - - // On the Info Screen, display XY with one decimal place when possible - //#define LCD_DECIMAL_SMALL_XY - - // Add an 'M73' G-code to set the current percentage - //#define LCD_SET_PROGRESS_MANUALLY - - // Show the E position (filament used) during printing - //#define LCD_SHOW_E_TOTAL - - /** - * LED Control Menu - * Add LED Control to the LCD menu - */ - #define LED_CONTROL_MENU - #if ENABLED(LED_CONTROL_MENU) - #define LED_COLOR_PRESETS // Enable the Preset Color menu option - //#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option - #if ENABLED(LED_COLOR_PRESETS) - #define LED_USER_PRESET_RED 255 // User defined RED value - #define LED_USER_PRESET_GREEN 255 // User defined GREEN value - #define LED_USER_PRESET_BLUE 255 // User defined BLUE value - #define LED_USER_PRESET_WHITE 255 // User defined WHITE value - #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity - #define LED_USER_PRESET_STARTUP RED // Have the printer display the user preset color on startup - #endif - #if ENABLED(NEO2_COLOR_PRESETS) - #define NEO2_USER_PRESET_RED 255 // User defined RED value - #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value - #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value - #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value - #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity - //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip - #endif - #endif - -#endif - -// LCD Print Progress options -#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) - #if CAN_SHOW_REMAINING_TIME - //#define SHOW_REMAINING_TIME // Display estimated time to completion - #if ENABLED(SHOW_REMAINING_TIME) - //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation - //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time - #endif - #endif - - #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI) - //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits - #endif - - #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) - //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing - #if ENABLED(LCD_PROGRESS_BAR) - #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar - #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message - #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) - //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it - //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar - #endif - #endif -#endif - -#if ENABLED(SDSUPPORT) - /** - * SD Card SPI Speed - * May be required to resolve "volume init" errors. - * - * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED - * otherwise full speed will be applied. - * - * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED'] - */ - //#define SD_SPI_SPEED SPI_HALF_SPEED - - // The standard SD detect circuit reads LOW when media is inserted and HIGH when empty. - // Enable this option and set to HIGH if your SD cards are incorrectly detected. - //#define SD_DETECT_STATE HIGH - - //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up - //#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash) - - //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping - - #define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls - - #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished - #define SD_FINISHED_RELEASECOMMAND "M84" // Use "M84XYE" to keep Z enabled so your bed stays in place - - // Reverse SD sort to show "more recent" files first, according to the card's FAT. - // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. - #define SDCARD_RATHERRECENTFIRST - - #define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing - - //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM - //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files - - //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted - - //#define MEDIA_MENU_AT_TOP // Force the media menu to be listed on the top of the main menu - - #define EVENT_GCODE_SD_ABORT "G27" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27") - - #if ENABLED(PRINTER_EVENT_LEDS) - #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination - #endif - - /** - * Continue after Power-Loss (Creality3D) - * - * Store the current state to the SD Card at the start of each layer - * during SD printing. If the recovery file is found at boot time, present - * an option on the LCD screen to continue the print from the last-known - * point in the file. - */ - //#define POWER_LOSS_RECOVERY - #if ENABLED(POWER_LOSS_RECOVERY) - #define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) - //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss - //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS) - //#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module. - //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss - //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor - //#define POWER_LOSS_PULLDOWN - //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume - //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. - - // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, - // especially with "vase mode" printing. Set too high and vases cannot be continued. - #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data - - // Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled! - //#define POWER_LOSS_RECOVER_ZHOME - #if ENABLED(POWER_LOSS_RECOVER_ZHOME) - //#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed - #endif - #endif - - /** - * 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! - #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. - // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. - #endif - - // Allow international symbols in long filenames. To display correctly, the - // LCD's font must contain the characters. Check your selected LCD language. - //#define UTF_FILENAME_SUPPORT - - //#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 ' and list long filenames with 'M20 L' - //#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol - - //#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu - - //#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!) - - /** - * Abort SD printing when any endstop is triggered. - * This feature is enabled with 'M540 S1' or from the LCD menu. - * Endstops must be activated for this option to work. - */ - //#define SD_ABORT_ON_ENDSTOP_HIT - - //#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file - - //#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S' - - /** - * Support for USB thumb drives using an Arduino USB Host Shield or - * equivalent MAX3421E breakout board. The USB thumb drive will appear - * to Marlin as an SD card. - * - * The MAX3421E can be assigned the same pins as the SD card reader, with - * the following pin mapping: - * - * SCLK, MOSI, MISO --> SCLK, MOSI, MISO - * INT --> SD_DETECT_PIN [1] - * SS --> SDSS - * - * [1] On AVR an interrupt-capable pin is best for UHS3 compatibility. - */ - //#define USB_FLASH_DRIVE_SUPPORT - #if ENABLED(USB_FLASH_DRIVE_SUPPORT) - /** - * USB Host Shield Library - * - * - UHS2 uses no interrupts and has been production-tested - * on a LulzBot TAZ Pro with a 32-bit Archim board. - * - * - UHS3 is newer code with better USB compatibility. But it - * is less tested and is known to interfere with Servos. - * [1] This requires USB_INTR_PIN to be interrupt-capable. - */ - //#define USE_UHS2_USB - //#define USE_UHS3_USB - - /** - * Native USB Host supported by some boards (USB OTG) - */ - //#define USE_OTG_USB_HOST - - #if DISABLED(USE_OTG_USB_HOST) - #define USB_CS_PIN SDSS - #define USB_INTR_PIN SD_DETECT_PIN - #endif - #endif - - /** - * When using a bootloader that supports SD-Firmware-Flashing, - * add a menu item to activate SD-FW-Update on the next reboot. - * - * Requires ATMEGA2560 (Arduino Mega) - * - * Tested with this bootloader: - * https://github.com/FleetProbe/MicroBridge-Arduino-ATMega2560 - */ - //#define SD_FIRMWARE_UPDATE - #if ENABLED(SD_FIRMWARE_UPDATE) - #define SD_FIRMWARE_UPDATE_EEPROM_ADDR 0x1FF - #define SD_FIRMWARE_UPDATE_ACTIVE_VALUE 0xF0 - #define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF - #endif - - /** - * Enable this option if you have more than ~3K of unused flash space. - * Marlin will embed all settings in the firmware binary as compressed data. - * Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'. - * See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'. - */ - //#define CONFIGURATION_EMBEDDING - - // Add an optimized binary file transfer mode, initiated with 'M28 B1' - //#define BINARY_FILE_TRANSFER - - #if ENABLED(BINARY_FILE_TRANSFER) - // Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER - //#define CUSTOM_FIRMWARE_UPLOAD - #endif - - /** - * Set this option to one of the following (or the board's defaults apply): - * - * LCD - Use the SD drive in the external LCD controller. - * ONBOARD - Use the SD drive on the control board. - * CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file). - * - * :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ] - */ - //#define SDCARD_CONNECTION LCD - - // Enable if SD detect is rendered useless (e.g., by using an SD extender) - //#define NO_SD_DETECT - - /** - * Multiple volume support - EXPERIMENTAL. - * Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive. - */ - //#define MULTI_VOLUME - #if ENABLED(MULTI_VOLUME) - #define VOLUME_SD_ONBOARD - #define VOLUME_USB_FLASH_DRIVE - #define DEFAULT_VOLUME SV_SD_ONBOARD - #define DEFAULT_SHARED_VOLUME SV_USB_FLASH_DRIVE - #endif - -#endif // SDSUPPORT - -/** - * By default an onboard SD card reader may be shared as a USB mass- - * storage device. This option hides the SD card from the host PC. - */ -//#define NO_SD_HOST_DRIVE // Disable SD Card access over USB (for security). - -/** - * 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 HAS_MARLINUI_U8GLIB - // Save many cycles by drawing a hollow frame or no frame on the Info Screen - //#define XYZ_NO_FRAME - #define XYZ_HOLLOW_FRAME - - // A bigger font is available for edit items. Costs 3120 bytes of flash. - // 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 2434 bytes of flash. - // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. - //#define USE_SMALL_INFOFONT - - /** - * Graphical Display Sleep - * - * The U8G library provides sleep / wake functions for SH1106, SSD1306, - * SSD1309, and some other DOGM displays. - * Enable this option to save energy and prevent OLED pixel burn-in. - * Adds the menu item Configuration > LCD Timeout (m) to set a wait period - * from 0 (disabled) to 99 minutes. - */ - //#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen - - /** - * ST7920-based LCDs can emulate a 16 x 4 character display using - * the ST7920 character-generator for very fast screen updates. - * Enable LIGHTWEIGHT_UI to use this special display mode. - * - * Since LIGHTWEIGHT_UI has limited space, the position and status - * message occupy the same line. Set STATUS_EXPIRE_SECONDS to the - * length of time to display the status message before clearing. - * - * Set STATUS_EXPIRE_SECONDS to zero to never clear the status. - * This will prevent position updates from being displayed. - */ - #if IS_U8GLIB_ST7920 - // Enable this option and reduce the value to optimize screen updates. - // The normal delay is 10µs. Use the lowest value that still gives a reliable display. - //#define DOGM_SPI_DELAY_US 5 - - //#define LIGHTWEIGHT_UI - #if ENABLED(LIGHTWEIGHT_UI) - #define STATUS_EXPIRE_SECONDS 20 - #endif - #endif - - /** - * Status (Info) Screen customizations - * These options may affect code size and screen render time. - * Custom status screens can forcibly override these settings. - */ - //#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones - //#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends) - #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends) - #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating - #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating - #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating - //#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active - //#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling - //#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow - //#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap - //#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap - //#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames - //#define STATUS_HEAT_PERCENT // Show heating in a progress bar - //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash. - - // Frivolous Game Options - //#define MARLIN_BRICKOUT - //#define MARLIN_INVADERS - //#define MARLIN_SNAKE - //#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu - -#endif // HAS_MARLINUI_U8GLIB - -#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI - // Show SD percentage next to the progress bar - //#define SHOW_SD_PERCENT - - // Enable to save many cycles by drawing a hollow frame on Menu Screens - #define MENU_HOLLOW_FRAME - - // Swap the CW/CCW indicators in the graphics overlay - //#define OVERLAY_GFX_REVERSE -#endif - -// -// Additional options for DGUS / DWIN displays -// -#if HAS_DGUS_LCD - #define LCD_BAUDRATE 115200 - - #define DGUS_RX_BUFFER_SIZE 128 - #define DGUS_TX_BUFFER_SIZE 48 - //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) - - #define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates - - #if ANY(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS, DGUS_LCD_UI_HIPRECY) - #define DGUS_PRINT_FILENAME // Display the filename during printing - #define DGUS_PREHEAT_UI // Display a preheat screen during heatup - - #if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS) - //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS - #else - #define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY - #endif - - #define DGUS_FILAMENT_LOADUNLOAD - #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - #define DGUS_FILAMENT_PURGE_LENGTH 10 - #define DGUS_FILAMENT_LOAD_LENGTH_PER_TIME 0.5 // (mm) Adjust in proportion to DGUS_UPDATE_INTERVAL_MS - #endif - - #define DGUS_UI_WAITING // Show a "waiting" screen between some screens - #if ENABLED(DGUS_UI_WAITING) - #define DGUS_UI_WAITING_STATUS 10 - #define DGUS_UI_WAITING_STATUS_PERIOD 8 // Increase to slower waiting status looping - #endif - #endif -#endif // HAS_DGUS_LCD - -// -// Additional options for AnyCubic Chiron TFT displays -// -#if ENABLED(ANYCUBIC_LCD_CHIRON) - // By default the type of panel is automatically detected. - // Enable one of these options if you know the panel type. - //#define CHIRON_TFT_STANDARD - //#define CHIRON_TFT_NEW - - // Enable the longer Anycubic powerup startup tune - //#define AC_DEFAULT_STARTUP_TUNE - - /** - * Display Folders - * By default the file browser lists all G-code files (including those in subfolders) in a flat list. - * Enable this option to display a hierarchical file browser. - * - * NOTES: - * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders. - * - When used with the "new" panel, folder names will also have '.gcode' appended to their names. - * This hack is currently required to force the panel to show folders. - */ - #define AC_SD_FOLDER_VIEW -#endif - -// -// Specify additional languages for the UI. Default specified by LCD_LANGUAGE. -// -#if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI) - //#define LCD_LANGUAGE_2 fr - //#define LCD_LANGUAGE_3 de - //#define LCD_LANGUAGE_4 es - //#define LCD_LANGUAGE_5 it - #ifdef LCD_LANGUAGE_2 - //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change - #endif -#endif - -// -// Touch UI for the FTDI Embedded Video Engine (EVE) -// -#if ENABLED(TOUCH_UI_FTDI_EVE) - // Display board used - //#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240) - //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272) - //#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" (480x272) - //#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480) - //#define LCD_LULZBOT_CLCD_UI // LulzBot Color LCD UI - //#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480) - //#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815 - //#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813 - - // Correct the resolution if not using the stock TFT panel. - //#define TOUCH_UI_320x240 - //#define TOUCH_UI_480x272 - //#define TOUCH_UI_800x480 - - // Mappings for boards with a standard RepRapDiscount Display connector - //#define AO_EXP1_PINMAP // LulzBot CLCD UI EXP1 mapping - //#define AO_EXP2_PINMAP // LulzBot CLCD UI EXP2 mapping - //#define CR10_TFT_PINMAP // Rudolph Riedel's CR10 pin mapping - //#define S6_TFT_PINMAP // FYSETC S6 pin mapping - //#define F6_TFT_PINMAP // FYSETC F6 pin mapping - - //#define OTHER_PIN_LAYOUT // Define pins manually below - #if ENABLED(OTHER_PIN_LAYOUT) - // Pins for CS and MOD_RESET (PD) must be chosen - #define CLCD_MOD_RESET 9 - #define CLCD_SPI_CS 10 - - // If using software SPI, specify pins for SCLK, MOSI, MISO - //#define CLCD_USE_SOFT_SPI - #if ENABLED(CLCD_USE_SOFT_SPI) - #define CLCD_SOFT_SPI_MOSI 11 - #define CLCD_SOFT_SPI_MISO 12 - #define CLCD_SOFT_SPI_SCLK 13 - #endif - #endif - - // Display Orientation. An inverted (i.e. upside-down) display - // is supported on the FT800. The FT810 and beyond also support - // portrait and mirrored orientations. - //#define TOUCH_UI_INVERTED - //#define TOUCH_UI_PORTRAIT - //#define TOUCH_UI_MIRRORED - - // UTF8 processing and rendering. - // Unsupported characters are shown as '?'. - //#define TOUCH_UI_USE_UTF8 - #if ENABLED(TOUCH_UI_USE_UTF8) - // Western accents support. These accented characters use - // combined bitmaps and require relatively little storage. - #define TOUCH_UI_UTF8_WESTERN_CHARSET - #if ENABLED(TOUCH_UI_UTF8_WESTERN_CHARSET) - // Additional character groups. These characters require - // full bitmaps and take up considerable storage: - //#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³ - //#define TOUCH_UI_UTF8_COPYRIGHT // © ® - //#define TOUCH_UI_UTF8_GERMANIC // ß - //#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ à Ø Þ æ ð ø þ - //#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡ - //#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥ - //#define TOUCH_UI_UTF8_ORDINALS // º ª - //#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷ - //#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾ - //#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬ - #endif - - // Cyrillic character set, costs about 27KiB of flash - //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET - #endif - - // Use a smaller font when labels don't fit buttons - #define TOUCH_UI_FIT_TEXT - - // Use a numeric passcode for "Screen lock" keypad. - // (recommended for smaller displays) - //#define TOUCH_UI_PASSCODE - - // Output extra debug info for Touch UI events - //#define TOUCH_UI_DEBUG - - // Developer menu (accessed by touching "About Printer" copyright text) - //#define TOUCH_UI_DEVELOPER_MENU -#endif - -// -// Classic UI Options -// -#if TFT_SCALED_DOGLCD - //#define TFT_MARLINUI_COLOR 0xFFFF // White - //#define TFT_MARLINBG_COLOR 0x0000 // Black - //#define TFT_DISABLED_COLOR 0x0003 // Almost black - //#define TFT_BTCANCEL_COLOR 0xF800 // Red - //#define TFT_BTARROWS_COLOR 0xDEE6 // 11011 110111 00110 Yellow - //#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan -#endif - -// -// ADC Button Debounce -// -#if HAS_ADC_BUTTONS - #define ADC_BUTTON_DEBOUNCE_DELAY 16 // Increase if buttons bounce or repeat too fast -#endif - -// @section safety - -/** - * The watchdog hardware timer will do a reset and disable all outputs - * if the firmware gets too overloaded to read the temperature sensors. - * - * If you find that watchdog reboot causes your AVR board to hang forever, - * enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO. - * NOTE: This method is less reliable as it can only catch hangups while - * interrupts are enabled. - */ -#define USE_WATCHDOG -#if ENABLED(USE_WATCHDOG) - //#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 INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR - //#define BABYSTEP_WITHOUT_HOMING - //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement). - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - //#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps - #define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep - #define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep - - //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. - #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) - #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. - // Note: Extra time may be added to mitigate controller latency. - //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle. - #if ENABLED(MOVE_Z_WHEN_IDLE) - #define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size. - #endif - #endif - - //#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28 - - //#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping - #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets - //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - #endif -#endif - -// @section extruder - -/** - * Linear Pressure Control v1.5 - * - * Assumption: advance [steps] = k * (delta velocity [steps/s]) - * K=0 means advance disabled. - * - * NOTE: K values for LIN_ADVANCE 1.5 differ from earlier versions! - * - * Set K around 0.22 for 3mm PLA Direct Drive with ~6.5cm between the drive gear and heatbreak. - * Larger K values will be needed for flexible filament and greater distances. - * If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk) - * print acceleration will be reduced during the affected moves to keep within the limit. - * - * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. - */ -//#define LIN_ADVANCE -#if ENABLED(LIN_ADVANCE) - //#define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants - #define LIN_ADVANCE_K 0.22 // Unit: mm compression per 1mm/s extruder speed - //#define LA_DEBUG // If enabled, this will generate debug information output over USB. - //#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration - //#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends. -#endif - -// @section leveling - -/** - * Points to probe for all 3-point Leveling procedures. - * Override if the automatically selected points are inadequate. - */ -#if EITHER(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_UBL) - //#define PROBE_PT_1_X 15 - //#define PROBE_PT_1_Y 180 - //#define PROBE_PT_2_X 15 - //#define PROBE_PT_2_Y 20 - //#define PROBE_PT_3_X 170 - //#define PROBE_PT_3_Y 20 -#endif - -/** - * Probing Margins - * - * Override PROBING_MARGIN for each side of the build plate - * Useful to get probe points to exact positions on targets or - * to allow leveling to avoid plate clamps on only specific - * sides of the bed. With NOZZLE_AS_PROBE negative values are - * allowed, to permit probing outside the bed. - * - * If you are replacing the prior *_PROBE_BED_POSITION options, - * LEFT and FRONT values in most cases will map directly over - * RIGHT and REAR would be the inverse such as - * (X/Y_BED_SIZE - RIGHT/BACK_PROBE_BED_POSITION) - * - * This will allow all positions to match at compilation, however - * should the probe position be modified with M851XY then the - * probe points will follow. This prevents any change from causing - * the probe to be unable to reach any points. - */ -#if PROBE_SELECTED && !IS_KINEMATIC - //#define PROBING_MARGIN_LEFT PROBING_MARGIN - //#define PROBING_MARGIN_RIGHT PROBING_MARGIN - //#define PROBING_MARGIN_FRONT PROBING_MARGIN - //#define PROBING_MARGIN_BACK PROBING_MARGIN -#endif - -#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) - // Override the mesh area if the automatic (max) area is too large - //#define MESH_MIN_X MESH_INSET - //#define MESH_MIN_Y MESH_INSET - //#define MESH_MAX_X X_BED_SIZE - (MESH_INSET) - //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET) -#endif - -#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS) - //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space -#endif - -/** - * Repeatedly attempt G29 leveling until it succeeds. - * Stop after G29_MAX_RETRIES attempts. - */ -//#define G29_RETRY_AND_RECOVER -#if ENABLED(G29_RETRY_AND_RECOVER) - #define G29_MAX_RETRIES 3 - #define G29_HALT_ON_FAILURE - /** - * Specify the GCODE commands that will be executed when leveling succeeds, - * between attempts, and after the maximum number of retries have been tried. - */ - #define G29_SUCCESS_COMMANDS "M117 Bed leveling done." - #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0" - #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1" - -#endif - -/** - * Thermal Probe Compensation - * - * Adjust probe measurements to compensate for distortion associated with the temperature - * of the probe, bed, and/or hotend. - * Use G76 to automatically calibrate this feature for probe and bed temperatures. - * (Extruder temperature/offset values must be calibrated manually.) - * Use M871 to set temperature/offset values manually. - * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html - */ -//#define PTC_PROBE // Compensate based on probe temperature -//#define PTC_BED // Compensate based on bed temperature -//#define PTC_HOTEND // Compensate based on hotend temperature - -#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND) - /** - * If the probe is outside the defined range, use linear extrapolation with the closest - * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the - * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START. - */ - //#define PTC_LINEAR_EXTRAPOLATION 4 - - #if ENABLED(PTC_PROBE) - // Probe temperature calibration generates a table of values starting at PTC_PROBE_START - // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples. - #define PTC_PROBE_START 30 // (°C) - #define PTC_PROBE_RES 5 // (°C) - #define PTC_PROBE_COUNT 10 - #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - #if ENABLED(PTC_BED) - // Bed temperature calibration builds a similar table. - #define PTC_BED_START 60 // (°C) - #define PTC_BED_RES 5 // (°C) - #define PTC_BED_COUNT 10 - #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - #if ENABLED(PTC_HOTEND) - // Note: There is no automatic calibration for the hotend. Use M871. - #define PTC_HOTEND_START 180 // (°C) - #define PTC_HOTEND_RES 5 // (°C) - #define PTC_HOTEND_COUNT 20 - #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - // G76 options - #if BOTH(PTC_PROBE, PTC_BED) - // Park position to wait for probe cooldown - #define PTC_PARK_POS { 0, 0, 100 } - - // Probe position to probe and wait for probe to reach target temperature - //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed - #define PTC_PROBE_POS { 90, 100 } - - // The temperature the probe should be at while taking measurements during - // bed temperature calibration. - #define PTC_PROBE_TEMP 30 // (°C) - - // Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster. - // Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z). - #define PTC_PROBE_HEATING_OFFSET 0.5 - #endif -#endif // PTC_PROBE || PTC_BED || PTC_HOTEND - -// @section extras - -// -// G60/G61 Position Save and Return -// -//#define SAVED_POSITIONS 1 // Each saved position slot costs 12 bytes - -// -// G2/G3 Arc Support -// -#define ARC_SUPPORT // Requires ~3226 bytes -#if ENABLED(ARC_SUPPORT) - #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment - #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment - #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle - //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length - #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections - //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles - //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure -#endif - -// G5 Bézier Curve Support with XYZE destination and IJPQ offsets -//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes - -#if EITHER(ARC_SUPPORT, BEZIER_CURVE_SUPPORT) - //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes -#endif - -/** - * Direct Stepping - * - * Comparable to the method used by Klipper, G6 direct stepping significantly - * reduces motion calculations, increases top printing speeds, and results in - * less step aliasing by calculating all motions in advance. - * Preparing your G-code: https://github.com/colinrgodsey/step-daemon - */ -//#define DIRECT_STEPPING - -/** - * G38 Probe Target - * - * This option adds G38.2 and G38.3 (probe towards target) - * and optionally G38.4 and G38.5 (probe away from target). - * Set MULTIPLE_PROBING for G38 to probe more than once. - */ -//#define G38_PROBE_TARGET -#if ENABLED(G38_PROBE_TARGET) - //#define G38_PROBE_AWAY // Include G38.4 and G38.5 to probe away from target - #define G38_MINIMUM_MOVE 0.0275 // (mm) Minimum distance that will produce a move. -#endif - -// Moves (or segments) with fewer steps than this will be joined with the next move -#define MIN_STEPS_PER_SEGMENT 6 - -/** - * Minimum delay before and after setting the stepper DIR (in ns) - * 0 : No delay (Expect at least 10µS since one Stepper ISR must transpire) - * 20 : Minimum for TMC2xxx drivers - * 200 : Minimum for A4988 drivers - * 400 : Minimum for A5984 drivers - * 500 : Minimum for LV8729 drivers (guess, no info in datasheet) - * 650 : Minimum for DRV8825 drivers - * 1500 : Minimum for TB6600 drivers (guess, no info in datasheet) - * 15000 : Minimum for TB6560 drivers (guess, no info in datasheet) - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MINIMUM_STEPPER_POST_DIR_DELAY 650 -//#define MINIMUM_STEPPER_PRE_DIR_DELAY 650 - -/** - * Minimum stepper driver pulse width (in µs) - * 0 : Smallest possible width the MCU can produce, compatible with TMC2xxx drivers - * 0 : Minimum 500ns for LV8729, adjusted in stepper.h - * 1 : Minimum for A4988 and A5984 stepper drivers - * 2 : Minimum for DRV8825 stepper drivers - * 3 : Minimum for TB6600 stepper drivers - * 30 : Minimum for TB6560 stepper drivers - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MINIMUM_STEPPER_PULSE 2 - -/** - * Maximum stepping rate (in Hz) the stepper driver allows - * If undefined, defaults to 1MHz / (2 * MINIMUM_STEPPER_PULSE) - * 5000000 : Maximum for TMC2xxx stepper drivers - * 1000000 : Maximum for LV8729 stepper driver - * 500000 : Maximum for A4988 stepper driver - * 250000 : Maximum for DRV8825 stepper driver - * 150000 : Maximum for TB6600 stepper driver - * 15000 : Maximum for TB6560 stepper driver - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MAXIMUM_STEPPER_RATE 250000 - -// @section temperature - -// Control heater 0 and heater 1 in parallel. -//#define HEATERS_PARALLEL - -//=========================================================================== -//================================= Buffers ================================= -//=========================================================================== - -// @section motion - -// The number of linear moves that can be in the planner at once. -// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g., 8, 16, 32) -#if BOTH(SDSUPPORT, DIRECT_STEPPING) - #define BLOCK_BUFFER_SIZE 8 -#elif ENABLED(SDSUPPORT) - #define BLOCK_BUFFER_SIZE 16 -#else - #define BLOCK_BUFFER_SIZE 16 -#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 flash (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 - -// Monitor RX buffer usage -// Dump an error to the serial port if the serial receive buffer overflows. -// If you see these errors, increase the RX_BUFFER_SIZE value. -// Not supported on all platforms. -//#define RX_BUFFER_MONITOR - -/** - * Emergency Command Parser - * - * Add a low-level parser to intercept certain commands as they - * enter the serial receive buffer, so they cannot be blocked. - * Currently handles M108, M112, M410, M876 - * NOTE: Not yet implemented for all platforms. - */ -//#define EMERGENCY_PARSER - -/** - * Realtime Reporting (requires EMERGENCY_PARSER) - * - * - Report position and state of the machine (like Grbl). - * - Auto-report position during long moves. - * - Useful for CNC/LASER. - * - * Adds support for commands: - * S000 : Report State and Position while moving. - * P000 : Instant Pause / Hold while moving. - * R000 : Resume from Pause / Hold. - * - * - During Hold all Emergency Parser commands are available, as usual. - * - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports. - */ -//#define REALTIME_REPORTING_COMMANDS -#if ENABLED(REALTIME_REPORTING_COMMANDS) - //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC -#endif - -// 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 - -// Printrun may have trouble receiving long strings all at once. -// This option inserts short delays between lines of serial output. -#define SERIAL_OVERRUN_PROTECTION - -// For serial echo, the number of digits after the decimal point -//#define SERIAL_FLOAT_PRECISION 4 - -/** - * 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 - -// @section extras - -/** - * Extra Fan Speed - * Adds a secondary fan speed for each print-cooling fan. - * 'M106 P T3-255' : Set a secondary speed for - * 'M106 P T2' : Use the set secondary speed - * 'M106 P T1' : Restore the previous fan speed - */ -//#define EXTRA_FAN_SPEED - -/** - * 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 -#if ENABLED(FWRETRACT) - #define FWRETRACT_AUTORETRACT // Override slicer retractions - #if ENABLED(FWRETRACT_AUTORETRACT) - #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length - #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length - #endif - #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value) - #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value) - #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting - #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise - #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover) - #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange) - #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction - #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction - #if ENABLED(MIXING_EXTRUDER) - //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously - #endif -#endif - -/** - * Universal tool change settings. - * Applies to all types of extruders except where explicitly noted. - */ -#if HAS_MULTI_EXTRUDER - // Z raise distance for tool-change, as needed for some extruders - #define TOOLCHANGE_ZRAISE 0 // (mm) - //#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled) - //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change - #if ENABLED(TOOLCHANGE_NO_RETURN) - //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change - #endif - - /** - * Extra G-code to run while executing tool-change commands. Can be used to use an additional - * stepper motor (I axis, see option LINEAR_AXES in Configuration.h) to drive the tool-changer. - */ - //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0 - //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1 - //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution! - - /** - * Tool Sensors detect when tools have been picked up or dropped. - * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. - */ - //#define TOOL_SENSOR - - /** - * Retract and prime filament on tool-change to reduce - * ooze and stringing and to get cleaner transitions. - */ - //#define TOOLCHANGE_FILAMENT_SWAP - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - // Load / Unload - #define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length - #define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B. - #define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading) - #define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down) - - // Longer prime to clean out a SINGLENOZZLE - #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length - #define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate - #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc. - - // Cool after prime to reduce stringing - #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip - #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 - #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) - - // Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed - //#define TOOLCHANGE_FS_SLOW_FIRST_PRIME - - /** - * Prime T0 the first time T0 is sent to the printer: - * [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ] - * If disabled, no priming on T0 until switching back to T0 from another extruder: - * [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ] - * Enable with M217 V1 before printing to avoid unwanted priming on host connect. - */ - //#define TOOLCHANGE_FS_PRIME_FIRST_USED - - /** - * Tool Change Migration - * This feature provides G-code and LCD options to switch tools mid-print. - * All applicable tool properties are migrated so the print can continue. - * Tools must be closely matching and other restrictions may apply. - * Useful to: - * - Change filament color without interruption - * - Switch spools automatically on filament runout - * - Switch to a different nozzle on an extruder jam - */ - #define TOOLCHANGE_MIGRATION_FEATURE - - #endif - - /** - * Position to park head during tool change. - * Doesn't apply to SWITCHING_TOOLHEAD, DUAL_X_CARRIAGE, or PARKING_EXTRUDER - */ - //#define TOOLCHANGE_PARK - #if ENABLED(TOOLCHANGE_PARK) - #define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 } - #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min) - //#define TOOLCHANGE_PARK_X_ONLY // X axis only move - //#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move - #endif -#endif // HAS_MULTI_EXTRUDER - -/** - * Advanced Pause for Filament Change - * - Adds the G-code M600 Filament Change to initiate a filament change. - * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT. - * - * Requirements: - * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE. - * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER. - * - * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. - */ -#define ADVANCED_PAUSE_FEATURE -#if ENABLED(ADVANCED_PAUSE_FEATURE) - #define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate. - #define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract. - // This short retract is done immediately, before parking the nozzle. - #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast. - #define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. - #define FILAMENT_CHANGE_UNLOAD_LENGTH 80 // (mm) The length of filament for a complete unload. - // For Bowden, the full length of the tube and nozzle. - // For direct drive, the full length of the nozzle. - // Set to 0 for manual unloading. - #define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load. - #define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 80 // (mm) Slow length, to allow time to insert material. - // 0 to disable start loading and skip to fast load only - #define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 6 // (mm/s) Load filament feedrate. This can be pretty fast. - #define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. - #define FILAMENT_CHANGE_FAST_LOAD_LENGTH 0 // (mm) Load length of filament, from extruder gear to nozzle. - // For Bowden, the full length of the tube and nozzle. - // For direct drive, the full length of the nozzle. - //#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted. - #define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate. - #define ADVANCED_PAUSE_PURGE_LENGTH 50 // (mm) Length to extrude after loading. - // Set to 0 for manual extrusion. - // Filament can be extruded repeatedly from the Filament Change menu - // until extrusion is consistent, and to purge old filament. - #define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park. - //#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused. - - // Filament Unload does a Retract, Delay, and Purge first: - #define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length. - #define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract. - #define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged. - #define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload - - #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety. - #define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed. - #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change. - //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again. - //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing. - - #define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change. - //#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change - - #define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu. - //#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302) -#endif - -// @section tmc - -/** - * TMC26X Stepper Driver options - * - * The TMC26XStepper library is required for this stepper driver. - * https://github.com/trinamic/TMC26XStepper - */ -#if HAS_DRIVER(TMC26X) - - #if AXIS_DRIVER_TYPE_X(TMC26X) - #define X_MAX_CURRENT 1000 // (mA) - #define X_SENSE_RESISTOR 91 // (mOhms) - #define X_MICROSTEPS 16 // Number of microsteps - #endif - - #if AXIS_DRIVER_TYPE_X2(TMC26X) - #define X2_MAX_CURRENT 1000 - #define X2_SENSE_RESISTOR 91 - #define X2_MICROSTEPS X_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Y(TMC26X) - #define Y_MAX_CURRENT 1000 - #define Y_SENSE_RESISTOR 91 - #define Y_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_Y2(TMC26X) - #define Y2_MAX_CURRENT 1000 - #define Y2_SENSE_RESISTOR 91 - #define Y2_MICROSTEPS Y_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z(TMC26X) - #define Z_MAX_CURRENT 1000 - #define Z_SENSE_RESISTOR 91 - #define Z_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_Z2(TMC26X) - #define Z2_MAX_CURRENT 1000 - #define Z2_SENSE_RESISTOR 91 - #define Z2_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z3(TMC26X) - #define Z3_MAX_CURRENT 1000 - #define Z3_SENSE_RESISTOR 91 - #define Z3_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z4(TMC26X) - #define Z4_MAX_CURRENT 1000 - #define Z4_SENSE_RESISTOR 91 - #define Z4_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_I(TMC26X) - #define I_MAX_CURRENT 1000 - #define I_SENSE_RESISTOR 91 - #define I_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_J(TMC26X) - #define J_MAX_CURRENT 1000 - #define J_SENSE_RESISTOR 91 - #define J_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_K(TMC26X) - #define K_MAX_CURRENT 1000 - #define K_SENSE_RESISTOR 91 - #define K_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_E0(TMC26X) - #define E0_MAX_CURRENT 1000 - #define E0_SENSE_RESISTOR 91 - #define E0_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_E1(TMC26X) - #define E1_MAX_CURRENT 1000 - #define E1_SENSE_RESISTOR 91 - #define E1_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E2(TMC26X) - #define E2_MAX_CURRENT 1000 - #define E2_SENSE_RESISTOR 91 - #define E2_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E3(TMC26X) - #define E3_MAX_CURRENT 1000 - #define E3_SENSE_RESISTOR 91 - #define E3_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E4(TMC26X) - #define E4_MAX_CURRENT 1000 - #define E4_SENSE_RESISTOR 91 - #define E4_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E5(TMC26X) - #define E5_MAX_CURRENT 1000 - #define E5_SENSE_RESISTOR 91 - #define E5_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E6(TMC26X) - #define E6_MAX_CURRENT 1000 - #define E6_SENSE_RESISTOR 91 - #define E6_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E7(TMC26X) - #define E7_MAX_CURRENT 1000 - #define E7_SENSE_RESISTOR 91 - #define E7_MICROSTEPS E0_MICROSTEPS - #endif - -#endif // TMC26X - -// @section tmc_smart - -/** - * To use TMC2130, TMC2160, TMC2660, TMC5130, TMC5160 stepper drivers in SPI mode - * connect your SPI 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.). - * You may also use software SPI if you wish to use general purpose IO pins. - * - * To use TMC2208 stepper UART-configurable stepper drivers connect #_SERIAL_TX_PIN - * to the driver side PDN_UART pin with a 1K resistor. - * To use the reading capabilities, also connect #_SERIAL_RX_PIN to PDN_UART without - * a resistor. - * The drivers can also be used with hardware serial. - * - * TMCStepper library is required to use TMC stepper drivers. - * https://github.com/teemuatlut/TMCStepper - */ -#if HAS_TRINAMIC_CONFIG - - #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - - /** - * Interpolate microsteps to 256 - * Override for each driver with _INTERPOLATE settings below - */ - #define INTERPOLATE true - - #if AXIS_IS_TMC(X) - #define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current. - #define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing - #define X_MICROSTEPS 16 // 0..256 - #define X_RSENSE 0.11 - #define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ... - //#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis - //#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis - #endif - - #if AXIS_IS_TMC(X2) - #define X2_CURRENT 800 - #define X2_CURRENT_HOME X2_CURRENT - #define X2_MICROSTEPS X_MICROSTEPS - #define X2_RSENSE 0.11 - #define X2_CHAIN_POS -1 - //#define X2_INTERPOLATE true - //#define X2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Y) - #define Y_CURRENT 800 - #define Y_CURRENT_HOME Y_CURRENT - #define Y_MICROSTEPS 16 - #define Y_RSENSE 0.11 - #define Y_CHAIN_POS -1 - //#define Y_INTERPOLATE true - //#define Y_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Y2) - #define Y2_CURRENT 800 - #define Y2_CURRENT_HOME Y2_CURRENT - #define Y2_MICROSTEPS Y_MICROSTEPS - #define Y2_RSENSE 0.11 - #define Y2_CHAIN_POS -1 - //#define Y2_INTERPOLATE true - //#define Y2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z) - #define Z_CURRENT 800 - #define Z_CURRENT_HOME Z_CURRENT - #define Z_MICROSTEPS 16 - #define Z_RSENSE 0.11 - #define Z_CHAIN_POS -1 - //#define Z_INTERPOLATE true - //#define Z_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z2) - #define Z2_CURRENT 800 - #define Z2_CURRENT_HOME Z2_CURRENT - #define Z2_MICROSTEPS Z_MICROSTEPS - #define Z2_RSENSE 0.11 - #define Z2_CHAIN_POS -1 - //#define Z2_INTERPOLATE true - //#define Z2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z3) - #define Z3_CURRENT 800 - #define Z3_CURRENT_HOME Z3_CURRENT - #define Z3_MICROSTEPS Z_MICROSTEPS - #define Z3_RSENSE 0.11 - #define Z3_CHAIN_POS -1 - //#define Z3_INTERPOLATE true - //#define Z3_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z4) - #define Z4_CURRENT 800 - #define Z4_CURRENT_HOME Z4_CURRENT - #define Z4_MICROSTEPS Z_MICROSTEPS - #define Z4_RSENSE 0.11 - #define Z4_CHAIN_POS -1 - //#define Z4_INTERPOLATE true - //#define Z4_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(I) - #define I_CURRENT 800 - #define I_CURRENT_HOME I_CURRENT - #define I_MICROSTEPS 16 - #define I_RSENSE 0.11 - #define I_CHAIN_POS -1 - //#define I_INTERPOLATE true - //#define I_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(J) - #define J_CURRENT 800 - #define J_CURRENT_HOME J_CURRENT - #define J_MICROSTEPS 16 - #define J_RSENSE 0.11 - #define J_CHAIN_POS -1 - //#define J_INTERPOLATE true - //#define J_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(K) - #define K_CURRENT 800 - #define K_CURRENT_HOME K_CURRENT - #define K_MICROSTEPS 16 - #define K_RSENSE 0.11 - #define K_CHAIN_POS -1 - //#define K_INTERPOLATE true - //#define K_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E0) - #define E0_CURRENT 800 - #define E0_MICROSTEPS 16 - #define E0_RSENSE 0.11 - #define E0_CHAIN_POS -1 - //#define E0_INTERPOLATE true - //#define E0_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E1) - #define E1_CURRENT 800 - #define E1_MICROSTEPS E0_MICROSTEPS - #define E1_RSENSE 0.11 - #define E1_CHAIN_POS -1 - //#define E1_INTERPOLATE true - //#define E1_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E2) - #define E2_CURRENT 800 - #define E2_MICROSTEPS E0_MICROSTEPS - #define E2_RSENSE 0.11 - #define E2_CHAIN_POS -1 - //#define E2_INTERPOLATE true - //#define E2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E3) - #define E3_CURRENT 800 - #define E3_MICROSTEPS E0_MICROSTEPS - #define E3_RSENSE 0.11 - #define E3_CHAIN_POS -1 - //#define E3_INTERPOLATE true - //#define E3_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E4) - #define E4_CURRENT 800 - #define E4_MICROSTEPS E0_MICROSTEPS - #define E4_RSENSE 0.11 - #define E4_CHAIN_POS -1 - //#define E4_INTERPOLATE true - //#define E4_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E5) - #define E5_CURRENT 800 - #define E5_MICROSTEPS E0_MICROSTEPS - #define E5_RSENSE 0.11 - #define E5_CHAIN_POS -1 - //#define E5_INTERPOLATE true - //#define E5_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E6) - #define E6_CURRENT 800 - #define E6_MICROSTEPS E0_MICROSTEPS - #define E6_RSENSE 0.11 - #define E6_CHAIN_POS -1 - //#define E6_INTERPOLATE true - //#define E6_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E7) - #define E7_CURRENT 800 - #define E7_MICROSTEPS E0_MICROSTEPS - #define E7_RSENSE 0.11 - #define E7_CHAIN_POS -1 - //#define E7_INTERPOLATE true - //#define E7_HOLD_MULTIPLIER 0.5 - #endif - - /** - * Override default SPI pins for TMC2130, TMC2160, TMC2660, TMC5130 and TMC5160 drivers here. - * The default pins can be found in your board's pins file. - */ - //#define X_CS_PIN -1 - //#define Y_CS_PIN -1 - //#define Z_CS_PIN -1 - //#define X2_CS_PIN -1 - //#define Y2_CS_PIN -1 - //#define Z2_CS_PIN -1 - //#define Z3_CS_PIN -1 - //#define Z4_CS_PIN -1 - //#define I_CS_PIN -1 - //#define J_CS_PIN -1 - //#define K_CS_PIN -1 - //#define E0_CS_PIN -1 - //#define E1_CS_PIN -1 - //#define E2_CS_PIN -1 - //#define E3_CS_PIN -1 - //#define E4_CS_PIN -1 - //#define E5_CS_PIN -1 - //#define E6_CS_PIN -1 - //#define E7_CS_PIN -1 - - /** - * Software option for SPI driven drivers (TMC2130, TMC2160, TMC2660, TMC5130 and TMC5160). - * The default SW SPI pins are defined the respective pins files, - * but you can override or define them here. - */ - //#define TMC_USE_SW_SPI - //#define TMC_SW_MOSI -1 - //#define TMC_SW_MISO -1 - //#define TMC_SW_SCK -1 - - /** - * Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses. - * Set the address using jumpers on pins MS1 and MS2. - * Address | MS1 | MS2 - * 0 | LOW | LOW - * 1 | HIGH | LOW - * 2 | LOW | HIGH - * 3 | HIGH | HIGH - * - * Set *_SERIAL_TX_PIN and *_SERIAL_RX_PIN to match for all drivers - * on the same serial port, either here or in your board's pins file. - */ - //#define X_SLAVE_ADDRESS 0 - //#define Y_SLAVE_ADDRESS 0 - //#define Z_SLAVE_ADDRESS 0 - //#define X2_SLAVE_ADDRESS 0 - //#define Y2_SLAVE_ADDRESS 0 - //#define Z2_SLAVE_ADDRESS 0 - //#define Z3_SLAVE_ADDRESS 0 - //#define Z4_SLAVE_ADDRESS 0 - //#define I_SLAVE_ADDRESS 0 - //#define J_SLAVE_ADDRESS 0 - //#define K_SLAVE_ADDRESS 0 - //#define E0_SLAVE_ADDRESS 0 - //#define E1_SLAVE_ADDRESS 0 - //#define E2_SLAVE_ADDRESS 0 - //#define E3_SLAVE_ADDRESS 0 - //#define E4_SLAVE_ADDRESS 0 - //#define E5_SLAVE_ADDRESS 0 - //#define E6_SLAVE_ADDRESS 0 - //#define E7_SLAVE_ADDRESS 0 - - /** - * Software enable - * - * Use for drivers that do not use a dedicated enable pin, but rather handle the same - * function through a communication line such as SPI or UART. - */ - //#define SOFTWARE_DRIVER_ENABLE - - /** - * TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only - * Use Trinamic's ultra quiet stepping mode. - * When disabled, Marlin will use spreadCycle stepping mode. - */ - #define STEALTHCHOP_XY - #define STEALTHCHOP_Z - #define STEALTHCHOP_I - #define STEALTHCHOP_J - #define STEALTHCHOP_K - #define STEALTHCHOP_E - - /** - * Optimize spreadCycle chopper parameters by using predefined parameter sets - * or with the help of an example included in the library. - * Provided parameter sets are - * CHOPPER_DEFAULT_12V - * CHOPPER_DEFAULT_19V - * CHOPPER_DEFAULT_24V - * CHOPPER_DEFAULT_36V - * CHOPPER_09STEP_24V // 0.9 degree steppers (24V) - * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V) - * CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9 - * - * Define your own with: - * { , , hysteresis_start[1..8] } - */ - #define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below) - //#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below) - //#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X - //#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below) - //#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y - //#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below) - //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_I CHOPPER_TIMING - //#define CHOPPER_TIMING_J CHOPPER_TIMING - //#define CHOPPER_TIMING_K CHOPPER_TIMING - //#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below) - //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E - - /** - * Monitor Trinamic drivers - * for error conditions like overtemperature and short to ground. - * To manage over-temp Marlin can decrease the driver current until the error condition clears. - * Other detected conditions can be used to stop the current print. - * Relevant G-codes: - * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. - * M911 - Report stepper driver overtemperature pre-warn condition. - * M912 - Clear stepper driver overtemperature pre-warn condition flag. - * M122 - Report driver parameters (Requires TMC_DEBUG) - */ - //#define MONITOR_DRIVER_STATUS - - #if ENABLED(MONITOR_DRIVER_STATUS) - #define CURRENT_STEP_DOWN 50 // [mA] - #define REPORT_CURRENT_CHANGE - #define STOP_ON_ERROR - #endif - - /** - * TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only - * 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_(XY|Z|E) must be enabled to use HYBRID_THRESHOLD. - * 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 3 - #define Z2_HYBRID_THRESHOLD 3 - #define Z3_HYBRID_THRESHOLD 3 - #define Z4_HYBRID_THRESHOLD 3 - #define I_HYBRID_THRESHOLD 3 - #define J_HYBRID_THRESHOLD 3 - #define K_HYBRID_THRESHOLD 3 - #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 - #define E5_HYBRID_THRESHOLD 30 - #define E6_HYBRID_THRESHOLD 30 - #define E7_HYBRID_THRESHOLD 30 - - /** - * Use StallGuard to home / probe X, Y, Z. - * - * TMC2130, TMC2160, TMC2209, TMC2660, TMC5130, and TMC5160 only - * Connect the stepper driver's DIAG1 pin to the X/Y endstop pin. - * X, Y, and Z homing will always be done in spreadCycle mode. - * - * X/Y/Z_STALL_SENSITIVITY is the default stall threshold. - * Use M914 X Y Z to set the stall threshold at runtime: - * - * Sensitivity TMC2209 Others - * HIGHEST 255 -64 (Too sensitive => False positive) - * LOWEST 0 63 (Too insensitive => No trigger) - * - * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. - * - * SPI_ENDSTOPS *** Beta feature! *** TMC2130/TMC5160 Only *** - * Poll the driver through SPI to determine load when homing. - * Removes the need for a wire from DIAG1 to an endstop pin. - * - * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when - * homing and adds a guard period for endstop triggering. - * - * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis. - */ - //#define SENSORLESS_HOMING // StallGuard capable drivers only - - #if EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) - // TMC2209: 0...255. TMC2130: -64...63 - #define X_STALL_SENSITIVITY 8 - #define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY - #define Y_STALL_SENSITIVITY 8 - #define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY - //#define Z_STALL_SENSITIVITY 8 - //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define I_STALL_SENSITIVITY 8 - //#define J_STALL_SENSITIVITY 8 - //#define K_STALL_SENSITIVITY 8 - //#define SPI_ENDSTOPS // TMC2130 only - //#define IMPROVE_HOMING_RELIABILITY - #endif - - /** - * TMC Homing stepper phase. - * - * Improve homing repeatability by homing to stepper coil's nearest absolute - * phase position. Trinamic drivers use a stepper phase table with 1024 values - * spanning 4 full steps with 256 positions each (ergo, 1024 positions). - * Full step positions (128, 384, 640, 896) have the highest holding torque. - * - * Values from 0..1023, -1 to disable homing phase for that axis. - */ - //#define TMC_HOME_PHASE { 896, 896, 896 } - - /** - * Beta feature! - * Create a 50/50 square wave step pulse optimal for stepper drivers. - */ - //#define SQUARE_WAVE_STEPPING - - /** - * Enable M122 debugging command for TMC stepper drivers. - * M122 S0/1 will enable continuous reporting. - */ - //#define TMC_DEBUG - - /** - * 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/TMCStepper - * - * Example: - * #define TMC_ADV() { \ - * stepperX.diag0_otpw(1); \ - * stepperY.intpol(0); \ - * } - */ - #define TMC_ADV() { } - -#endif // HAS_TRINAMIC_CONFIG - -// @section L64XX - -/** - * L64XX Stepper Driver options - * - * Arduino-L6470 library (0.8.0 or higher) is required. - * https://github.com/ameyer/Arduino-L6470 - * - * Requires the following to be defined in your pins_YOUR_BOARD file - * L6470_CHAIN_SCK_PIN - * L6470_CHAIN_MISO_PIN - * L6470_CHAIN_MOSI_PIN - * L6470_CHAIN_SS_PIN - * ENABLE_RESET_L64XX_CHIPS(Q) where Q is 1 to enable and 0 to reset - */ - -#if HAS_L64XX - - //#define L6470_CHITCHAT // Display additional status info - - #if AXIS_IS_L64XX(X) - #define X_MICROSTEPS 128 // Number of microsteps (VALID: 1, 2, 4, 8, 16, 32, 128) - L6474 max is 16 - #define X_OVERCURRENT 2000 // (mA) Current where the driver detects an over current - // L6470 & L6474 - VALID: 375 x (1 - 16) - 6A max - rounds down - // POWERSTEP01: VALID: 1000 x (1 - 32) - 32A max - rounds down - #define X_STALLCURRENT 1500 // (mA) Current where the driver detects a stall (VALID: 31.25 * (1-128) - 4A max - rounds down) - // L6470 & L6474 - VALID: 31.25 * (1-128) - 4A max - rounds down - // POWERSTEP01: VALID: 200 x (1 - 32) - 6.4A max - rounds down - // L6474 - STALLCURRENT setting is used to set the nominal (TVAL) current - #define X_MAX_VOLTAGE 127 // 0-255, Maximum effective voltage seen by stepper - not used by L6474 - #define X_CHAIN_POS -1 // Position in SPI chain, 0=Not in chain, 1=Nearest MOSI - #define X_SLEW_RATE 1 // 0-3, Slew 0 is slowest, 3 is fastest - #endif - - #if AXIS_IS_L64XX(X2) - #define X2_MICROSTEPS X_MICROSTEPS - #define X2_OVERCURRENT 2000 - #define X2_STALLCURRENT 1500 - #define X2_MAX_VOLTAGE 127 - #define X2_CHAIN_POS -1 - #define X2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Y) - #define Y_MICROSTEPS 128 - #define Y_OVERCURRENT 2000 - #define Y_STALLCURRENT 1500 - #define Y_MAX_VOLTAGE 127 - #define Y_CHAIN_POS -1 - #define Y_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Y2) - #define Y2_MICROSTEPS Y_MICROSTEPS - #define Y2_OVERCURRENT 2000 - #define Y2_STALLCURRENT 1500 - #define Y2_MAX_VOLTAGE 127 - #define Y2_CHAIN_POS -1 - #define Y2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z) - #define Z_MICROSTEPS 128 - #define Z_OVERCURRENT 2000 - #define Z_STALLCURRENT 1500 - #define Z_MAX_VOLTAGE 127 - #define Z_CHAIN_POS -1 - #define Z_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z2) - #define Z2_MICROSTEPS Z_MICROSTEPS - #define Z2_OVERCURRENT 2000 - #define Z2_STALLCURRENT 1500 - #define Z2_MAX_VOLTAGE 127 - #define Z2_CHAIN_POS -1 - #define Z2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z3) - #define Z3_MICROSTEPS Z_MICROSTEPS - #define Z3_OVERCURRENT 2000 - #define Z3_STALLCURRENT 1500 - #define Z3_MAX_VOLTAGE 127 - #define Z3_CHAIN_POS -1 - #define Z3_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z4) - #define Z4_MICROSTEPS Z_MICROSTEPS - #define Z4_OVERCURRENT 2000 - #define Z4_STALLCURRENT 1500 - #define Z4_MAX_VOLTAGE 127 - #define Z4_CHAIN_POS -1 - #define Z4_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(I) - #define I_MICROSTEPS 128 - #define I_OVERCURRENT 2000 - #define I_STALLCURRENT 1500 - #define I_MAX_VOLTAGE 127 - #define I_CHAIN_POS -1 - #define I_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(J) - #define J_MICROSTEPS 128 - #define J_OVERCURRENT 2000 - #define J_STALLCURRENT 1500 - #define J_MAX_VOLTAGE 127 - #define J_CHAIN_POS -1 - #define J_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(K) - #define K_MICROSTEPS 128 - #define K_OVERCURRENT 2000 - #define K_STALLCURRENT 1500 - #define K_MAX_VOLTAGE 127 - #define K_CHAIN_POS -1 - #define K_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E0) - #define E0_MICROSTEPS 128 - #define E0_OVERCURRENT 2000 - #define E0_STALLCURRENT 1500 - #define E0_MAX_VOLTAGE 127 - #define E0_CHAIN_POS -1 - #define E0_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E1) - #define E1_MICROSTEPS E0_MICROSTEPS - #define E1_OVERCURRENT 2000 - #define E1_STALLCURRENT 1500 - #define E1_MAX_VOLTAGE 127 - #define E1_CHAIN_POS -1 - #define E1_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E2) - #define E2_MICROSTEPS E0_MICROSTEPS - #define E2_OVERCURRENT 2000 - #define E2_STALLCURRENT 1500 - #define E2_MAX_VOLTAGE 127 - #define E2_CHAIN_POS -1 - #define E2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E3) - #define E3_MICROSTEPS E0_MICROSTEPS - #define E3_OVERCURRENT 2000 - #define E3_STALLCURRENT 1500 - #define E3_MAX_VOLTAGE 127 - #define E3_CHAIN_POS -1 - #define E3_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E4) - #define E4_MICROSTEPS E0_MICROSTEPS - #define E4_OVERCURRENT 2000 - #define E4_STALLCURRENT 1500 - #define E4_MAX_VOLTAGE 127 - #define E4_CHAIN_POS -1 - #define E4_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E5) - #define E5_MICROSTEPS E0_MICROSTEPS - #define E5_OVERCURRENT 2000 - #define E5_STALLCURRENT 1500 - #define E5_MAX_VOLTAGE 127 - #define E5_CHAIN_POS -1 - #define E5_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E6) - #define E6_MICROSTEPS E0_MICROSTEPS - #define E6_OVERCURRENT 2000 - #define E6_STALLCURRENT 1500 - #define E6_MAX_VOLTAGE 127 - #define E6_CHAIN_POS -1 - #define E6_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E7) - #define E7_MICROSTEPS E0_MICROSTEPS - #define E7_OVERCURRENT 2000 - #define E7_STALLCURRENT 1500 - #define E7_MAX_VOLTAGE 127 - #define E7_CHAIN_POS -1 - #define E7_SLEW_RATE 1 - #endif - - /** - * Monitor L6470 drivers for error conditions like over temperature and over current. - * In the case of over temperature Marlin can decrease the drive until the error condition clears. - * Other detected conditions can be used to stop the current print. - * Relevant G-codes: - * M906 - I1/2/3/4/5 Set or get motor drive level using axis codes X, Y, Z, E. Report values if no axis codes given. - * I not present or I0 or I1 - X, Y, Z or E0 - * I2 - X2, Y2, Z2 or E1 - * I3 - Z3 or E3 - * I4 - Z4 or E4 - * I5 - E5 - * M916 - Increase drive level until get thermal warning - * M917 - Find minimum current thresholds - * M918 - Increase speed until max or error - * M122 S0/1 - Report driver parameters - */ - //#define MONITOR_L6470_DRIVER_STATUS - - #if ENABLED(MONITOR_L6470_DRIVER_STATUS) - #define KVAL_HOLD_STEP_DOWN 1 - //#define L6470_STOP_ON_ERROR - #endif - -#endif // HAS_L64XX - -// @section i2cbus - -// -// I2C Master ID for LPC176x LCD and Digital Current control -// Does not apply to other peripherals based on the Wire library. -// -//#define I2C_MASTER_ID 1 // Set a value from 0 to 2 - -/** - * 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 - */ - -//#define EXPERIMENTAL_I2CBUS -#if ENABLED(EXPERIMENTAL_I2CBUS) - #define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave -#endif - -// @section extras - -/** - * Photo G-code - * Add the M240 G-code to take a photo. - * The photo can be triggered by a digital pin or a physical movement. - */ -//#define PHOTO_GCODE -#if ENABLED(PHOTO_GCODE) - // A position to move to (and raise Z) before taking the photo - //#define PHOTO_POSITION { X_MAX_POS - 5, Y_MAX_POS, 0 } // { xpos, ypos, zraise } (M240 X Y Z) - //#define PHOTO_DELAY_MS 100 // (ms) Duration to pause before moving back (M240 P) - //#define PHOTO_RETRACT_MM 6.5 // (mm) E retract/recover for the photo move (M240 R S) - - // Canon RC-1 or homebrew digital camera trigger - // Data from: https://www.doc-diy.net/photo/rc-1_hacked/ - //#define PHOTOGRAPH_PIN 23 - - // Canon Hack Development Kit - // https://captain-slow.dk/2014/03/09/3d-printing-timelapses/ - //#define CHDK_PIN 4 - - // Optional second move with delay to trigger the camera shutter - //#define PHOTO_SWITCH_POSITION { X_MAX_POS, Y_MAX_POS } // { xpos, ypos } (M240 I J) - - // Duration to hold the switch or keep CHDK_PIN high - //#define PHOTO_SWITCH_MS 50 // (ms) (M240 D) - - /** - * PHOTO_PULSES_US may need adjustment depending on board and camera model. - * Pin must be running at 48.4kHz. - * Be sure to use a PHOTOGRAPH_PIN which can rise and fall quick enough. - * (e.g., MKS SBase temp sensor pin was too slow, so used P1.23 on J8.) - * - * Example pulse data for Nikon: https://bit.ly/2FKD0Aq - * IR Wiring: https://git.io/JvJf7 - */ - //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4kHz oscillation - #ifdef PHOTO_PULSES_US - #define PHOTO_PULSE_DELAY_US 13 // (µs) Approximate duration of each HIGH and LOW pulse in the oscillation - #endif -#endif - -/** - * 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 https://marlinfw.org/docs/configuration/2.0.9/laser_spindle.html for more config details. - */ -//#define SPINDLE_FEATURE -//#define LASER_FEATURE -#if EITHER(SPINDLE_FEATURE, LASER_FEATURE) - #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH - - #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower - #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC) - // ESP32: If SPINDLE_LASER_PWM_PIN is onboard then <=78125Hz. For I2S expander - // the frequency determines the PWM resolution. 2500Hz = 0-100, 977Hz = 0-255, ... - // (250000 / SPINDLE_LASER_FREQUENCY) = max value. - #endif - - //#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11 - #if ENABLED(AIR_EVACUATION) - #define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH - //#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin - #endif - - //#define AIR_ASSIST // Air Assist control with G-codes M8-M9 - #if ENABLED(AIR_ASSIST) - #define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin - //#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin - #endif - - //#define SPINDLE_SERVO // A servo converting an angle to spindle power - #ifdef SPINDLE_SERVO - #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control - #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle - #endif - - /** - * Speed / Power can be set ('M3 S') and displayed in terms of: - * - PWM255 (S0 - S255) - * - PERCENT (S0 - S100) - * - RPM (S0 - S50000) Best for use with a spindle - * - SERVO (S0 - S180) - */ - #define CUTTER_POWER_UNIT PWM255 - - /** - * Relative Cutter Power - * Normally, 'M3 O' sets - * OCR power is relative to the range SPEED_POWER_MIN...SPEED_POWER_MAX. - * so input powers of 0...255 correspond to SPEED_POWER_MIN...SPEED_POWER_MAX - * instead of normal range (0 to SPEED_POWER_MAX). - * Best used with (e.g.) SuperPID router controller: S0 = 5,000 RPM and S255 = 30,000 RPM - */ - //#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] - - #if ENABLED(SPINDLE_FEATURE) - //#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction - #define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction - #define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed - - #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power - #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop - - /** - * M3/M4 Power Equation - * - * Each tool uses different value ranges for speed / power control. - * These parameters are used to convert between tool power units and PWM. - * - * Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE - * PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE - */ - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage - #define SPEED_POWER_MIN 5000 // (RPM) - #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM - #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments) - #endif - - #else - - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage - #define SPEED_POWER_MIN 0 // (%) 0-100 - #define SPEED_POWER_MAX 100 // (%) 0-100 - #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments) - #endif - - // Define the minimum and maximum test pulse time values for a laser test fire function - #define LASER_TEST_PULSE_MIN 1 // (ms) Used with Laser Control Menu - #define LASER_TEST_PULSE_MAX 999 // (ms) Caution: Menu may not show more than 3 characters - - #define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power - #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop - - /** - * Laser Safety Timeout - * - * The laser should be turned off when there is no movement for a period of time. - * Consider material flammability, cut rate, and G-code order when setting this - * value. Too low and it could turn off during a very slow move; too high and - * the material could ignite. - */ - #define LASER_SAFETY_TIMEOUT_MS 1000 // (ms) - - /** - * Any M3 or G1/2/3/5 command with the 'I' parameter enables continuous inline power mode. - * - * e.g., 'M3 I' enables continuous inline power which is processed by the planner. - * Power is stored in move blocks and applied when blocks are processed by the Stepper ISR. - * - * 'M4 I' sets dynamic mode which uses the current feedrate to calculate a laser power OCR value. - * - * Any move in dynamic mode will use the current feedrate to calculate the laser power. - * Feed rates are set by the F parameter of a move command e.g. G1 X0 Y10 F6000 - * Laser power would be calculated by bit shifting off 8 LSB's. In binary this is div 256. - * The calculation gives us ocr values from 0 to 255, values over F65535 will be set as 255 . - * More refined power control such as compesation for accell/decell will be addressed in future releases. - * - * M5 I clears inline mode and set power to 0, M5 sets the power output to 0 but leaves inline mode on. - */ - - /** - * Enable M3 commands for laser mode inline power planner syncing. - * This feature enables any M3 S-value to be injected into the block buffers while in - * CUTTER_MODE_CONTINUOUS. The option allows M3 laser power to be commited without waiting - * for a planner syncronization - */ - //#define LASER_POWER_SYNC - - /** - * Scale the laser's power in proportion to the movement rate. - * - * - Sets the entry power proportional to the entry speed over the nominal speed. - * - Ramps the power up every N steps to approximate the speed trapezoid. - * - Due to the limited power resolution this is only approximate. - */ - //#define LASER_POWER_TRAP - - // - // Laser I2C Ammeter (High precision INA226 low/high side module) - // - //#define I2C_AMMETER - #if ENABLED(I2C_AMMETER) - #define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range - #define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value - #endif - - // - // Laser Coolant Flow Meter - // - //#define LASER_COOLANT_FLOW_METER - #if ENABLED(LASER_COOLANT_FLOW_METER) - #define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21) - #define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin - #define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds - #define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below - #if ENABLED(FLOWMETER_SAFETY) - #define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled - #endif - #endif - - #endif -#endif // SPINDLE_FEATURE || LASER_FEATURE - -/** - * Synchronous Laser Control with M106/M107 - * - * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing - * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan - * header (as with some add-on laser kits). Enable this option to set fan/laser - * speeds with much more exact timing for improved print fidelity. - * - * NOTE: This option sacrifices some cooling fan speed options. - */ -//#define LASER_SYNCHRONOUS_M106_M107 - -/** - * Coolant Control - * - * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off. - * - * Note: COOLANT_MIST_PIN and/or COOLANT_FLOOD_PIN must also be defined. - */ -//#define COOLANT_CONTROL -#if ENABLED(COOLANT_CONTROL) - #define COOLANT_MIST // Enable if mist coolant is present - #define COOLANT_FLOOD // Enable if flood coolant is present - #define COOLANT_MIST_INVERT false // Set "true" if the on/off function is reversed - #define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed -#endif - -/** - * 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 - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor. :[0,1,2,3,4] - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define FILWIDTH_ERROR_MARGIN 1.0 // (mm) If a measurement differs too much from nominal width ignore it - #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 - -/** - * Power Monitor - * Monitor voltage (V) and/or current (A), and -when possible- power (W) - * - * Read and configure with M430 - * - * The current sensor feeds DC voltage (relative to the measured current) to an analog pin - * The voltage sensor feeds DC voltage (relative to the measured voltage) to an analog pin - */ -//#define POWER_MONITOR_CURRENT // Monitor the system current -//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage - -#if ENABLED(POWER_MONITOR_CURRENT) - #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! - #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current - #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) -#endif - -#if ENABLED(POWER_MONITOR_VOLTAGE) - #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! - #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage -#endif - -/** - * Stepper Driver Anti-SNAFU Protection - * - * If the SAFE_POWER_PIN is defined for your board, Marlin will check - * that stepper drivers are properly plugged in before applying power. - * Disable protection if your stepper drivers don't support the feature. - */ -//#define DISABLE_DRIVER_SAFE_POWER_PROTECT - -/** - * CNC Coordinate Systems - * - * Enables G53 and G54-G59.3 commands to select coordinate systems - * and G92.1 to reset the workspace to native machine space. - */ -//#define CNC_COORDINATE_SYSTEMS - -/** - * Auto-report fan speed with M123 S - * Requires fans with tachometer pins - */ -//#define AUTO_REPORT_FANS - -/** - * Auto-report temperatures with M155 S - */ -#define AUTO_REPORT_TEMPERATURES -#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT - //#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report -#endif - -/** - * Auto-report position with M154 S - */ -//#define AUTO_REPORT_POSITION - -/** - * Include capabilities in M115 output - */ -#define EXTENDED_CAPABILITIES_REPORT -#if ENABLED(EXTENDED_CAPABILITIES_REPORT) - //#define M115_GEOMETRY_REPORT -#endif - -/** - * Expected Printer Check - * Add the M16 G-code to compare a string to the MACHINE_NAME. - * M16 with a non-matching string causes the printer to halt. - */ -//#define EXPECTED_PRINTER_CHECK - -/** - * Disable all Volumetric extrusion options - */ -//#define NO_VOLUMETRICS - -#if DISABLED(NO_VOLUMETRICS) - /** - * 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 (and enable volumetric). - * M200 S0/S1 to disable/enable volumetric extrusion. - */ - //#define VOLUMETRIC_DEFAULT_ON - - //#define VOLUMETRIC_EXTRUDER_LIMIT - #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - /** - * Default volumetric extrusion limit in cubic mm per second (mm^3/sec). - * This factory setting applies to all extruders. - * Use 'M200 [T] L' to override and 'M502' to reset. - * A non-zero value activates Volume-based Extrusion Limiting. - */ - #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 // (mm^3/sec) - #endif -#endif - -/** - * 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 - -// Extra options for the M114 "Current Position" report -//#define M114_DETAIL // Use 'M114` for details to check planner calculations -//#define M114_REALTIME // Real current position based on forward kinematics -//#define M114_LEGACY // M114 used to synchronize on every call. Enable if needed. - -//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others) - -/** - * Spend 28 bytes of SRAM to optimize the G-code parser - */ -#define FASTER_GCODE_PARSER - -#if ENABLED(FASTER_GCODE_PARSER) - //#define GCODE_QUOTED_STRINGS // Support for quoted string parameters -#endif - -// Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack) -//#define MEATPACK_ON_SERIAL_PORT_1 -//#define MEATPACK_ON_SERIAL_PORT_2 - -//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase - -//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW - -/** - * CNC G-code options - * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc. - * Note that G0 feedrates should be used with care for 3D printing (if used at all). - * High feedrates may cause ringing and harm print quality. - */ -//#define PAREN_COMMENTS // Support for parentheses-delimited comments -//#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc. - -// Enable and set a (default) feedrate for all G0 moves -//#define G0_FEEDRATE 3000 // (mm/min) -#ifdef G0_FEEDRATE - //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode -#endif - -/** - * Startup commands - * - * Execute certain G-code commands immediately after power-on. - */ -//#define STARTUP_COMMANDS "M17 Z" - -/** - * G-code Macros - * - * Add G-codes M810-M819 to define and run G-code macros. - * Macros are not saved to EEPROM. - */ -//#define GCODE_MACROS -#if ENABLED(GCODE_MACROS) - #define GCODE_MACROS_SLOTS 5 // Up to 10 may be used - #define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro -#endif - -/** - * User-defined menu items to run custom G-code. - * Up to 25 may be defined, but the actual number is LCD-dependent. - */ - -// Custom Menu: Main Menu -//#define CUSTOM_MENU_MAIN -#if ENABLED(CUSTOM_MENU_MAIN) - //#define CUSTOM_MENU_MAIN_TITLE "Custom Commands" - #define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done" - #define CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK - //#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script - #define CUSTOM_MENU_MAIN_ONLY_IDLE // Only show custom menu when the machine is idle - - #define MAIN_MENU_ITEM_1_DESC "Home & UBL Info" - #define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W" - //#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action - - #define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL - #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) - //#define MAIN_MENU_ITEM_2_CONFIRM - - //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL - //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) - //#define MAIN_MENU_ITEM_3_CONFIRM - - //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" - //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" - //#define MAIN_MENU_ITEM_4_CONFIRM - - //#define MAIN_MENU_ITEM_5_DESC "Home & Info" - //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" - //#define MAIN_MENU_ITEM_5_CONFIRM -#endif - -// Custom Menu: Configuration Menu -//#define CUSTOM_MENU_CONFIG -#if ENABLED(CUSTOM_MENU_CONFIG) - //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" - #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done" - #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK - //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script - #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle - - #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" - #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" - //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action - - #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" - #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" - //#define CONFIG_MENU_ITEM_2_CONFIRM - - //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" - //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" - //#define CONFIG_MENU_ITEM_3_CONFIRM - - //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" - //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" - //#define CONFIG_MENU_ITEM_4_CONFIRM - - //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" - //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" - //#define CONFIG_MENU_ITEM_5_CONFIRM -#endif - -/** - * User-defined buttons to run custom G-code. - * Up to 25 may be defined. - */ -//#define CUSTOM_USER_BUTTONS -#if ENABLED(CUSTOM_USER_BUTTONS) - //#define BUTTON1_PIN -1 - #if PIN_EXISTS(BUTTON1) - #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH. - #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? - #define BUTTON1_GCODE "G28" - #define BUTTON1_DESC "Homing" // Optional string to set the LCD status - #endif - - //#define BUTTON2_PIN -1 - #if PIN_EXISTS(BUTTON2) - #define BUTTON2_HIT_STATE LOW - #define BUTTON2_WHEN_PRINTING false - #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) - #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL - #endif - - //#define BUTTON3_PIN -1 - #if PIN_EXISTS(BUTTON3) - #define BUTTON3_HIT_STATE LOW - #define BUTTON3_WHEN_PRINTING false - #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) - #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL - #endif -#endif - -/** - * Host Action Commands - * - * Define host streamer action commands in compliance with the standard. - * - * See https://reprap.org/wiki/G-code#Action_commands - * Common commands ........ poweroff, pause, paused, resume, resumed, cancel - * G29_RETRY_AND_RECOVER .. probe_rewipe, probe_failed - * - * Some features add reason codes to extend these commands. - * - * Host Prompt Support enables Marlin to use the host for user prompts so - * filament runout and other processes can be managed from the host side. - */ -//#define HOST_ACTION_COMMANDS -#if ENABLED(HOST_ACTION_COMMANDS) - //#define HOST_PAUSE_M76 // Tell the host to pause in response to M76 - //#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback - #if ENABLED(HOST_PROMPT_SUPPORT) - //#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications - #endif - //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start - //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down -#endif - -/** - * Cancel Objects - * - * Implement M486 to allow Marlin to skip objects - */ -//#define CANCEL_OBJECTS -#if ENABLED(CANCEL_OBJECTS) - #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message -#endif - -/** - * I2C position encoders for closed loop control. - * Developed by Chris Barr at Aus3D. - * - * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder - * Github: https://github.com/Aus3D/MagneticEncoder - * - * Supplier: https://aus3d.com.au/magnetic-encoder-module - * Alternative Supplier: https://reliabuild3d.com/ - * - * Reliabuild 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_MICROSTEP // 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_MICROSTEP - #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 behavior. - - #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 4 // (ms) Minimum time between encoder checks. - - // Use a rolling average to identify persistent errors that indicate skips, as opposed to vibration and noise. - #define I2CPE_ERR_ROLLING_AVERAGE - -#endif // I2C_POSITION_ENCODERS - -/** - * Analog Joystick(s) - */ -//#define JOYSTICK -#if ENABLED(JOYSTICK) - #define JOY_X_PIN 5 // RAMPS: Suggested pin A5 on AUX2 - #define JOY_Y_PIN 10 // RAMPS: Suggested pin A10 on AUX2 - #define JOY_Z_PIN 12 // RAMPS: Suggested pin A12 on AUX2 - #define JOY_EN_PIN 44 // RAMPS: Suggested pin D44 on AUX2 - - //#define INVERT_JOY_X // Enable if X direction is reversed - //#define INVERT_JOY_Y // Enable if Y direction is reversed - //#define INVERT_JOY_Z // Enable if Z direction is reversed - - // Use M119 with JOYSTICK_DEBUG to find reasonable values after connecting: - #define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max - #define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 } - #define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 } - //#define JOYSTICK_DEBUG -#endif - -/** - * Mechanical Gantry Calibration - * Modern replacement for the Prusa TMC_Z_CALIBRATION. - * Adds capability to work with any adjustable current drivers. - * Implemented as G34 because M915 is deprecated. - */ -//#define MECHANICAL_GANTRY_CALIBRATION -#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) - #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma - #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move - #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move - //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction - - //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle - //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM - //#define GANTRY_CALIBRATION_COMMANDS_PRE "" - #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position -#endif - -/** - * Instant freeze / unfreeze functionality - * Potentially useful for emergency stop that allows being resumed. - */ -//#define FREEZE_FEATURE -#if ENABLED(FREEZE_FEATURE) - //#define FREEZE_PIN 41 // Override the default (KILL) pin here - #define FREEZE_STATE LOW // State of pin indicating freeze -#endif - -/** - * MAX7219 Debug Matrix - * - * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip as a realtime status display. - * Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. - */ -//#define MAX7219_DEBUG -#if ENABLED(MAX7219_DEBUG) - #define MAX7219_CLK_PIN 64 - #define MAX7219_DIN_PIN 57 - #define MAX7219_LOAD_PIN 44 - - //#define MAX7219_GCODE // Add the M7219 G-code to control the LED matrix - #define MAX7219_INIT_TEST 2 // Test pattern at startup: 0=none, 1=sweep, 2=spiral - #define MAX7219_NUMBER_UNITS 1 // Number of Max7219 units in chain. - #define MAX7219_ROTATE 0 // Rotate the display clockwise (in multiples of +/- 90°) - // connector at: right=0 bottom=-90 top=90 left=180 - //#define MAX7219_REVERSE_ORDER // The individual LED matrix units may be in reversed order - //#define MAX7219_SIDE_BY_SIDE // Big chip+matrix boards can be chained side-by-side - - /** - * 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_PLANNER_HEAD 3 // Show the planner queue head position on this and the next LED matrix row - #define MAX7219_DEBUG_PLANNER_TAIL 5 // Show the planner queue tail position on this and the next LED matrix row - - #define MAX7219_DEBUG_PLANNER_QUEUE 0 // Show the current planner 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 - -/** - * NanoDLP Sync support - * - * Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will - * output a "Z_move_comp" string to enable synchronization with DLP projector exposure. - * This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands. - */ -//#define NANODLP_Z_SYNC -#if ENABLED(NANODLP_Z_SYNC) - //#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z). -#endif - -/** - * Ethernet. Use M552 to enable and set the IP address. - */ -#if HAS_ETHERNET - #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network -#endif - -/** - * WiFi Support (Espressif ESP32 WiFi) - */ -//#define WIFISUPPORT // Marlin embedded WiFi managenent -//#define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib) - -#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT) - //#define WEBSUPPORT // Start a webserver (which may include auto-discovery) - //#define OTASUPPORT // Support over-the-air firmware updates - //#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host - - /** - * To set a default WiFi SSID / Password, create a file called Configuration_Secure.h with - * the following defines, customized for your network. This specific file is excluded via - * .gitignore to prevent it from accidentally leaking to the public. - * - * #define WIFI_SSID "WiFi SSID" - * #define WIFI_PWD "WiFi Password" - */ - //#include "Configuration_Secure.h" // External file with WiFi SSID / Password -#endif - -/** - * Průša Multi-Material Unit (MMU) - * Enable in Configuration.h - * - * These devices allow a single stepper driver on the board to drive - * multi-material feeders with any number of stepper motors. - */ -#if HAS_PRUSA_MMU1 - /** - * This option only allows the multiplexer to switch on tool-change. - * Additional options to configure custom E moves are pending. - * - * 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 inputs - //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs -#elif HAS_PRUSA_MMU2 - // Serial port used for communication with MMU2. - #define MMU2_SERIAL_PORT 2 - - // Use hardware reset for MMU if a pin is defined for it - //#define MMU2_RST_PIN 23 - - // Enable if the MMU2 has 12V stepper motors (MMU2 Firmware 1.0.2 and up) - //#define MMU2_MODE_12V - - // G-code to execute when MMU2 F.I.N.D.A. probe detects filament runout - #define MMU2_FILAMENT_RUNOUT_SCRIPT "M600" - - // Add an LCD menu for MMU2 - //#define MMU2_MENUS - #if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S) - // Settings for filament load / unload from the LCD menu. - // This is for Průša MK3-style extruders. Customize for your hardware. - #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 - #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \ - { 7.2, 1145 }, \ - { 14.4, 871 }, \ - { 36.0, 1393 }, \ - { 14.4, 871 }, \ - { 50.0, 198 } - - #define MMU2_RAMMING_SEQUENCE \ - { 1.0, 1000 }, \ - { 1.0, 1500 }, \ - { 2.0, 2000 }, \ - { 1.5, 3000 }, \ - { 2.5, 4000 }, \ - { -15.0, 5000 }, \ - { -14.0, 1200 }, \ - { -6.0, 600 }, \ - { 10.0, 700 }, \ - { -10.0, 400 }, \ - { -50.0, 2000 } - #endif - - /** - * Using a sensor like the MMU2S - * This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S. - * See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11 - */ - #if HAS_PRUSA_MMU2S - #define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries) - - #define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min) - #define MMU2_CAN_LOAD_SEQUENCE \ - { 0.1, MMU2_CAN_LOAD_FEEDRATE }, \ - { 60.0, MMU2_CAN_LOAD_FEEDRATE }, \ - { -52.0, MMU2_CAN_LOAD_FEEDRATE } - - #define MMU2_CAN_LOAD_RETRACT 6.0 // (mm) Keep under the distance between Load Sequence values - #define MMU2_CAN_LOAD_DEVIATION 0.8 // (mm) Acceptable deviation - - #define MMU2_CAN_LOAD_INCREMENT 0.2 // (mm) To reuse within MMU2 module - #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \ - { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE } - - #else - - /** - * MMU1 Extruder Sensor - * - * Support for a Průša (or other) IR Sensor to detect filament near the extruder - * and make loading more reliable. Suitable for an extruder equipped with a filament - * sensor less than 38mm from the gears. - * - * During loading the extruder will stop when the sensor is triggered, then do a last - * move up to the gears. If no filament is detected, the MMU2 can make some more attempts. - * If all attempts fail, a filament runout will be triggered. - */ - //#define MMU_EXTRUDER_SENSOR - #if ENABLED(MMU_EXTRUDER_SENSOR) - #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail - #endif - - #endif - - //#define MMU2_DEBUG // Write debug info to serial output - -#endif // HAS_PRUSA_MMU2 - -/** - * Advanced Print Counter settings - */ -#if ENABLED(PRINTCOUNTER) - #define SERVICE_WARNING_BUZZES 3 - // Activate up to 3 service interval watchdogs - //#define SERVICE_NAME_1 "Service S" - //#define SERVICE_INTERVAL_1 100 // print hours - //#define SERVICE_NAME_2 "Service L" - //#define SERVICE_INTERVAL_2 200 // print hours - //#define SERVICE_NAME_3 "Service 3" - //#define SERVICE_INTERVAL_3 1 // print hours -#endif - -// @section develop - -// -// M100 Free Memory Watcher to debug memory usage -// -//#define M100_FREE_MEMORY_WATCHER - -// -// M42 - Set pin states -// -//#define DIRECT_PIN_CONTROL - -// -// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe -// -//#define PINS_DEBUGGING - -// Enable Marlin dev mode which adds some special commands -//#define MARLIN_DEV_MODE - -#if ENABLED(MARLIN_DEV_MODE) - /** - * D576 - Buffer Monitoring - * To help diagnose print quality issues stemming from empty command buffers. - */ - //#define BUFFER_MONITORING -#endif - -/** - * Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial. - * When running in the debugger it will break for debugging. This is useful to help understand - * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash. - */ -//#define POSTMORTEM_DEBUGGING - -/** - * Software Reset options - */ -//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller -//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL - -// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR. -//#define OPTIBOOT_RESET_REASON diff --git a/Makefile b/Makefile deleted file mode 100644 index b39e760..0000000 --- a/Makefile +++ /dev/null @@ -1,1035 +0,0 @@ -# Marlin Firmware Arduino Project Makefile -# -# Makefile Based on: -# Arduino 0011 Makefile -# Arduino adaptation by mellis, eighthave, oli.keller -# Marlin adaption by Daid -# Marlin 2.0 support and RELOC_WORKAROUND by @marcio-ao -# -# 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 macOS, 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. Set -# "PROG_MCU" as the AVR part name corresponding to "MCU". You can use the -# following command to get a list of correspondences: `avrdude -c alf -p x` -# Older boards are atmega8 based, newer ones like Arduino Mini, Bluetooth -# or Diecimila have the atmega168. If you're using a LilyPad Arduino, -# change F_CPU to 8000000. If you are using Gen7 electronics, you -# probably need to use 20000000. Either way, you must regenerate -# 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 overridden from -# the command line with, for example, "make HARDWARE_MOTHERBOARD=71" -# -# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use... -# -# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \ -# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino -# -# To compile and upload simply add "upload" to the end of the line... -# -# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \ -# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino upload -# -# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or -# start upload manually (using stk500) like so: -# -# 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 ?= 1020 - -ifeq ($(OS),Windows_NT) - # Windows - ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino - ARDUINO_USER_DIR ?= ${HOME}/Arduino -else - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Linux) - # Linux - ARDUINO_INSTALL_DIR ?= /usr/share/arduino - ARDUINO_USER_DIR ?= ${HOME}/Arduino - endif - ifeq ($(UNAME_S),Darwin) - # Darwin (macOS) - ARDUINO_INSTALL_DIR ?= /Applications/Arduino.app/Contents/Java - ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino - AVR_TOOLS_PATH ?= /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/ - endif -endif - -# Arduino source install directory, and version number -# On most linuxes this will be /usr/share/arduino -ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino -ARDUINO_VERSION ?= 106 - -# The installed Libraries are in the User folder -ARDUINO_USER_DIR ?= ${HOME}/Arduino - -# You can optionally set a path to the avr-gcc tools. -# Requires a trailing slash. For example, /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 Tone is needed (i.e., SPEAKER is defined in Configuration.h) -# Disabling this (and SPEAKER) saves approximately 350 bytes of memory. -TONE ?= 1 - -# This defines if U8GLIB is needed (may require RELOC_WORKAROUND) -U8GLIB ?= 0 - -# This defines whether to include the Trinamic TMCStepper library -TMC ?= 0 - -# This defines whether to include the AdaFruit NeoPixel library -NEOPIXEL ?= 0 - -############ -# Try to automatically determine whether RELOC_WORKAROUND is needed based -# on GCC versions: -# https://www.avrfreaks.net/comment/1789106#comment-1789106 - -CC_MAJ:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC__ | cut -f3 -d\ ) -CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ ) -CC_PATCHLEVEL:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_PATCHLEVEL__ | cut -f3 -d\ ) -CC_VER:=$(shell echo $$(( $(CC_MAJ) * 10000 + $(CC_MIN) * 100 + $(CC_PATCHLEVEL) ))) -ifeq ($(shell test $(CC_VER) -lt 40901 && echo 1),1) - $(warning This GCC version $(CC_VER) is likely broken. Enabling relocation workaround.) - RELOC_WORKAROUND = 1 -endif - -############################################################################ -# 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", ... - -ifeq ($(HARDWARE_MOTHERBOARD),0) - - # No motherboard selected - -# -# RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 -# - -# MEGA/RAMPS up to 1.2 -else ifeq ($(HARDWARE_MOTHERBOARD),1000) - -# RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1010) -# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1011) -# RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) -else ifeq ($(HARDWARE_MOTHERBOARD),1012) -# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1013) -# RAMPS 1.3 (Power outputs: Spindle, Controller Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1014) - -# RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1020) -# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1021) -# RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -else ifeq ($(HARDWARE_MOTHERBOARD),1022) -# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1023) -# RAMPS 1.4 (Power outputs: Spindle, Controller Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1024) - -# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1030) -# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1031) -# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1) -else ifeq ($(HARDWARE_MOTHERBOARD),1032) -# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1033) -# RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) -else ifeq ($(HARDWARE_MOTHERBOARD),1034) - -# -# RAMPS Derivatives - ATmega1280, ATmega2560 -# - -# 3Drag Controller -else ifeq ($(HARDWARE_MOTHERBOARD),1100) -# Velleman K8200 Controller (derived from 3Drag Controller) -else ifeq ($(HARDWARE_MOTHERBOARD),1101) -# Velleman K8400 Controller (derived from 3Drag Controller) -else ifeq ($(HARDWARE_MOTHERBOARD),1102) -# Velleman K8600 Controller (Vertex Nano) -else ifeq ($(HARDWARE_MOTHERBOARD),1103) -# Velleman K8800 Controller (Vertex Delta) -else ifeq ($(HARDWARE_MOTHERBOARD),1104) -# 2PrintBeta BAM&DICE with STK drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1105) -# 2PrintBeta BAM&DICE Due with STK drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1106) -# MKS BASE v1.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1107) -# MKS BASE v1.4 with Allegro A4982 stepper drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1108) -# MKS BASE v1.5 with Allegro A4982 stepper drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1109) -# MKS BASE v1.6 with Allegro A4982 stepper drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1110) -# MKS BASE 1.0 with Heroic HR4982 stepper drivers -else ifeq ($(HARDWARE_MOTHERBOARD),1111) -# MKS GEN v1.3 or 1.4 -else ifeq ($(HARDWARE_MOTHERBOARD),1112) -# MKS GEN L -else ifeq ($(HARDWARE_MOTHERBOARD),1113) -# BigTreeTech or BIQU KFB2.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1114) -# zrib V2.0 (Chinese RAMPS replica) -else ifeq ($(HARDWARE_MOTHERBOARD),1115) -# zrib V5.2 (Chinese RAMPS replica) -else ifeq ($(HARDWARE_MOTHERBOARD),1116) -# Felix 2.0+ Electronics Board (RAMPS like) -else ifeq ($(HARDWARE_MOTHERBOARD),1117) -# Invent-A-Part RigidBoard -else ifeq ($(HARDWARE_MOTHERBOARD),1118) -# Invent-A-Part RigidBoard V2 -else ifeq ($(HARDWARE_MOTHERBOARD),1119) -# Sainsmart 2-in-1 board -else ifeq ($(HARDWARE_MOTHERBOARD),1120) -# Ultimaker -else ifeq ($(HARDWARE_MOTHERBOARD),1121) -# Ultimaker (Older electronics. Pre 1.5.4. This is rare) -else ifeq ($(HARDWARE_MOTHERBOARD),1122) - MCU ?= atmega1280 - PROG_MCU ?= m1280 -# Azteeg X3 -else ifeq ($(HARDWARE_MOTHERBOARD),1123) -# Azteeg X3 Pro -else ifeq ($(HARDWARE_MOTHERBOARD),1124) -# Ultimainboard 2.x (Uses TEMP_SENSOR 20) -else ifeq ($(HARDWARE_MOTHERBOARD),1125) -# Rumba -else ifeq ($(HARDWARE_MOTHERBOARD),1126) -# Raise3D N series Rumba derivative -else ifeq ($(HARDWARE_MOTHERBOARD),1127) -# Rapide Lite 200 (v1, low-cost RUMBA clone with drv) -else ifeq ($(HARDWARE_MOTHERBOARD),1128) -# Formbot T-Rex 2 Plus -else ifeq ($(HARDWARE_MOTHERBOARD),1129) -# Formbot T-Rex 3 -else ifeq ($(HARDWARE_MOTHERBOARD),1130) -# Formbot Raptor -else ifeq ($(HARDWARE_MOTHERBOARD),1131) -# Formbot Raptor 2 -else ifeq ($(HARDWARE_MOTHERBOARD),1132) -# bq ZUM Mega 3D -else ifeq ($(HARDWARE_MOTHERBOARD),1133) -# MakeBoard Mini v2.1.2 by MicroMake -else ifeq ($(HARDWARE_MOTHERBOARD),1134) -# TriGorilla Anycubic version 1.3-based on RAMPS EFB -else ifeq ($(HARDWARE_MOTHERBOARD),1135) -# ... Ver 1.4 -else ifeq ($(HARDWARE_MOTHERBOARD),1136) -# ... Rev 1.1 (new servo pin order) -else ifeq ($(HARDWARE_MOTHERBOARD),1137) -# Creality: Ender-4, CR-8 -else ifeq ($(HARDWARE_MOTHERBOARD),1138) -# Creality: CR10S, CR20, CR-X -else ifeq ($(HARDWARE_MOTHERBOARD),1139) -# Dagoma F5 -else ifeq ($(HARDWARE_MOTHERBOARD),1140) -# FYSETC F6 1.3 -else ifeq ($(HARDWARE_MOTHERBOARD),1141) -# FYSETC F6 1.4 -else ifeq ($(HARDWARE_MOTHERBOARD),1142) -# Wanhao Duplicator i3 Plus -else ifeq ($(HARDWARE_MOTHERBOARD),1143) -# VORON Design -else ifeq ($(HARDWARE_MOTHERBOARD),1144) -# Tronxy TRONXY-V3-1.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1145) -# Z-Bolt X Series -else ifeq ($(HARDWARE_MOTHERBOARD),1146) -# TT OSCAR -else ifeq ($(HARDWARE_MOTHERBOARD),1147) -# Overlord/Overlord Pro -else ifeq ($(HARDWARE_MOTHERBOARD),1148) -# ADIMLab Gantry v1 -else ifeq ($(HARDWARE_MOTHERBOARD),1149) -# ADIMLab Gantry v2 -else ifeq ($(HARDWARE_MOTHERBOARD),1150) -# BIQU Tango V1 -else ifeq ($(HARDWARE_MOTHERBOARD),1151) -# MKS GEN L V2 -else ifeq ($(HARDWARE_MOTHERBOARD),1152) -# MKS GEN L V2.1 -else ifeq ($(HARDWARE_MOTHERBOARD),1153) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1154) -# Ortur 4 -else ifeq ($(HARDWARE_MOTHERBOARD),1155) -# Tenlog D3 Hero IDEX printer -else ifeq ($(HARDWARE_MOTHERBOARD),1156) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1157) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1158) -# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) -else ifeq ($(HARDWARE_MOTHERBOARD),1159) -# Longer LK1 PRO / Alfawise U20 Pro (PRO version) -else ifeq ($(HARDWARE_MOTHERBOARD),1160) -# Longer LKx PRO / Alfawise Uxx Pro (PRO version) -else ifeq ($(HARDWARE_MOTHERBOARD),1161) -# Zonestar zrib V5.3 (Chinese RAMPS replica) -else ifeq ($(HARDWARE_MOTHERBOARD),1162) -# Pxmalion Core I3 -else ifeq ($(HARDWARE_MOTHERBOARD),1163) - -# -# RAMBo and derivatives -# - -# Rambo -else ifeq ($(HARDWARE_MOTHERBOARD),1200) -# Mini-Rambo -else ifeq ($(HARDWARE_MOTHERBOARD),1201) -# Mini-Rambo 1.0a -else ifeq ($(HARDWARE_MOTHERBOARD),1202) -# Einsy Rambo -else ifeq ($(HARDWARE_MOTHERBOARD),1203) -# Einsy Retro -else ifeq ($(HARDWARE_MOTHERBOARD),1204) -# abee Scoovo X9H -else ifeq ($(HARDWARE_MOTHERBOARD),1205) -# Rambo ThinkerV2 -else ifeq ($(HARDWARE_MOTHERBOARD),1206) - -# -# Other ATmega1280, ATmega2560 -# - -# Cartesio CN Controls V11 -else ifeq ($(HARDWARE_MOTHERBOARD),1300) -# Cartesio CN Controls V12 -else ifeq ($(HARDWARE_MOTHERBOARD),1301) -# Cartesio CN Controls V15 -else ifeq ($(HARDWARE_MOTHERBOARD),1302) -# Cheaptronic v1.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1303) -# Cheaptronic v2.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1304) -# Makerbot Mightyboard Revision E -else ifeq ($(HARDWARE_MOTHERBOARD),1305) -# Megatronics -else ifeq ($(HARDWARE_MOTHERBOARD),1306) -# Megatronics v2.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1307) -# Megatronics v3.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1308) -# Megatronics v3.1 -else ifeq ($(HARDWARE_MOTHERBOARD),1309) -# Megatronics v3.2 -else ifeq ($(HARDWARE_MOTHERBOARD),1310) -# Elefu Ra Board (v3) -else ifeq ($(HARDWARE_MOTHERBOARD),1311) -# Leapfrog -else ifeq ($(HARDWARE_MOTHERBOARD),1312) -# Mega controller -else ifeq ($(HARDWARE_MOTHERBOARD),1313) -# Geeetech GT2560 Rev A -else ifeq ($(HARDWARE_MOTHERBOARD),1314) -# Geeetech GT2560 Rev A+ (with auto level probe) -else ifeq ($(HARDWARE_MOTHERBOARD),1315) -# Geeetech GT2560 Rev B -else ifeq ($(HARDWARE_MOTHERBOARD),1316) -# Geeetech GT2560 Rev B for A10(M/T/D) -else ifeq ($(HARDWARE_MOTHERBOARD),1317) -# Geeetech GT2560 Rev B for A10(M/T/D) -else ifeq ($(HARDWARE_MOTHERBOARD),1318) -# Geeetech GT2560 Rev B for Mecreator2 -else ifeq ($(HARDWARE_MOTHERBOARD),1319) -# Geeetech GT2560 Rev B for A20(M/T/D) -else ifeq ($(HARDWARE_MOTHERBOARD),1320) -# Einstart retrofit -else ifeq ($(HARDWARE_MOTHERBOARD),1321) -# Wanhao 0ne+ i3 Mini -else ifeq ($(HARDWARE_MOTHERBOARD),1322) -# Leapfrog Xeed 2015 -else ifeq ($(HARDWARE_MOTHERBOARD),1323) -# PICA Shield (original version) -else ifeq ($(HARDWARE_MOTHERBOARD),1324) -# PICA Shield (rev C or later) -else ifeq ($(HARDWARE_MOTHERBOARD),1325) -# Intamsys 4.0 (Funmat HT) -else ifeq ($(HARDWARE_MOTHERBOARD),1326) -# Malyan M180 Mainboard Version 2 (no display function, direct G-code only) -else ifeq ($(HARDWARE_MOTHERBOARD),1327) -# Geeetech GT2560 Rev B for A20(M/T/D) -else ifeq ($(HARDWARE_MOTHERBOARD),1328) -# Mega controller & Protoneer CNC Shield V3.00 -else ifeq ($(HARDWARE_MOTHERBOARD),1329) - -# -# ATmega1281, ATmega2561 -# - -# Minitronics v1.0/1.1 -else ifeq ($(HARDWARE_MOTHERBOARD),1400) - MCU ?= atmega1281 - PROG_MCU ?= m1281 -# Silvergate v1.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1401) - MCU ?= atmega1281 - PROG_MCU ?= m1281 - -# -# Sanguinololu and Derivatives - ATmega644P, ATmega1284P -# - -# Sanguinololu < 1.2 -else ifeq ($(HARDWARE_MOTHERBOARD),1500) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Sanguinololu 1.2 and above -else ifeq ($(HARDWARE_MOTHERBOARD),1501) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Melzi -else ifeq ($(HARDWARE_MOTHERBOARD),1502) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Melzi V2.0 -else ifeq ($(HARDWARE_MOTHERBOARD),1503) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Melzi with ATmega1284 (MaKr3d version) -else ifeq ($(HARDWARE_MOTHERBOARD),1504) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Melzi Creality3D board (for CR-10 etc) -else ifeq ($(HARDWARE_MOTHERBOARD),1505) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Melzi Malyan M150 board -else ifeq ($(HARDWARE_MOTHERBOARD),1506) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Tronxy X5S -else ifeq ($(HARDWARE_MOTHERBOARD),1507) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# STB V1.1 -else ifeq ($(HARDWARE_MOTHERBOARD),1508) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Azteeg X1 -else ifeq ($(HARDWARE_MOTHERBOARD),1509) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# Anet 1.0 (Melzi clone) -else ifeq ($(HARDWARE_MOTHERBOARD),1510) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p -# ZoneStar ZMIB V2 -else ifeq ($(HARDWARE_MOTHERBOARD),1511) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega1284p - PROG_MCU ?= m1284p - -# -# Other ATmega644P, ATmega644, ATmega1284P -# - -# Gen3 Monolithic Electronics -else ifeq ($(HARDWARE_MOTHERBOARD),1600) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Gen3+ -else ifeq ($(HARDWARE_MOTHERBOARD),1601) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Gen6 -else ifeq ($(HARDWARE_MOTHERBOARD),1602) - HARDWARE_VARIANT ?= Gen6 - MCU ?= atmega644p - PROG_MCU ?= m644p -# Gen6 deluxe -else ifeq ($(HARDWARE_MOTHERBOARD),1603) - HARDWARE_VARIANT ?= Gen6 - MCU ?= atmega644p - PROG_MCU ?= m644p -# Gen7 custom (Alfons3 Version) -else ifeq ($(HARDWARE_MOTHERBOARD),1604) - HARDWARE_VARIANT ?= Gen7 - MCU ?= atmega644 - PROG_MCU ?= m644 - F_CPU ?= 20000000 -# Gen7 v1.1, v1.2 -else ifeq ($(HARDWARE_MOTHERBOARD),1605) - HARDWARE_VARIANT ?= Gen7 - MCU ?= atmega644p - PROG_MCU ?= m644p - F_CPU ?= 20000000 -# Gen7 v1.3 -else ifeq ($(HARDWARE_MOTHERBOARD),1606) - HARDWARE_VARIANT ?= Gen7 - MCU ?= atmega644p - PROG_MCU ?= m644p - F_CPU ?= 20000000 -# Gen7 v1.4 -else ifeq ($(HARDWARE_MOTHERBOARD),1607) - HARDWARE_VARIANT ?= Gen7 - MCU ?= atmega1284p - PROG_MCU ?= m1284p - F_CPU ?= 20000000 -# Alpha OMCA board -else ifeq ($(HARDWARE_MOTHERBOARD),1608) - HARDWARE_VARIANT ?= SanguinoA - MCU ?= atmega644 - PROG_MCU ?= m644 -# Final OMCA board -else ifeq ($(HARDWARE_MOTHERBOARD),1609) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p -# Sethi 3D_1 -else ifeq ($(HARDWARE_MOTHERBOARD),1610) - HARDWARE_VARIANT ?= Sanguino - MCU ?= atmega644p - PROG_MCU ?= m644p - -# -# Teensyduino - AT90USB1286, AT90USB1286P -# - -# Teensylu -else ifeq ($(HARDWARE_MOTHERBOARD),1700) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# Printrboard (AT90USB1286) -else ifeq ($(HARDWARE_MOTHERBOARD),1701) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# Printrboard Revision F (AT90USB1286) -else ifeq ($(HARDWARE_MOTHERBOARD),1702) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# Brainwave (AT90USB646) -else ifeq ($(HARDWARE_MOTHERBOARD),1703) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb646 - PROG_MCU ?= usb646 -# Brainwave Pro (AT90USB1286) -else ifeq ($(HARDWARE_MOTHERBOARD),1704) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# SAV Mk-I (AT90USB1286) -else ifeq ($(HARDWARE_MOTHERBOARD),1705) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# Teensy++2.0 (AT90USB1286) -else ifeq ($(HARDWARE_MOTHERBOARD),1706) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 -# 5DPrint D8 Driver Board -else ifeq ($(HARDWARE_MOTHERBOARD),1707) - HARDWARE_VARIANT ?= Teensy - MCU ?= at90usb1286 - PROG_MCU ?= usb1286 - -# UltiMachine Archim1 (with DRV8825 drivers) -else ifeq ($(HARDWARE_MOTHERBOARD),3023) - HARDWARE_VARIANT ?= archim - MCPU = cortex-m3 - F_CPU = 84000000 - IS_MCU = 0 -# UltiMachine Archim2 (with TMC2130 drivers) -else ifeq ($(HARDWARE_MOTHERBOARD),3024) - HARDWARE_VARIANT ?= archim - MCPU = cortex-m3 - F_CPU = 84000000 - IS_MCU = 0 -endif - -# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py -# if you are setting this to something other than 16MHz -# Do not put the UL suffix, it's done later on. -# Set to 16Mhz if not yet set. -F_CPU ?= 16000000 - -# Set to microcontroller if IS_MCU not yet set -IS_MCU ?= 1 - -ifeq ($(IS_MCU),1) - # Set to arduino, ATmega2560 if not yet set. - HARDWARE_VARIANT ?= arduino - MCU ?= atmega2560 - PROG_MCU ?= m2560 - - TOOL_PREFIX = avr - MCU_FLAGS = -mmcu=$(MCU) - SIZE_FLAGS = --mcu=$(MCU) -C -else - TOOL_PREFIX = arm-none-eabi - CPU_FLAGS = -mthumb -mcpu=$(MCPU) - SIZE_FLAGS = -A -endif - -# 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 - -# The Makefile for previous versions of Marlin used VPATH for all -# source files, but for Marlin 2.0, we use VPATH only for arduino -# library files. - -VPATH = . -VPATH += $(BUILD_DIR) -VPATH += $(HARDWARE_SRC) - -ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino)) - # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI - # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src -endif - -ifeq ($(IS_MCU),1) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino - - # Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial - # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src -endif - -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src - -ifeq ($(LIQUID_TWI2), 1) - WIRE = 1 - VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2 -endif -ifeq ($(WIRE), 1) - # Old libraries (avr-core 1.6.21 / Arduino < 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/utility - # New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8) - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src/utility -endif -ifeq ($(NEOPIXEL), 1) -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel -endif -ifeq ($(U8GLIB), 1) -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/csrc -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/cppsrc -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/fntsrc -endif -ifeq ($(TMC), 1) -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src -VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src/source -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 += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/variants/sanguino -else ifeq ($(HARDWARE_VARIANT), archim) - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/libsam - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/CMSIS/Include/ - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/Device/ATMEL/ - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/avr - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/USB - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/Wire/src - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/SPI/src - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/U8glib/src/clib - VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim - LDSCRIPT = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/linker_scripts/gcc/flash.ld - LDLIBS = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/libsam_sam3x8e_gcc_rel.a -else - HARDWARE_SUB_VARIANT ?= standard - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT) -endif - -LIB_SRC = wiring.c \ - wiring_analog.c wiring_digital.c \ - wiring_shift.c WInterrupts.c hooks.c - -ifeq ($(HARDWARE_VARIANT), archim) - LIB_ASRC += wiring_pulse_asm.S -else - LIB_SRC += wiring_pulse.c -endif - -ifeq ($(HARDWARE_VARIANT), Teensy) - LIB_SRC = wiring.c - VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy -endif - -LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp - -ifeq ($(NEOPIXEL), 1) - LIB_CXXSRC += Adafruit_NeoPixel.cpp -endif - -ifeq ($(LIQUID_TWI2), 0) - LIB_CXXSRC += LiquidCrystal.cpp -else - LIB_SRC += twi.c - LIB_CXXSRC += Wire.cpp LiquidTWI2.cpp -endif - -ifeq ($(WIRE), 1) - LIB_SRC += twi.c - LIB_CXXSRC += Wire.cpp -endif - -ifeq ($(TONE), 1) - LIB_CXXSRC += Tone.cpp -endif - -ifeq ($(U8GLIB), 1) - LIB_CXXSRC += U8glib.cpp - LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c \ - u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c \ - u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c -endif - -ifeq ($(TMC), 1) - LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp \ - CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp \ - DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp \ - SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp \ - TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp -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) - LIB_CXXSRC += main.cpp -else - LIB_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)$(TOOL_PREFIX)-gcc -CXX = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-g++ -OBJCOPY = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objcopy -OBJDUMP = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objdump -AR = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-ar -SIZE = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-size -NM = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-nm -AVRDUDE = avrdude -REMOVE = rm -f -MV = mv -f - -# Place -D or -U options here -CDEFS = -DF_CPU=$(F_CPU)UL ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION) -CXXDEFS = $(CDEFS) - -ifeq ($(HARDWARE_VARIANT), Teensy) - CDEFS += -DUSB_SERIAL - LIB_SRC += usb.c pins_teensy.c - LIB_CXXSRC += usb_api.cpp - -else ifeq ($(HARDWARE_VARIANT), archim) - CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ - CDEFS += -DUSB_VID=0x27B1 -DUSB_PID=0x0001 -DUSBCON - CDEFS += '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"' - - LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp \ - UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp \ - PluggableUSB.cpp USBCore.cpp - - LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c - - ifeq ($(U8GLIB), 1) - LIB_SRC += u8g_com_api.c u8g_pb32h1.c - endif -endif - -# Add all the source directories as include directories too -CINCS = ${addprefix -I ,${VPATH}} -CXXINCS = ${addprefix -I ,${VPATH}} - -# Silence warnings for library code (won't work for .h files, unfortunately) -LIBWARN = -w -Wno-packed-bitfield-compat - -# Compiler flag to set the C/CPP Standard level. -CSTANDARD = -std=gnu99 -CXXSTANDARD = -std=gnu++11 -CDEBUG = -g$(DEBUG) -CWARN = -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -Wno-pragmas -Wunused-parameter -CXXWARN = -Wall -Wno-packed-bitfield-compat -Wno-pragmas -Wunused-parameter -CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \ - -fshort-enums -ffunction-sections -fdata-sections -ifneq ($(HARDWARE_MOTHERBOARD),) - CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD} -endif - -#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) -CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti -CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD) -CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD) -ASFLAGS := $(CDEFS) -#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs - -ifeq ($(HARDWARE_VARIANT), archim) - LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align - LD_SUFFIX = $(LDLIBS) - - LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty - LDFLAGS += -u _lseek -u _read -u _write -u _exit -u kill -u _getpid -else - LD_PREFIX = -Wl,--gc-sections,--relax - LDFLAGS = -lm - CTUNING += -flto -endif - -# 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$(PROG_MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \ - -b$(UPLOAD_RATE) - -# Since Marlin 2.0, the source files may be distributed into several -# different directories, so it is necessary to find them recursively - -SRC = $(shell find src -name '*.c' -type f) -CXXSRC = $(shell find src -name '*.cpp' -type f) - -# Define all object files. -OBJ = ${patsubst %.c, $(BUILD_DIR)/arduino/%.o, ${LIB_SRC}} -OBJ += ${patsubst %.cpp, $(BUILD_DIR)/arduino/%.o, ${LIB_CXXSRC}} -OBJ += ${patsubst %.S, $(BUILD_DIR)/arduino/%.o, ${LIB_ASRC}} -OBJ += ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}} -OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}} - -# Define all listing files. -LST = $(LIB_ASRC:.S=.lst) $(LIB_CXXSRC:.cpp=.lst) $(LIB_SRC:.c=.lst) - -# Combine all necessary flags and optional flags. -# Add target processor to flags. -ALL_CFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(CFLAGS) -I. -ALL_CXXFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(CXXFLAGS) -ALL_ASFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(ASFLAGS) -x assembler-with-cpp - -# set V=1 (eg, "make V=1") to print the full commands etc. -ifneq ($V,1) - Pecho=@echo - P=@ -else - Pecho=@: - P= -endif - -# Create required build hierarchy if it does not exist - -$(shell mkdir -p $(dir $(OBJ))) - -# Default target. -all: sizeafter - -build: elf hex bin - -elf: $(BUILD_DIR)/$(TARGET).elf -bin: $(BUILD_DIR)/$(TARGET).bin -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) $(SIZE_FLAGS) $(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 .bin -.PRECIOUS: .o - -.elf.hex: - $(Pecho) " COPY $@" - $P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ - -.elf.bin: - $(Pecho) " COPY $@" - $P $(OBJCOPY) -O binary -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 $(CXX) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX) - -# Object files that were found in "src" will be stored in $(BUILD_DIR) -# in directories that mirror the structure of "src" - -$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE) - $(Pecho) " CC $<" - $P $(CC) -MMD -c $(ALL_CFLAGS) $(CWARN) $< -o $@ - -$(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE) - $(Pecho) " CXX $<" - $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $(CXXWARN) $< -o $@ - -# Object files for Arduino libs will be created in $(BUILD_DIR)/arduino - -$(BUILD_DIR)/arduino/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE) - $(Pecho) " CC $<" - $P $(CC) -MMD -c $(ALL_CFLAGS) $(LIBWARN) $< -o $@ - -$(BUILD_DIR)/arduino/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE) - $(Pecho) " CXX $<" - $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $(LIBWARN) $< -o $@ - -$(BUILD_DIR)/arduino/%.o: %.S $(MAKEFILE) - $(Pecho) " CXX $<" - $P $(CXX) -MMD -c $(ALL_ASFLAGS) $< -o $@ - -# Target: clean project. -clean: - $(Pecho) " RMDIR $(BUILD_DIR)/" - $P rm -rf $(BUILD_DIR) - - -.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter - -# Automatically include the dependency files created by gcc --include ${patsubst %.o, %.d, ${OBJ}} diff --git a/Marlin.ino.mega.hex b/Marlin.ino.mega.hex deleted file mode 100644 index 182e06a..0000000 --- a/Marlin.ino.mega.hex +++ /dev/null @@ -1,10345 +0,0 @@ -:100000000C94481E0C94881E0C94881E0C94881E18 -:100010000C94881E0C94881E0C94881E0C94881EC8 -:100020000C94881E0D944B200D944B200D944B2066 -:100030000C94881E0C94881E0C94881E0C94881EA8 -:100040000C94881E0C941A880C94881E0C94881E9C -:100050000C94881E0C947C850C94881E0D94DD1ED7 -:100060000C94881E0C9499DD0C948FDD0C94881EE2 -:100070000C94881E0C94881E0C94881E0C94881E68 -:100080000C94881E0C94881E0C94881E0C94881E58 -:100090000C94881E0C94881E0C94881E0D94271FA7 -:1000A0000C94881E0C94881E0C94881E0C94881E38 -:1000B0000C94881E0C94881E0C94881E0C94881E28 -:1000C0000C94881E0C94881E0C94881E0C94881E18 -:1000D0000C94881E0C94881E0C94881E0C94881E08 -:1000E0000C94881E084AD73B3BCE016E84BCBFFDF2 -:1000F000C12F3D6C74319ABD56833DDA3D00C77FF8 -:1001000011BED9E4BB4C3E916BAAAABE0000008090 -:100110003F05A84CCDB2D44EB93836A9020C50B91F -:10012000918688083CA6AAAA2ABE000000803F004B -:100130000C942C440C941F4E0D94C8090C94BE963C -:100140000C945E270C941C440C942D740C9418444D -:100150000D94B0180C9433CE0D940A1C0C9473605B -:100160000D9475070C94DA220C94EE340C94A230A2 -:100170000C94462E0C946E260C9413CE0D94C30949 -:100180000C9439470C94DE470C946E280C94879697 -:100190000C942A250D94A8180C94AB960D945B072B -:1001A0000C943A2E0C9496260C94FC470C946A25D9 -:1001B0000C94012E0D94251C0C94662D0D94D206E2 -:1001C0000C940C440D9426090C9485270C940E482D -:1001D0000C94D7200C9428230C94C3960C94EFCD48 -:1001E0000C9457CE0C941A480D94671C0C94092952 -:1001F0000C94EB270C9424510C9406560C947628FE -:100200000D94E0090C94CD640D944B070C947E265C -:100210000C94FA480C9401320C9421240C94D32CA5 -:100220000D942E090C946E760C94A7280C944A70A9 -:100230000C943F960C943D750C94D92B0C94CC2BBC -:100240000C94BF270C94F5CB0C94C8260C94F1CBDE -:100250000C94432E0D94F0090C94F6470C94F32063 -:100260000D94D1070C944D2E0D944C070C94583BD3 -:100270000C94F21E0C9432280D948D180C94EF23DC -:100280000C9428440D94C3180C9459CE0C94BE5869 -:100290000C9456260C944B2E0C94A5730C94C920E8 -:1002A0000C9466260C9436470C94372E0D94BF2779 -:1002B0000C94C76F0C9444270C94FA340D94CB180B -:1002C0000C94B0200C9435CE0C944D700D94D9182C -:1002D0000D94831C0C94145F0C942E270C948F2582 -:1002E0000C944F750C9402480C94C6220C94A622D0 -:1002F0000D94731C0C94A8530D94C41C0D940834D5 -:100300000C94312E0C94F4340D94D6090D945C09A0 -:100310000C94B2530C940B370C9486260C94501FFB -:100320000C9419390C9424440D94D1060C948E3BF2 -:100330000C94FC220D94791C0C9408440C94062314 -:100340000D9492180C9422C60C94EF570C940C5CEC -:100350000C94DD2B0C947A280C94532E0C94E126EB -:100360000C94E4470C945E260D94D1180C947228DA -:100370000C94EA470C94C8230C94AC270C94497055 -:100380000C9492740C943F260C94502E0C94742868 -:100390000C9433470C9493960C9492220C94D84767 -:1003A0000C94111F0C948B250C944F450C94AD5359 -:1003B0000C944D3E0D946E070D944C1D0C940CCC7A -:1003C0000D947F090D94A4180C94CFCD0D9446097B -:1003D0000C943A240C9408CC0C9408240C941448E3 -:1003E0000D94B9180D94E9070C947C280D94AC1861 -:1003F0000C9416350C940F350C9495750C9437CEDF -:100400000C944C450C940FCE0C9464630C94E8222D -:100410000D94D5180C9430290C9452450C94F36D1E -:100420000C9420440D94F1090C94F0470D94CD09DF -:100430000C94A1240C94AD740C9499270C94C3CD06 -:100440000D945D080D94621C0D94BD180C945150D0 -:100450000D94A1090C945BCE0C94BE1E0C94A69630 -:100460000C944B270C9428280C948A1E0C949C25E1 -:100470000C942DC50C94342E0C94B7530C9408484E -:100480000D9445080C9411CE0C94635A0C94E771AA -:100490000C9488730C948D2E0D94B3180C94AF2685 -:1004A0000C9476260C94B0220C94142F0C94E52016 -:1004B0000C94444B0C9410440C944E740C94A4244F -:1004C0000C9463250D948E1C0C94402E0C94924C2D -:1004D0000D94E3180C9471270C9478280C94013532 -:1004E0000C942F960C94B5240D94DF180C947E2850 -:1004F0000C9408350C94061F0C943D2E0C94EDCDF5 -:100500000C9414230C94DF2C0D94D0060D94C71872 -:100510000C94262E0C9414440D94A2074E414E497F -:100520004E495459494E46CDCCCC3D0AD7233C17B1 -:10053000B7D13877CC2B329595E6241FB14F0A00FE -:100540000020410000C84200401C4620BCBE4CCAEE -:100550001B0E5AAEC59D741FE0201023102490106E -:10056000A011202210241037B00840048003001F7F -:10057000E02010211023101520112021102110310E -:10058000300840048003001FE03FF03CF03B701F48 -:10059000601EE03DF03BF038700FC0078003001F85 -:1005A000E03FF03EF03CF01AE01EE03EF03EF03E50 -:1005B000F00FC007800300554E4C4F414420464980 -:1005C0004C414D454E54004C4F41442046494C410E -:1005D0004D454E540046494C414D454E54204348EC -:1005E000414E47450041425300504C410045727214 -:1005F0003A207574663820666F6E74206E6F7420B2 -:10060000696E697469616C697A65642E00FFE0FF48 -:10061000D140A0C8A6A22FF80023AC00AF10FFFE67 -:10062000FF05FFD0FFE0FFC1FFD1E240A0C8A6A2B6 -:100630002FF800238127AC00AFFFD0FF64FFD1A5C6 -:10064000FFD0FF64FF64FFD1A4FFD0FF16FFFE427E -:10065000656400456E636C6F73757265002568751F -:100660003A25303268750025303268753A253032C7 -:100670006875002530326875272530326875002589 -:100680006875642025303268753A25303268750007 -:1006900020202020202020002020202000657272B1 -:1006A000006F0557059F0587053FFFF03800703044 -:1006B000FC3020FC102078102030102C00D02E317F -:1006C000D02F7BD02F7BD02E31D02C00D0203010DB -:1006D00020781020FC1030FC303800703FFFF03FD5 -:1006E000FFF03800703186302387102787902F87DE -:1006F000D02F03D020301020781020781020301018 -:100700002F03D02F87D0278790238710318630384A -:1007100000703FFFF01FFFF81FFFF80410400208B1 -:1007200020020820041040082080104100104100E1 -:100730000820800410400000001FFFF81FFFF85041 -:1007400072696E742041626F72746564004D323557 -:1007500020500A4D32340050617573696E672E2E39 -:100760002E004D3234004C6F6164202A004C6F61C2 -:1007700064206D6D00556E6C6F6164202A00556EAB -:100780006C6F6164206D6D0046696C2E2044696158 -:100790002E202A0046696C2E204469612E004520D7 -:1007A000696E206D6D5E3300200820466163740021 -:1007B0002008204D6178002008204D696E004F66AA -:1007C00066004F6E004175746F74656D70004D6901 -:1007D0006E2054726176656C205370656564004DBF -:1007E000696E2056656C6F63697479004D6178207D -:1007F00040205370656564004D6178204520416359 -:1008000063656C004D6178204020416363656C0036 -:1008100054726176656C20416363656C0052657447 -:100820007261637420416363656C00416363656C4E -:1008300000402073746570732F6D6D0041647661A4 -:100840006E6365642053657474696E6773003F005E -:1008500043616E63656C00496E6974004D343238D3 -:1008600000496E697469616C697A6520454550522A -:100870004F4D0046696C616D656E740054656D7016 -:100880006572617475726500544D432044726976D7 -:100890006572730053746570732F6D6D004A756EC9 -:1008A0006374696F6E2044657600416363656C65AF -:1008B000726174696F6E004D617820537065656474 -:1008C00020286D6D2F73290053657420486F6D6566 -:1008D000204F66667365747300436F6E6669677553 -:1008E000726174696F6E005A2052616973650032DB -:1008F0006E64204E6F7A7A6C652040004265640019 -:100900004E6F7A7A6C650046616E2053706565643F -:1009100000436F6E66696775726174696F6E00522D -:100920006573746F72652044656661756C747300DD -:100930004C6F61642053657474696E6773005374FF -:100940006F72652053657474696E677300507265C9 -:1009500068656174202420436F6E6600546F6F6C6D -:10096000204368616E676500546F6F6C204F666648 -:100970007365747300416476616E636564205365CA -:100980007474696E6773004D61696E004D37303263 -:1009900020542564004D36303020423020542564E8 -:1009A000004D373032203B2564004D373031205424 -:1009B0002564004368616E67652046696C616D65FA -:1009C0006E7400556E6C6F61642046696C616D6574 -:1009D0006E74004C6F61642046696C616D656E7465 -:1009E000005072656865617420437573746F6D00A3 -:1009F000507265686561742024004261636B005524 -:100A00006E6C6F6164202A004C6F6164202A004381 -:100A100068616E67652046696C616D656E74202A39 -:100A2000004D61696E00436F6E74696E75650050AC -:100A300075726765206D6F726500524553554D455F -:100A4000204F5054494F4E533A005052494E542073 -:100A50005041555345440020204E6F7A7A6C653AD8 -:100A600020005061726B696E672E2E2E00000057B9 -:100A700061697420666F720066696C616D656E7481 -:100A8000206368616E676500746F207374617274AF -:100A9000005761697420666F720066696C616D65EC -:100AA0006E7420756E6C6F616400004E6F7A7A6CA4 -:100AB000652068656174696E6700506C6561736577 -:100AC00020776169742E2E2E00005072657373209A -:100AD000627574746F6E00746F2068656174206E47 -:100AE0006F7A7A6C650000496E736572742066696E -:100AF0006C616D656E7400616E64207072657373F5 -:100B000020627574746F6E00746F20636F6E746909 -:100B10006E7565005761697420666F720066696C56 -:100B2000616D656E74206C6F616400005072657356 -:100B30007320427574746F6E00746F2072657375E4 -:100B40006D65207072696E7400005761697420666B -:100B50006F72207072696E7400746F2072657375A5 -:100B60006D652E2E2E00005761697420666F72002D -:100B700066696C616D656E742070757267650000E2 -:100B80004D36303020423020542569004D37303109 -:100B900020542569004D37303220542569005669AC -:100BA0006F6C657400496E6469676F00426C7565AF -:100BB00000477265656E0059656C6C6F77004F7207 -:100BC000616E67650052656400576869746500422C -:100BD0006C756520496E74656E736974790047722F -:100BE00065656E20496E74656E736974790052652F -:100BF0006420496E74656E73697479004C454420B5 -:100C0000436F6E74726F6C00437573746F6D204C1C -:100C10006967687473004C69676874205072657303 -:100C20006574730044656661756C74004F66660098 -:100C30004F6E004C6967687473004D61696E003FC8 -:100C4000004261636B0053746F70004E6F204D65FE -:100C5000646961005072696E742066726F6D204D18 -:100C600065646961004368616E6765204D6564690C -:100C700061004D3231004C696768747300436861EC -:100C80006E67652046696C616D656E7400436F6EBA -:100C900066696775726174696F6E0054656D706521 -:100CA000726174757265004D6F74696F6E00526584 -:100CB00073756D65205072696E740054756E6500B1 -:100CC00053746F70205072696E7400506175736553 -:100CD000205072696E7400496E666F2053637265AE -:100CE000656E003F005374617274205072696E74B7 -:100CF0000043616E63656C005072696E74004361FD -:100D00006E6E6F7420656E746572207375626469AF -:100D1000723A200002202E2E004D61696E004D6F48 -:100D2000766520246D6D00302E303235004D6F76A3 -:100D30006520302E316D6D004D6F766520316D6D03 -:100D4000004D6F76652031306D6D002100486F7465 -:100D5000656E6420746F6F20636F6C640042616322 -:100D60006B0050726F63656564004D6F7665202A75 -:100D7000004D6F7665204578747275646572004D1C -:100D80006F76652040004D6F74696F6E0044697323 -:100D900061626C65205374657070657273004D38C4 -:100DA00034004732385A004732385900486F6D6571 -:100DB00020400047323858004175746F20486F6DED -:100DC0006500473238004D6F7665204178697300C1 -:100DD0004D61696E0050726568656174202420421F -:100DE00065640050726568656174202420416C6CF4 -:100DF0000050726568656174202420456E64207E11 -:100E000000507265686561742024207E0054656D11 -:100E1000706572617475726500E905E505436F6F71 -:100E20006C646F776E005072656865617420240091 -:100E300046616E205370656564207E0042656400E3 -:100E40004E6F7A7A6C65207E004D61696E00453286 -:100E5000004531005A005900580045320045310024 -:100E60005A0059004F6666004F6E005800544D43BB -:100E7000204472697665727300537465616C74689E -:100E800043686F7020456E61626C656400537465E1 -:100E90007070696E67204D6F646500447269766595 -:100EA000722043757272656E7400416476616E6380 -:100EB00065642053657474696E677300466C6F7760 -:100EC000207E00466C6F770046616E20537065652A -:100ED00064207E00426564004E6F7A7A6C65207EE5 -:100EE000005370656564004D61696E00000C0F0071 -:100EF000FE07022503BB017FFE08FE08FE05080869 -:100F000006000040F0C88888987810050808060098 -:100F100000C0F88888888888F80505050600012043 -:100F200030F830200508080600002070F820202046 -:100F300020E00509090600FF2070A8A8B88888707D -:100F400020070505070001D86C366CD8050909068D -:100F500000FFF8A88888888888A8F8050A0A06008B -:100F6000FE205050505088A8A88870030303060044 -:100F70000340A040FFFFFFFFFFFFFFFFFFFFFFFF5A -:100F8000FFFFFFFFFFFFFFFFFFFF0000000605FF61 -:100F90000107070602008080808080008003030331 -:100FA000060105A0A0A005060606000050F8505056 -:100FB000F8500509090600FF2070A8A07028A87045 -:100FC00020050707060000C8C810204098980507AC -:100FD0000706000040A0A040A89068010303060295 -:100FE000058080800309090601FF20404080808041 -:100FF0004040200309090601FF8040402020204096 -:10100000408005070706000020A8702070A8200572 -:1010100005050600012020F820200203030601FF39 -:10102000C04080050101060003F80202020601002B -:10103000C0C00507070600000810102040408005CA -:101040000707060000708898A8C88870030707067D -:10105000010040C040404040E00507070600007026 -:101060008808102040F8050707060000F80810302F -:1010700008887005070706000010305090F810101F -:10108000050707060000F880F008088870050707C4 -:10109000060000304080F0888870050707060000D1 -:1010A000F808101020202005070706000070888827 -:1010B0007088887005070706000070888878081017 -:1010C00060020505060100C0C000C0C00206060699 -:1010D00001FFC0C000C0408003050506010120409B -:1010E000804020050303060002F800F8030505060A -:1010F000010180402040800507070600007088102D -:10110000202000200507070600007088B8A8B880D6 -:1011100070050707060000708888F888888805072A -:1011200007060000F04848704848F0050707060029 -:101130000070888080808870050707060000F048EE -:1011400048484848F0050707060000F88080F0800E -:1011500080F8050707060000F88080F08080800591 -:1011600007070600007088808098887005070706CA -:101170000000888888F8888888030707060100E04F -:101180004040404040E005070706000038101010BE -:101190001090600507070600008890A0C0A0908806 -:1011A000050707060000808080808080F80507071B -:1011B00006000088D8A888888888050707060000E8 -:1011C0008888C8A89888880507070600007088885E -:1011D00088888870050707060000F08888F08080FE -:1011E0008005070706000070888888A890680507B2 -:1011F00007060000F08888F0A09088050707060021 -:101200000070888070088870050707060000F820C5 -:10121000202020202005070706000088888888886D -:1012200088700507070600008888888850502005C8 -:10123000070706000088888888A8A85005070706C1 -:10124000000088885020508888050707060000881D -:10125000885020202020050707060000F8081020ED -:101260004080F80309090601FFE0808080808080CB -:1012700080E00507070600008040402010100803AA -:1012800009090601FFE020202020202020E005039E -:10129000030600052050880501010600FEF803033F -:1012A000030601058040200505050600007008784A -:1012B00088780507070600008080F0888888F00598 -:1012C000050506000070808088700507070600008D -:1012D000080878888888780505050600007088F079 -:1012E0008070050707060000304840E04040400598 -:1012F00007070600FE7088888878087005070706CB -:1013000000008080F0888888880307070601004075 -:1013100000C0404040E00409090601FE1000301002 -:10132000101010906005070706000080808890E08C -:101330009088030707060100C04040404040E00598 -:101340000505060000D0A8A8A8A805050506000008 -:10135000B0C88888880505050600007088888870F0 -:101360000507070600FEF0888888F08080050707DB -:101370000600FE78888888780808050505060000BC -:10138000B0C880808005050506000078807008F0F0 -:101390000507070600002020F82020201805050575 -:1013A000060000888888986805050506000088887A -:1013B0008850200505050600008888A8A850050566 -:1013C0000506000088502050880507070600FE88A3 -:1013D000888850204080050505060000F810204050 -:1013E000F80309090601FF204040408040404020AA -:1013F0000109090602FF8080808080808080800350 -:1014000009090601FF80404040204040408005031C -:101410000306000248A890FF486F6D696E6720467A -:1014200061696C6564006F70656E0054524947478E -:1014300045524544003A20007A5F6D696E00795F3D -:101440006D696E00785F6D6178005265706F7274BF -:10145000696E6720656E6473746F70207374617455 -:1014600075730A000000184300009A4200001643FA -:101470000000E6C20000A8C20000000020746F6FE8 -:10148000206C6F6E6720657874727573696F6E205B -:1014900070726576656E7465640A0020636F6C64B3 -:1014A00020657874727573696F6E207072657665E9 -:1014B0006E7465640A00000018430000A8C20000B2 -:1014C00000005761726E696E673A20486F6D696EF1 -:1014D000672042756D702044697669736F72203C95 -:1014E00020310A00020204008085430000214300ED -:1014F0000016430000A0400000A040000000400093 -:10150000000001000000010000800055555500005A -:1015100000400033333300AAAA2A00499224000075 -:10152000002000C7711C0099991900D1451700557A -:101530005515003BB1130024491200111111000090 -:101540000010000F0F0F00E3380E0043790D00CCA0 -:10155000CC0C00C3300C00E8A20B0064210B00AAE5 -:10156000AA0A00703D0A009DD80900427B0900923A -:10157000240900DCD3080088880800104208000015 -:10158000000800F0C1070087870700755007007149 -:101590001C07003EEB0600A1BC0600699006006631 -:1015A000660600703E06006118060017F405007418 -:1015B000D105005BB00500B29005006272050055D0 -:1015C00055050078390500B81E0500050505004ED3 -:1015D000EC040087D40400A1BD040090A7040049D6 -:1015E000920400C17D0400EE690400C75604004463 -:1015F0004404005C3204000821040041100400008F -:101600000004003FF00300F8E0030026D20300C30B -:10161000C30300CCB503003AA803000A9B030038BB -:101620008E0300C08103009F750300D06903005042 -:101630005E03001D53030034480300913D03003353 -:1016400033030016290300381F03009715030030E9 -:101650000C0300030303000BFA020049F10200BA75 -:10166000E802005CE002002DD802002DD0020059F3 -:10167000C80200B0C0020031B90200DAB10200AA0B -:10168000AA0200A0A30200BC9C0200FA9502005C22 -:101690008F0200DF88020082820200457C02002760 -:1016A00076020027700200436A02007C640200D0C8 -:1016B0005E02003F590200C8530200FFFDFCFAF829 -:1016C000F6F4F2F0EEECEAE9E7E5E3E1E0DEDCDA9D -:1016D000D9D7D5D4D2D0CFCDCBCAC8C7C5C3C2C045 -:1016E000BFBDBCBAB9B7B6B4B3B2B0AFADACAAA9BE -:1016F000A8A6A5A4A2A1A09E9D9C9A99989795940E -:101700009392908F8E8D8B8A89888786848382813D -:10171000807F7E7D7B7A797877767574737271704D -:101720006F6E6D6C6B6A6968676665646362616041 -:101730005F5E5D5C5B5A5958585756555453525129 -:1017400050504F4E4D4C4B4A4A49484746464544F7 -:1017500043424241403F3E3E3D3C3B3B3A393838B4 -:1017600037363535343332323130302F2E2E2D2C62 -:101770002B2B2A2929282727262525242323222104 -:101780002120201F1E1E1D1C1C1B1B1A1919181896 -:10179000171616151514131312121111100F0F0E20 -:1017A0000E0D0D0C0C0B0A0A09090808070706069E -:1017B0000505040403030202010000DB0FC93F45D5 -:1017C000BCDA3F8FB30240FCF0274056946140FEE4 -:1017D0004B9B4084A5D840E0231841346A5641E829 -:1017E00059974164DBD5416E271742B4B75542CEB5 -:1017F0001A9742C8AED542B5885A43D40684BFA6CC -:101800005FA7BF7443E0BF10B11AC01C2C58C0E8DA -:10181000F697C0B849D6C04E4E17C124D355C180E3 -:101820002497C1A0B5D5C1121A17C244AE55C278CB -:101830001797C26CACD5C267885AC320746F6F20EB -:101840006C6F6E6720657874727573696F6E207047 -:10185000726576656E7465640A0020636F6C64203F -:10186000657874727573696F6E2070726576656ED7 -:101870007465640A0053657474696E6773205374E9 -:101880006F72656400290A002062797465733B20D9 -:10189000637263200053657474696E6773205374B8 -:1018A0006F726564202800454550524F4D20496EA7 -:1018B000697469616C697A65640A0048617264637D -:1018C0006F6465642044656661756C74205365744B -:1018D00074696E6773204C6F616465640020286DC5 -:1018E0006D290020460020420020480020204D3174 -:1018F00034352053004D6174657269616C206865F0 -:101900006174757020706172616D657465727300C9 -:1019100020204D39303600205431204500205430ED -:101920002045005374657070657220647269766535 -:10193000722063757272656E740020204D353639E1 -:1019400020533100543120450054302045002058A8 -:1019500000447269766572207374657070696E6791 -:10196000206D6F64650020204D3134392043203BC9 -:1019700020556E69747320696E2043656C736975B8 -:10198000730A0054656D70657261747572652055D7 -:101990006E697473002020473231203B004C696E21 -:1019A00065617220556E69747300454550524F4D04 -:1019B000206461746173697A65206572726F722E3A -:1019C0000A00290A002062797465733B2063726300 -:1019D00020002073746F7265642073657474696E7F -:1019E00067732072657472696576656420280020CB -:1019F0002863616C63756C6174656429210A002039 -:101A0000213D2000454550524F4D20435243206D0B -:101A100069736D61746368202D202873746F72651B -:101A2000642920002053697A653A2000496E646574 -:101A3000783A200000007A4300007A430000A04179 -:101A40000000C8428747BC428747BC420000C843E9 -:101A5000E78CC042E8030000E803000064000000D7 -:101A600088130000204D61726C696E3D563836292E -:101A70000A00454550524F4D2076657273696F6E6E -:101A8000206D69736D617463682028454550524F1D -:101A90004D3D0024F4D43050C38E20C2A2401782A2 -:101AA0008B7011127A910D816CD90AA861E108C777 -:101AB000586607615143061E4B5D05C145A7041AD0 -:101AC000411104093D9803713931034036DB026549 -:101AD000339102D4305402802E1D02632CEE017526 -:101AE0002AC501B028A001102781018F2564012B90 -:101AF000244B01E0223401AC211F018D200D018017 -:101B00001FFC00841EED00971DDF00B81CD200E60C -:101B10001BC600201BBC00641AB200B219A8000A40 -:101B200019A0006A189900D117910040178B00B5D1 -:101B300016840031167E00B31579003A157300C77C -:101B4000146F0058146A00EE1366008813630025B2 -:101B5000135E00C7125B006C12570015125400C1CF -:101B600011510070114F0021114B00D61049008D0A -:101B70001047004610440002104200C00F40008091 -:101B80000F3E00420F3C00060F3B00CB0E38009387 -:101B90000E37005C0E3500270E3400F30D3200C105 -:101BA0000D3100900D3000600D2E00320D2D00051E -:101BB0000D2C00D90C2B00AE0C2900850C29005CE3 -:101BC0000C2700350C27000E0C2600E80B2400C45F -:101BD0000B2400A00B23007D0B23005A0B2100399E -:101BE0000B2100180B2000F80A1F00D90A1E00BBA9 -:101BF0000A1E009D0A1D00800A1D00630A1C004782 -:101C00000A1B002C0A1B00110A1A00F7091A00DD32 -:101C1000091900C4091900AB091900920917007BC2 -:101C2000091800630917004C091600360916002030 -:101C30000916000A091500F5081500E0081400CC83 -:101C4000081400B8081400A4081400900813007DBC -:101C50000812006B081300580812004608120034DE -:101C6000081100230811001208110001081100F0EA -:101C7000071000E0071000D0071000C0071000B0E8 -:101C8000070F00A107100091070E0083070F0074D3 -:101C9000070F0065070E0057070E0049070E003BAF -:101CA000070D002E070E0020070D0013070D00067C -:101CB000070D00F9060C00ED060D00E0060C00D43F -:101CC000060C00C8060C00BC060C00B0060C00A4F4 -:101CD000060B0099060C008D060B0082060B0077A0 -:101CE000060B006C060B0061060A0057060B004C41 -:101CF000060A0042060A0038060A002E060A0024D8 -:101D0000060A001A060A001006090007060A00FD66 -:101D1000050900F4050900EB050900E2050900D9F1 -:101D2000050900D0050900C7050900BE050900B571 -:101D3000050800AD050800A50509009C05080094EC -:101D40000508008C050800840508007C050800745F -:101D50000508006C050700650508005D05070056CD -:101D60000508004E05070047050700400508003834 -:101D7000050700310507002A050700230507001C99 -:101D8000050600160507000F0507000805060002F6 -:101D9000050700FB040600F5040700EE040600E852 -:101DA000040600E2040700DB040600D5040600CFA9 -:101DB000040600C9040600C3040600BD040600B7FB -:101DC000040600B1040500AC040600A6040600A049 -:101DD0000405009B04060095040500900406008A93 -:101DE00004050085040500800406007A04050075DA -:101DF000040500700405006B04050066040500611D -:101E00000405005C04050057040500520405004D5C -:101E100004050048040500430405003E0404003A9C -:101E200004050035040500300404002C04050027D7 -:101E3000040400230405001E0404001A0404001610 -:101E4000040500110404000D040400090405000445 -:101E500004040000040400FC030400F8030400F47C -:101E6000030400F0030400EC030400E8030400E4AE -:101E7000030400E0030400DC030400D8030400D4DE -:101E8000030400D0030400CC030400C8030300C50E -:101E900003030024F404D9201BC40C5C0E9804C472 -:101EA000095F0265077101F405F900FB04B30048FE -:101EB000048700C10369005803550003034500BEB1 -:101EC000023A008402310053022A0029022500044C -:101ED000022000E4011C00C8011900AF011700989E -:101EE0000114008401130071011000610110005100 -:101EF000010E0043010D0036010B002B010B0020E9 -:101F0000010B00150109000C01090003010800FB89 -:101F1000000800F3000800EB000700E4000600DE04 -:101F2000000600D8000600D2000600CC000500C75D -:101F3000000500C2000500BD000400B9000400B5A2 -:101F4000000400B1000400AD000400A9000400A5D5 -:101F5000000300A20003009F0004009B0003009800 -:101F60000003009500020093000300900003008D21 -:101F70000002008B0003008800020086000200843B -:101F8000000300810002007F0002007D0002007B50 -:101F90000002007900020077000100760002007460 -:101FA00000020072000100710002006F0002006D6B -:101FB0000001006C0002006A000100690002006775 -:101FC000000100660001006500010064000200627B -:101FD00000010061000100600001005F0002005D7F -:101FE0000001005C0001005B0001005A0001005983 -:101FF0000001005800010057000100560001005583 -:102000000001005400010053000000530001005281 -:1020100000010051000100500001004F0001004E7E -:102020000000004E0001004D0001004C0001004B7B -:102030000000004B0001004A000100490001004877 -:102040000000004800010047000100460000004673 -:10205000000100450000004500010044000100436C -:102060000000004300010042000000420001004166 -:1020700000000041000100400001003F0000003F5F -:102080000001003E0000003E0001003D0000003D58 -:102090000001003C0000003C0000003C0001003B4F -:1020A0000000003B0001003A0000003A0001003946 -:1020B000000000390001003800000038000000383E -:1020C0000001003700000037000100360000003634 -:1020D000000000360001003500000035000000352A -:1020E000000100340000003400000034000100331F -:1020F0000000003300000033000100320000003215 -:102100000000003200010031000000310000003109 -:102110000001003000000030000000300001002FFE -:102120000000002F0000002F0000002F0001002EF3 -:102130000000002E0000002E0001002D0000002DE8 -:102140000000002D0000002D0001002C0000002CDC -:102150000000002C0000002C0001002B0000002BD0 -:102160000000002B0000002B0001002A0000002AC4 -:102170000000002A0000002A0001002900000029B8 -:1021800000000029000000290000002900010028AB -:10219000000000280000002800000028000000289F -:1021A0000001002700000027000000270000002792 -:1021B0000000002700010026000000260000002685 -:1021C0000000002600000026000100250000002578 -:1021D000000000250000002500000025000000256B -:1021E000000100240000002400000024000000245E -:1021F0000000002400010023000000230000002351 -:102200000000002300000023000000230000002342 -:102210000001002200000022000000220000002235 -:102220000000002200000022000100210000002127 -:10223000000000210000002100000021000000211A -:10224000000000210001002000000020000000200C -:1022500000000020000000200000002000000020FE -:10226000000000200001001F0000001F0000001FF0 -:102270000000001F0000001F0000001F0000001FE2 -:102280000001001E0000001E0000001E0000001ED5 -:10229000000000393000003325000087190000B02D -:1022A0000F0000DB080000BD040000740200003FC6 -:1022B00001000020436F756E7420583A00453200CB -:1022C000426564004531004500626564002C20735E -:1022D000797374656D2073746F7070656421204824 -:1022E00065617465725F49443A20004572723A2014 -:1022F0004D415854454D50004D415854454D502086 -:102300007472696767657265640048656174696EB7 -:1023100067204661696C65640048656174696E6731 -:10232000206661696C6564004572723A204D494EC1 -:1023300054454D50004D494E54454D5020747269DE -:1023400067676572656400544845524D414C2052A0 -:10235000554E4157415900546865726D616C205269 -:10236000756E6177617900202F0020400020424087 -:102370003A0020403A00496E76616C6964206578C5 -:102380007472756465720A004163746976652045EC -:10239000787472756465723A20000009121B242D4E -:1023A000363F48415A536C657E7719100B023D3415 -:1023B0002F265158434A757C676E323B2029161FE1 -:1023C000040D7A7368615E574C452B2239300F0635 -:1023D0001D14636A7178474E555C646D767F404981 -:1023E000525B2C253E3708011A137D746F665950D5 -:1023F0004B42353C272E1118030A565F444D727B21 -:1024000060691E170C053A3328214F465D546B62F4 -:102410007970070E151C232A31384148535A656CD0 -:10242000777E09001B122D243F3658514A437C7594 -:102430006E671019020B343D262F737A6168575E60 -:10244000454C3B3229201F160D046A6378714E47B4 -:102450005C55222B3039060F141D252C373E010800 -:10246000131A6D647F7649405B523C352E27181154 -:102470000A03747D666F5059424B171E050C333AA0 -:1024800021285F564D447B7269600E071C152A2374 -:102490003831464F545D626B707900002110422044 -:1024A00063308440A550C660E770088129914AA135 -:1024B0006BB18CC1ADD1CEE1EFF1311210027332AC -:1024C0005222B5529442F772D662399318837BB385 -:1024D0005AA3BDD39CC3FFF3DEE36224433420043C -:1024E0000114E664C774A44485546AA54BB52885D5 -:1024F0000995EEE5CFF5ACC58DD55336722611168C -:102500003006D776F6669556B4465BB77AA7199724 -:102510003887DFF7FEE79DD7BCC7C448E558866813 -:10252000A7784008611802282338CCC9EDD98EE974 -:10253000AFF9488969990AA92BB9F55AD44AB77AEB -:10254000966A711A500A333A122AFDDBDCCBBFFBC4 -:102550009EEB799B588B3BBB1AABA66C877CE44CFB -:10256000C55C222C033C600C411CAEED8FFDECCD14 -:10257000CDDD2AAD0BBD688D499D977EB66ED55ECB -:10258000F44E133E322E511E700E9FFFBEEFDDDF64 -:10259000FCCF1BBF3AAF599F788F8891A981CAB1F0 -:1025A000EBA10CD12DC14EF16FE18010A100C23022 -:1025B000E3200450254046706760B9839893FBA3DD -:1025C000DAB33DC31CD37FE35EF3B1029012F32272 -:1025D000D2323542145277625672EAB5CBA5A8952D -:1025E00089856EF54FE52CD50DC5E234C324A014C2 -:1025F00081046674476424540544DBA7FAB79987BD -:10260000B8975FE77EF71DC73CD7D326F236910611 -:10261000B01657667676154634564CD96DC90EF904 -:102620002FE9C899E9898AB9ABA944586548067861 -:102630002768C018E1088238A3287DCB5CDB3FEB1C -:102640001EFBF98BD89BBBAB9ABB754A545A376AB1 -:10265000167AF10AD01AB32A923A2EFD0FED6CDDEC -:102660004DCDAABD8BADE89DC98D267C076C645C01 -:10267000454CA23C832CE01CC10C1FEF3EFF5DCFFC -:102680007CDF9BAFBABFD98FF89F176E367E554E51 -:10269000745E932EB23ED10EF01E7C3C3E5E2B3D0E -:1026A0003F2F5B5D3B2C2A225C0043616E6E6F7492 -:1026B000206F70656E2073756264697220004D65CD -:1026C00064696120496E6974204661696C005344F5 -:1026D0002063617264206F6B0A006F70656E526FC9 -:1026E0006F74206661696C65640A00766F6C756D45 -:1026F000652E696E6974206661696C65640A004EB6 -:102700006F20534420636172640A000A4D32340022 -:102710004D3233202573002E0A006F70656E2066DF -:1027200061696C65642C2046696C653A20004669D5 -:102730006C652073656C65637465640A0020536979 -:102740007A653A200046696C65206F70656E656435 -:102750003A2000454E4420535542524F5554494E5D -:10276000450A002220706F73002220706172656E2E -:10277000743A2200535542524F5554494E45204316 -:10278000414C4C207461726765743A220053756243 -:1027900063616C6C204F766572666C6F770045786C -:1027A000636565646564206D617820535542524FBE -:1027B0005554494E452064657074683A00577269F3 -:1027C00074696E6720746F2066696C653A200043F7 -:1027D0004F4D4D554E49434154494F4E0044525977 -:1027E00052554E004552524F525300494E464F00EB -:1027F0004543484F004572726F7220777269746961 -:102800006E6720746F20454550524F4D210A00538A -:10281000544F505045442E20005072696E746572BA -:102820002073746F707065642064756520746F2008 -:102830006572726F72732E20466978207468652005 -:102840006572726F7220616E6420757365204D39F8 -:10285000393920746F20726573746172742E202868 -:1028600054656D706572617475726520697320724C -:10287000657365742E2053657420697420616674D5 -:1028800065722072657374617274696E67290A00DB -:102890004E6F20436865636B73756D20776974684C -:1028A000206C696E65206E756D6265722C204C61BE -:1028B0007374204C696E653A20004E6F2043686542 -:1028C000636B73756D2077697468206C696E652021 -:1028D0006E756D6265722C204C617374204C696E4C -:1028E000653A2000636865636B73756D206D69736D -:1028F0006D617463682C204C617374204C696E6543 -:102900003A20004C696E65204E756D6265722069D3 -:1029100073206E6F74204C617374204C696E652057 -:102920004E756D6265722B312C204C617374204C96 -:10293000696E653A20004D3131300053657269612E -:102940006C20737461747573206D69736D61746349 -:10295000680A0053442072656164206572726F7268 -:102960000A004B494C4C20627574746F6E2F70696D -:102970006E0A002121204B494C4C20636175736520 -:10298000642062792000746F6F206D756368206920 -:102990006E6163746976652074696D65202D2063AE -:1029A000757272656E7420636F6D6D616E643A202E -:1029B000002121204B494C4C2063617573656420D4 -:1029C00062792000627573793A207061757365646D -:1029D00020666F7220696E7075740A006275737973 -:1029E0003A2070617573656420666F722075736537 -:1029F000720A00627573793A2070726F636573733F -:102A0000696E670A004D656469612052656D6F7675 -:102A10006564004D6564696120496E736572746513 -:102A20006400506C65617365205265736574005075 -:102A300052494E5445522048414C54454400255378 -:102A40003A202553004B494C4C45442E20005072EF -:102A5000696E7465722068616C7465642E206B69A0 -:102A60006C6C28292063616C6C6564210A00006528 -:102A700063686F3A004572726F723A00486F74650E -:102A80006E6420746F6F20636F6C640A005072650F -:102A9000737320627574746F6E20746F2072657327 -:102AA000756D650A00496E736572742066696C61A4 -:102AB0006D656E7420616E64207072657373206240 -:102AC0007574746F6E0A005072657373206275744A -:102AD000746F6E20746F2068656174206E6F7A7AEF -:102AE0006C650A004C4F570048494748004F4B005F -:102AF0004572726F723A20416C6C200020636F6ED9 -:102B00006E656374696F6E2E2E2E2000546573748B -:102B1000696E6720004C4F570048494748004F4BAB -:102B2000004572726F723A20416C6C200020636F16 -:102B30006E6E656374696F6E2E2E2E200054657361 -:102B400074696E6720004C4F570048494748004F52 -:102B50004B004572726F723A20416C6C200020630A -:102B60006F6E6E656374696F6E2E2E2E2000546535 -:102B70007374696E6720004C4F57004849474800FE -:102B80004F4B004572726F723A20416C6C200020EE -:102B9000636F6E6E656374696F6E2E2E2E20005407 -:102BA000657374696E6720004C4F57004849474869 -:102BB000004F4B004572726F723A20416C6C2000DE -:102BC00020636F6E6E656374696F6E2E2E2E20000B -:102BD00054657374696E672000544D4320434F4E13 -:102BE0004E454354494F4E204552524F52002044C7 -:102BF0000020204D32303020540020204D32303023 -:102C0000205300202844697361626C6564293A008E -:102C100046696C616D656E742073657474696E6766 -:102C2000730020204D3230312058004D6178204112 -:102C30006363656C65726174696F6E2028756E6977 -:102C400074732F7332290020204D32303320580006 -:102C50004D617820666565647261746573202875BE -:102C60006E6974732F73290020520020204D32307A -:102C700034205000416363656C65726174696F6EE6 -:102C80002028756E6974732F7332292028503C7088 -:102C900072696E742D616363656C3E20523C72658F -:102CA00074726163742D616363656C3E20543C747F -:102CB000726176656C2D616363656C3E2900204A04 -:102CC0000020540020530020204D32303520420097 -:102CD000416476616E6365642028423C6D696E5F75 -:102CE0007365676D656E745F74696D655F75733E5E -:102CF00020533C6D696E5F66656564726174653E04 -:102D000020543C6D696E5F74726176656C5F6665B8 -:102D10006564726174653E204A3C6A756E635F64E7 -:102D200065763E290020204D32313700546F6F6C9C -:102D30002D6368616E67696E670020204D323138FF -:102D4000205400486F74656E64206F666673657406 -:102D5000730020440020490020204D3330312050A2 -:102D600000486F74656E6420504944004F46460029 -:102D70004F4E0020204D61783A2000200020204D49 -:102D8000696E3A2000203B200020204D3231312056 -:102D90005300536F667420656E6473746F707300B4 -:102DA000203B00205500204C0020204D36303320A1 -:102DB000540046696C616D656E74206C6F61642FA0 -:102DC000756E6C6F616400737072656164437963E2 -:102DD0006C6500737465616C746843686F70002083 -:102DE000647269766572206D6F64653A090073706C -:102DF000726561644379636C6500737465616C74BA -:102E00006843686F700020647269766572206D6F28 -:102E100064653A09007370726561644379636C6537 -:102E200000737465616C746843686F70002064722D -:102E300069766572206D6F64653A0900737072651A -:102E400061644379636C6500737465616C74684395 -:102E5000686F700020647269766572206D6F6465BA -:102E60003A09007370726561644379636C6500733D -:102E70007465616C746843686F7000206472697671 -:102E80006572206D6F64653A0900202E6873747254 -:102E9000743A2000202E68656E643A200020636832 -:102EA0006F70706572202E746F66663A2000202E57 -:102EB00068737472743A2000202E68656E643A203C -:102EC000002063686F70706572202E746F66663ABA -:102ED0002000202E68737472743A2000202E6865DA -:102EE0006E643A20002063686F70706572202E74E3 -:102EF0006F66663A2000202E68737472743A200060 -:102F0000202E68656E643A20002063686F707065DB -:102F100072202E746F66663A2000202E68737472D9 -:102F2000743A2000202E68656E643A2000206368A1 -:102F30006F70706572202E746F66663A20003F5382 -:102F4000206F7574206F662072616E67652028316E -:102F50002E2E38290A003F50206F7574206F66208E -:102F600072616E676520282D332E2E3132290A00BA -:102F70003F4F206F7574206F662072616E67652009 -:102F800028312E2E3135290A003B200020496E764B -:102F9000616C69642065787472756465722000479D -:102FA000322F47332062616420706172616D6574F5 -:102FB0006572730A00536C6565702E2E2E00436C8B -:102FC00069636B20746F20526573756D652E2E2EAC -:102FD000004E6F204D6F76652E00456E6420666949 -:102FE0006C65206C6973740A00426567696E2066BF -:102FF000696C65206C6973740A004E6F206D65649E -:1030000069610A00286E6F2066696C652900437546 -:103010007272656E742066696C653A2000534420B4 -:103020007072696E74696E67206279746520004EF3 -:103030006F74205344207072696E74696E670A0061 -:103040002E0A0044656C6574696F6E206661696C58 -:1030500065642C2046696C653A200046696C6520E1 -:1030600064656C657465643A005072696E742074AE -:10307000696D653A20000A53746174733A20466999 -:103080006C616D656E7420757365643A20002C2048 -:103090004C6F6E67657374206A6F623A2000546FDC -:1030A00074616C2074696D653A20005374617473A7 -:1030B0003A20002C204661696C65643A20002C207F -:1030C00046696E69736865643A20005072696E746F -:1030D000733A200053746174733A20006F6B006F71 -:1030E000666600F027EB27E427DD27CF274445421B -:1030F00055473A004D3131322053687574646F770B -:103100006E004D3131332053004D616B6572626F3B -:1031100074205265706C696361746F72204F46460B -:103120002E002F2F004D31343520533C696E6465DD -:10313000783E206F7574206F662072616E6765201F -:1031400028302D31290A003F4A206F7574206F66A0 -:103150002072616E67652028302E303120746F2018 -:10316000302E33290A0046523A0020466C6F773AD7 -:103170002000496E76616C696420657874727564AC -:1031800065720A0064697300656E0043290A006174 -:10319000626C656420286D696E2074656D70200016 -:1031A000436F6C6420657874727564657320617216 -:1031B0006520004F666673657473204170706C699A -:1031C0006564004572723A20546F6F206661722107 -:1031D00000546F6F206661722066726F6D20726599 -:1031E000666572656E636520706F696E740A00456E -:1031F0004550524F4D204F4B0A002064726976654E -:10320000722063757272656E743A20002064726970 -:103210007665722063757272656E743A2000206460 -:1032200072697665722063757272656E743A2000F9 -:10323000206472697665722063757272656E743A85 -:103240002000206472697665722063757272656E03 -:10325000743A200020204D323036205800486F6DDF -:1032600065206F6666736574004361703A00434F72 -:103270004E4649475F4558504F5254004D454154C2 -:103280005041434B00434F4F4C45525F54454D50C6 -:1032900045524154555245004348414D4245525FC5 -:1032A00054454D50455241545552450042414259B2 -:1032B0005354455050494E470041524353004D4FDF -:1032C00054494F4E5F4D4F44455300544845524D6D -:1032D000414C5F50524F54454354494F4E0045585E -:1032E00054454E4445445F4D323000435553544F8E -:1032F0004D5F4649524D574152455F55504C4F41E5 -:1033000044004C464E5F5752495445004C4F4E477F -:103310005F46494C454E414D45004155544F52453D -:10332000504F52545F53445F5354415455530053CC -:10333000445F575249544500524550454154004D51 -:10334000554C54495F564F4C554D450053444341ED -:1033500052440050524F4D50545F535550504F52AD -:103360005400484F53545F414354494F4E5F434FBD -:103370004D4D414E445300454D455247454E4359EE -:103380005F50415253455200434153455F4C4947BA -:1033900048545F4252494748544E45535300544F96 -:1033A00047474C455F4C494748545300534F465498 -:1033B000574152455F504F574552004255494C4482 -:1033C0005F50455243454E54004C4556454C494E7E -:1033D000475F44415441005A5F50524F42450052AA -:1033E000554E4F5554004155544F4C4556454C0091 -:1033F0005052494E545F4A4F420050524F47524537 -:103400005353004155544F5245504F52545F544509 -:103410004D50004155544F5245504F52545F504FFC -:103420005300564F4C554D45545249430045455065 -:10343000524F4D0042494E4152595F46494C455FFB -:103440005452414E534645520053455249414C5FF8 -:10345000584F4E5F584F4646004649524D574152CD -:10346000455F4E414D453A4D61726C696E20322E7A -:10347000302E392E352028417072203131203230E3 -:1034800032342031373A30343A31392920534F55CC -:103490005243455F434F44455F55524C3A67697408 -:1034A0006875622E636F6D2F4D61726C696E46692F -:1034B000726D776172652F4D61726C696E2050522A -:1034C0004F544F434F4C5F56455253494F4E3A313C -:1034D0002E30204D414348494E455F545950453A9E -:1034E0004D616B6572626F74205265706C696361C7 -:1034F000746F722045585452554445525F434F559E -:103500004E543A3220555549443A636564653261F8 -:1035100032662D343161322D343734382D396231F1 -:10352000322D6335356336326633363766660A00C8 -:1035300020204D3235302043004C434420436F6EF1 -:103540007472617374004D383400446F6E6520707E -:1035500072696E74696E672066696C650A004D3722 -:1035600037004D3331002569730025696D202569C9 -:1035700073002569682025696D2025697300256918 -:1035800064202569682025696D20256973002569F7 -:103590007920256964202569682025696D202569C1 -:1035A0007300436F6F6C696E672E2E2E0045256386 -:1035B0002025530042656420436F6F6C696E672E4F -:1035C0002E2E004265642048656174696E672E2E58 -:1035D0002E00206661696C65642120426164206868 -:1035E00065617465722069640A0050494420417520 -:1035F000746F74756E650023646566696E6520443A -:10360000454641554C545F004B6420004B692000F7 -:103610004B7020002066696E6973686564212050D4 -:10362000757420746865206C617374204B702C2055 -:103630004B6920616E64204B6420636F6E7374610C -:103640006E74732066726F6D2062656C6F7720698F -:103650006E746F20436F6E66696775726174696F0F -:103660006E2E680A00504944204175746F74756E5F -:103670006500206661696C6564212074696D656F01 -:1036800075740A00504944204175746F74756E65F5 -:1036900000206661696C6564212054656D706572F7 -:1036A000617475726520746F6F20686967680A00BD -:1036B000504944204175746F74756E6500504944DB -:1036C000204379636C65730025532025692F256994 -:1036D00000204B643A2000204B693A2000204B70B8 -:1036E0003A200020436C6173736963205049442081 -:1036F0000A002054753A2000204B753A2000206DB6 -:1037000061783A2000206D696E3A200020643A20EA -:103710000020626961733A200048656174696E67D0 -:103720002E2E2E002073746172740A0050494420BA -:103730004175746F74756E6500206661696C6564AF -:10374000212054656D706572617475726520746FA7 -:103750006F20686967680A00504944204175746F9A -:1037600074756E6500504944204175746F74756EB0 -:1037700065004572723A207574663820666F6E7403 -:10378000206E6F7420696E697469616C697A656412 -:103790002E004572723A207574663820666F6E741A -:1037A000206E6F7420696E697469616C697A6564F2 -:1037B0002E00667265736800646F696E670020662C -:1037C000696C653A20004E6F7720002F6175746F29 -:1037D00025632E670000002100240027002A002D09 -:1037E000003000330001010000040107010A01005C -:1037F000000A0B02090C0D0E08070304010000006B -:1038000000000000000000000000000000000000B8 -:103810000000000000000000000000121110000075 -:103820000000000000000000000000000000000098 -:1038300000000000006D61726C696E66772E6F7219 -:103840006700322E302E392E35001FFFFFFFFFFF9D -:10385000FF600000000001FF400000000000FF804A -:1038600000000000007F83CF00000C303F87FF8006 -:10387000000C301F867980000C000F8C30C7838CC1 -:1038800030E78C30CFC7CC31F38C30DCECEC33B983 -:103890008C30D86C6C33198C30D06C0C33198C3064 -:1038A000D86C0C33198C30DC6C0E3B198C30CF7C0F -:1038B000079F198C30C77C038F194000000000005F -:1038C00002600000000000061FFFFFFFFFFFF8700E -:1038D000012C0190012701B0012201C0011D01F05E -:1038E0000118011002130130020E0160020901905B -:1038F000020401C002FF000003FA004003F500804B -:1039000003F000D003EB002004E6007004E100E0C7 -:1039100004DC004005D700C005D2004006CD00D031 -:1039200006C8008007C3003008BE00F008B900C018 -:1039300009B400B00AAF00B00BAA00D00CA500007B -:103940000EA000500F9B00C0109600501291000076 -:10395000148C00C0158700B0178200B0197D00D00C -:103960001B7800001E730040206E0090226900F05A -:1039700024640040275F0090295A00E02B55001076 -:103980002E500020304B0010324600E033410090B2 -:10399000353C001037370070383200A0392D00B0A8 -:1039A0003A2800A03B2300603C1E00103D19009007 -:1039B0003D1400103E0F00703E0A00C03E0500009E -:1039C0003F0000403FFBFF803FF6FFC03FF1FF207C -:1039D00020506C616E6E65724275666665724279E2 -:1039E0007465733A20002046726565204D656D6FE1 -:1039F00072793A200020436F6D70696C65643A20DB -:103A000041707220313120323032340A00204C6152 -:103A1000737420557064617465643A2032303232B8 -:103A20002D30372D3239207C20417574686F723A01 -:103A3000204D2E2042616B65720A004D61726C69E7 -:103A40006E20322E302E392E350A0020536F6674C8 -:103A5000776172652052657365740A00205761743E -:103A60006368646F672052657365740A0020427250 -:103A70006F776E206F75742052657365740A00202D -:103A800045787465726E616C2052657365740A00C6 -:103A9000506F77657255700A0073746172740A0012 -:103AA000473237004D31303031006F6B0065727234 -:103AB0006F722077726974696E6720746F2066690F -:103AC0006C650A00446F6E6520736176696E6720CD -:103AD00066696C652E0A004D323900456E64737458 -:103AE0006F707300255320256320256320256320F4 -:103AF000256300205A3A0020593A0020583A0065C0 -:103B00006E6473746F7073206869743A20000000EB -:103B100020002300260029002C002F003200000185 -:103B20000000030106010901000022002500280011 -:103B30002B002E00310034000201000005010801B5 -:103B40000B01050505050705080808080202020221 -:103B50000A0A080804040404010101010101010129 -:103B60000303030303030303040707070C0C0C0CF4 -:103B70000C0C0C0C020202020606060606060606DD -:103B80000B0B0B0B0B0B0B0B01021020200808106A -:103B900020401020408002010201080402010102BD -:103BA0000408102040808040201008040201800496 -:103BB00002018040201008040201080402010102F1 -:103BC000040810204080010204081020408001FFFA -:103BD000FF496E736572742066696C616D656E7401 -:103BE00020616E6420707265737320627574746FE7 -:103BF0006E0A00220A00556E6B6E6F776E20636F3F -:103C00006D6D616E643A202200204500205A00202C -:103C1000590020204D3932205800537465707320AC -:103C200070657220756E697400486F6D652025732C -:103C3000257325732046697273740020453A00206D -:103C40005A3A0020593A00583A004D616B65726249 -:103C50006F74205265706C696361746F7220526575 -:103C60006164792E005072696E74696E672E2E2E13 -:103C7000005072696E7420506175736564006F6BDB -:103C80000A00526573656E643A20000056017E0199 -:103C900011241FBECFEFD1E2DEBFCDBF00E00CBFCD -:103CA00084B780930F1914BE0FB6F894A89580912D -:103CB0006000886180936000109260000FBE13E086 -:103CC000A0E0B2E0ECE5F4E802E00BBF02C0079030 -:103CD0000D92AA3FB107D9F729E1AAEFB3E001C0DD -:103CE0001D92AF30B207E1F71EE1C7E4DEE100E06C -:103CF00006C021970109802FFE010F945C41C63454 -:103D0000D10780E00807A9F70F943E2A0D941C42C2 -:103D10000C9400000F931F93CF93DF93809147097A -:103D200090E0EC01CC0FDD1FCC0FDD1F8E010A5D92 -:103D30001D4F880F991FFC01EE5DFD4F6081718161 -:103D4000072E000C880B990B0F94B8392AE037ED39 -:103D500043E25CE30F94173ACA54DA4F2881398161 -:103D60004A815B810F94173AF801608371838283E3 -:103D70009383DF91CF911F910F9108950F931F931C -:103D8000CF93DF938091510990E0EC01CC0FDD1FC0 -:103D9000CC0FDD1F8E010A5D1D4F880F991FFC019E -:103DA000EE5DFD4F60817181072E000C880B990B31 -:103DB0000F94B8392AE037ED43E25CE30F94173AE9 -:103DC000CA54DA4F288139814A815B810F94173AAE -:103DD000F8016083718382839383DF91CF911F9178 -:103DE0000F910895CF93DF93EC01CB01BA010F94AB -:103DF000B8392DEC3CEC4CEC5DE30F94023F0F9492 -:103E00007B3F79836883DF91CF910895E0914709E3 -:103E1000E23030F4F0E0EE52FA4F809136098083C0 -:103E20000895809197178823C1F081508093971748 -:103E3000E4EAF4E1882351F08150990B2BE1289FAB -:103E4000F001299FF00D1124E757F94E8BE1A9E805 -:103E5000B4E101900D928A95E1F720919717211115 -:103E600005C08091A21780648093A21781E090E042 -:103E7000A0E0B0E0211103C080E090E0DC0180937D -:103E80003B0990933C09A0933D09B0933E091092E1 -:103E9000A10581E080939F0583E0809375020895DA -:103EA000CF93DF93EC01CB01BA010F94B8390F9493 -:103EB0007B3F6883DF91CF91089581E080934E0925 -:103EC000089582E080934E0908958F929F92AF9259 -:103ED000BF92CF92DF92EF92FF92CF936B017C0162 -:103EE00020E030E0A9010F94B13987FFA3C06DEB4A -:103EF00077E386E095EBA70196010F94083E6B01EE -:103F00007C0120E030E040E251E40F94173A20E0D9 -:103F100030E048EC52E40F94173A4B015C0120E08A -:103F200030E040E251ECC701B6010F94B1391816E8 -:103F300054F420E030E048EC52E4C701B6010F949D -:103F4000684087FD8BC020E030E0A901C701B601C1 -:103F50000F94B13987FF73C060E070E080EA90ECA5 -:103F6000A50194010F94083E20E030E040E251E4C6 -:103F70000F94023F0F94743F6B017C01F7FC64C007 -:103F800020E137E240E050E00F94C63DCA01B9019C -:103F90002AE030E040E050E00F94C63D605D609361 -:103FA000A305C701B60128EE33E040E050E00F94CE -:103FB000C63D9AE0892E912CA12CB12CCA01B901E1 -:103FC000A50194010F94C63D605D6093A405C701EF -:103FD000B60124E630E040E050E00F94C63DCA014F -:103FE000B901A50194010F94C63D605D6093A505DC -:103FF0008EE28093A605C701B601A50194010F9436 -:10400000C63DC62FCA01B901A50194010F94C63D52 -:10401000605D6093A705C05DC093A80583EA95E045 -:10402000CF91FF90EF90DF90CF90BF90AF909F9097 -:104030008F9008956DEB77E386E095E35CCF60E0C9 -:1040400070E080EA90E48CCFF094E094D094C09437 -:10405000C11CD11CE11CF11C6DE2A1CF20E030E0BD -:10406000A901C701B6010F94B13987FF6AC060E0AA -:1040700070E080EA90ECA50194010F94083E20E0E6 -:1040800030E040E251E40F94023F0F94743F4B0143 -:104090005C0120E030E0A901C701B6010F9468403F -:1040A00087FD0BC020E030E040E251E4C701B601DB -:1040B0000F94B13960E287FD13C0B7FC47C0C5015A -:1040C000B40128EE33E040E050E00F94C63DCA0151 -:1040D000B9012AE030E040E050E00F94C63D605D59 -:1040E0006093A405C501B40124E630E040E050E04F -:1040F0000F94C63D8AE0C82ED12CE12CF12CCA01C8 -:10410000B901A70196010F94C63D605D6093A505B6 -:104110008EE28093A605C501B401A70196010F9414 -:10412000C63DC62FCA01B901A70196010F94C63D2D -:10413000605D6093A705C05DC093A80584EA95E023 -:104140006FCF60E070E080EA90E495CFB094A094E7 -:1041500090948094811C911CA11CB11C6DE2C0CF75 -:10416000CF93DF93EC01CB01BA010F94B83929EC5E -:1041700038EC48EC5EE30F94023F20E030E040E092 -:104180005FE30F94083E0F947B3F6883DF91CF91EC -:104190000895CF93DF93EC01CB01BA010F94B839A6 -:1041A000688379838A839B83DF91CF910895CF932E -:1041B000DF93EC01CB01BA010F94B839688379839E -:1041C0008A839B83DF91CF910895E091470986E030 -:1041D000E802F0011124EE50FA4F8091360990E088 -:1041E00095838483089580915109882369F0809193 -:1041F000E4088770873041F482EC9DE09093F308E7 -:104200008093F2081092510908958F929F92AF9275 -:10421000BF92CF92DF92EF92FF92CF936B017C011E -:1042200020E030E0A9010F94B13987FDC3C06DEBE8 -:1042300077E386E095E3A70196010F94083E6B01B2 -:104240007C0120E030E0A9010F94B13987FFB7C0AD -:10425000C701B601905820E030E040E251E40F94ED -:10426000173A20E030E040E251E40F94173A20E0A2 -:1042700030E040EA50E40F94083E20E030E040E2B5 -:1042800051E40F94023F0F94743F6B017C0160E294 -:1042900080EAC81686E8D80681E0E806F1048CF0CA -:1042A000C701B60120EA36E841E050E00F94C63D70 -:1042B000CA01B9012AE030E040E050E00F94C63D69 -:1042C000605D6093A20560E280E1C81687E2D806CF -:1042D000E104F1048CF0C701B60120E137E240E0CF -:1042E00050E00F94C63DCA01B9012AE030E040E039 -:1042F00050E00F94C63D605D6093A30560E288EED8 -:10430000C81683E0D806E104F1048CF0C701B601B9 -:1043100028EE33E040E050E00F94C63DCA01B901F9 -:104320002AE030E040E050E00F94C63D605D6093CD -:10433000A40560E284E6C816D104E104F1048CF01F -:10434000C701B60124E630E040E050E00F94C63DDE -:10435000CA01B9012AE030E040E050E00F94C63DC8 -:10436000605D6093A5058AE0882E912CA12CB12C6C -:10437000C701B601A50194010F94C63DC62FCA011D -:10438000B901A50194010F94C63D605D6093A60537 -:104390008EE28093A705C05DC093A80582EA95E0F0 -:1043A000CF91FF90EF90DF90CF90BF90AF909F9014 -:1043B0008F9008956DEB77E386E095EB3CCF20E09E -:1043C00030E040E251E4C701B60149CF8F929F929D -:1043D000AF92BF92CF92DF92EF92FF92CF936B0199 -:1043E0007C0120E030E0A9010F94B13987FD93C032 -:1043F0006DEB77E386E095E3A70196010F94083E05 -:104400006B017C0120E030E040E251E40F94173A68 -:1044100020E030E04AE754E40F94173A4B015C0186 -:1044200020E030E0A901C701B6010F94B13920E0C6 -:1044300030E040EA50E487FF04C020E030E040EA8A -:1044400050ECC501B4010F94083E20E030E040E29A -:1044500051E40F94023F0F94743F6B017C01C1142F -:10446000D104E104F10409F45BC0F7FE59C0F094F3 -:10447000E094D094C094C11CD11CE11CF11C8DE2CD -:104480008093A305C701B60128EE33E040E050E079 -:104490000F94C63D8AE0882E912CA12CB12CCA0124 -:1044A000B901A50194010F94C63D605D6093A40518 -:1044B0008EE28093A505C701B60124E630E040E016 -:1044C00050E00F94C63DCA01B901A50194010F94B3 -:1044D000C63D605D6093A605C701B601A5019401C4 -:1044E0000F94C63DC62FCA01B901A50194010F94CE -:1044F000C63D605D6093A705C05DC093A80583EAD3 -:1045000095E0CF91FF90EF90DF90CF90BF90AF906C -:104510009F908F9008956DEB77E386E095EB6CCFDD -:1045200080E2AECFCF93DF93EC01CB01BA010F94C1 -:10453000B83920E030E040E251E40F94023F688354 -:1045400079838A839B83DF91CF9108950F94B83943 -:1045500020E030E040E251E40F94023F0C9405214A -:10456000CF93DF93EC01CB01BA010F94B8392AE065 -:1045700037ED43E25DE30F94023F0F947B3F688386 -:1045800079838A839B83DF91CF910895CF93DF93C3 -:10459000EC01CB01BA010F94B8392AE037ED43E2C0 -:1045A0005DE30F94023F688379838A839B83DF9165 -:1045B000CF910895CF93DF93EC01CB01BA010F9413 -:1045C000B839688379838A839B83DF91CF9108957B -:1045D000CF93DF93EC01CB01BA010F94B83920E0FF -:1045E00030E048EC52E40F94023F688379838A8379 -:1045F0009B83DF91CF9108950F94B83920E030E08C -:1046000048EC52E40F94023F0C94651FCF93DF9364 -:10461000EC01CB01BA010F94B8390F94743F798340 -:104620006883DF91CF910895CF93DF93EC01CB01A5 -:10463000BA010F94B83920E030E04AE754E40F940F -:10464000023F688379838A839B83DF91CF910895AA -:104650000F94B83920E030E04AE754E40F94023F69 -:104660000C94E621282F8FEF80931B0210924509AE -:1046700080913B0990913C09A0913D09B0913E0980 -:10468000B7FF08C010923B0910923C0910923D09F7 -:1046900010923E0980919705882331F080913B0963 -:1046A0008093A00510929F0580919E051816FCF43A -:1046B000082E000C990B821B91092091A005022E57 -:1046C000000C330B2817390794F097FF02C090E0D5 -:1046D00080E08093A005092E000CAA0BBB0B8093F1 -:1046E0003B0990933C09A0933D09B0933E0980910A -:1046F000A0056623A9F09091A105891714F4809371 -:10470000A1052091A105022E000C330B2C5F3F4F19 -:10471000482F082E000C550B241735071CF4845025 -:104720008093A10508950F931F93522F2091431654 -:10473000309144162817390741F1109201049093E3 -:104740004416809343168B0130E020E000933B0930 -:1047500010933C0920933D0930933E094093A105F5 -:1047600050939E058D5C944621F41092400910925E -:104770008F0582E08093750281E080939F051092FF -:10478000940580931B0210923A091F910F9108958E -:1047900020E040E070E060E08FE095E30C9493232C -:1047A000CF93C1E0C0934009FC0180819181A28137 -:1047B000B38180931C0290931D02A0931E02B093BC -:1047C0001F0220E040E070E060E080919C05909145 -:1047D0009D050E949323C0930104CF910895CF9328 -:1047E000DF9300D01F92CDB7DEB78DEC9CECACEC24 -:1047F000BCE389839A83AB83BC83CE0101960E947C -:10480000D0230F900F900F900F90DF91CF910895CC -:10481000CF93DF9300D01F92CDB7DEB78DEC9CEC29 -:10482000ACECBDE389839A83AB83BC83CE01019654 -:104830000E94D0230F900F900F900F90DF91CF9197 -:104840000895CF93DF9300D01F92CDB7DEB780E0FD -:1048500090E0A0E8BFE389839A83AB83BC83CE0159 -:1048600001960E94D0230F900F900F900F90DF9130 -:10487000CF910895CF93DF9300D01F92CDB7DEB7CD -:1048800080E090E0A0E2B1E489839A83AB83BC83AB -:10489000CE0101960E94D0230F900F900F900F90A1 -:1048A000DF91CF910895E0918F05E63028F581E002 -:1048B0008E0F80938F0540913B0950913C09609188 -:1048C0003D0970913E092091A10590919E0580912E -:1048D000400939E0E39FF0011124E65BFA4FA09113 -:1048E0004316B0914416B183A083428353836483FB -:1048F00075832683978380870895CF93DF93EC0198 -:104900000E94532420E040E070E060E0CE01DF919F -:10491000CF910C949323FC01A081B1811C92A281C0 -:10492000B3818C918F5F8C930280F381E02D908115 -:104930008CE0989F800D1124E5E4F6E113AE84AF7E -:104940000895FC0184910895FC01808108950097E9 -:1049500051F0FC0180E09191992331F0907C9038E6 -:10496000D1F38F5FF8CF80E0089590E080E0089564 -:10497000CF92DF92EF92FF92CF93C82F833011F442 -:1049800060932F050F941E1D6B017C0124EA30E714 -:104990004DE75FE360911C0270911D0280911E0241 -:1049A00090911F020F94B13987FD18C08AEF90E0F3 -:1049B000A0E0B0E08C0D9D1DAE1DBF1D80933005A5 -:1049C00090933105A0933205B0933305C093100244 -:1049D000CF91FF90EF90DF90CF90089580E090E02E -:1049E000DC01E8CFCF92DF92EF92FF920F931F93FB -:1049F0000F941E1D009106051091070520910805D2 -:104A0000309109056B017C01C01AD10AE20AF30A50 -:104A10009701860137FD11C020910505209520934F -:104A200005056A547C4F8F4F9F4F60930605709326 -:104A30000705809308059093090581E0909105058D -:104A4000911101C080E01F910F91FF90EF90DF90D6 -:104A5000CF900895CF92DF92EF92FF920F94B839E2 -:104A60006B017C0120E030E0A9010F94B1392DEBFE -:104A700037E346E055E387FF04C02DEB37E346E01C -:104A800055EBC701B6010F94083E6B017C0120E095 -:104A900030E0A9010F94B13920E030E040E05FE35D -:104AA00087FF04C020E030E040E05FEBC701B601C3 -:104AB0000F94083E0F94743FCB01FF90EF90DF906E -:104AC000CF900C9492BD0F94B8390F94743FCB01E2 -:104AD0000C9492BD0F94B83929EC38EC48EC5EE3A5 -:104AE0000F94023F20E030E040E05FE30F94083E87 -:104AF0000F947B3F862F0C942ABECF93DF93CDB7C4 -:104B0000DEB720E2488559856F818E810F941E158E -:104B1000DF91CF910895809147090C949ACC0F941E -:104B2000B8392DEC3CEC4CEC5DE30F94023F0F9454 -:104B30007B3FCB010C94C7BDAF92BF92CF92DF9267 -:104B4000EF92FF920F931F93CF93DF9361E081E089 -:104B50000E943223C091A10505E00C0FD1E086E24E -:104B6000E82E8AE0F82E12E01C1B9FE2C92E9AE084 -:104B7000D92EBD2EBC1AAC2EA194C1112EC0DD239E -:104B8000D9F08091A0051816BCF040913B095091D6 -:104B90003C0960913D0970913E094F5F5F4F6F4F37 -:104BA0007F4F40933B0950933C0960933D097093BC -:104BB0003E098F5F8093A00580917502882331F0B4 -:104BC00041E06AE37AE08A2D0F949314CF5F0C13CF -:104BD000D4CF83E080939E051FC0C13041F59091F2 -:104BE000A005913069F0809175028823C9F11F9268 -:104BF000DF92CF92BF9281E0913051F180E028C0E6 -:104C000080913F0910923F09882369F3C0934E09B0 -:104C100080919F05882339F3DF91CF911F910F91E8 -:104C2000FF90EF90DF90CF90BF90AF900895C2308B -:104C300069F69091A0059230A9F0809175028823C1 -:104C400079F01F92FF92EF921F9381E09230B1F6BC -:104C50008F930E947D250F900F900F900F900F90D3 -:104C6000D0E0B4CF80913F0910923F09882329F307 -:104C7000C0934E0980919F058823F9F2CDCF809192 -:104C80007502882341F0609190057091910541E093 -:104C900081E00D94931408950D9421120D9419122E -:104CA0000D9411120D9409120D9401126091F814D3 -:104CB0007091F9148FEB94E10D940F2160913415EC -:104CC000709135158BEF94E10D940F216091701563 -:104CD0007091711587E395E10D940F216091AC15EA -:104CE0007091AD1583E795E10D940F216091E81562 -:104CF0007091E9158FEA95E10D940F2160914709B4 -:104D000080913609909137090C94DCCC809151093F -:104D10000E940CCD882341F020E040E070E060E08C -:104D200086E996E20C9493230C94C823EF92FF92A9 -:104D30000F931F938BE4E82E8DE0F82E10E000E037 -:104D40002DE43DE048EC53E26DE57DE082E69DE038 -:104D50000F941D241F910F91FF90EF900895EF92F3 -:104D6000FF920F931F938FE3E82E8CE0F82E10E054 -:104D700000E020EC3CE04DE45EE361E47CE086E4AE -:104D80009CE00F941D241F910F91FF90EF900895C8 -:104D9000EF92FF920F931F938EE4E82E88E0F82E97 -:104DA00010E000E021E638E043E55EE260E578E00F -:104DB00087E598E00F941D241F910F91FF90EF90CD -:104DC0000895CF92DF92EF92FF920F931F93CF93AC -:104DD000DF93CDB7DEB7CDB6DEB68091FC1169E7C3 -:104DE0007FE0882311F06CEF71E1FB01019000205E -:104DF000E9F7CF01861B970B01962DB73EB7281B0D -:104E0000390B0FB6F8943EBF0FBE2DBF0DB71EB7BE -:104E10000F5F1F4F80E2EDB7FEB78183C801019697 -:104E20000F94ED4183EEE82E8CE0F82E25EE3CE069 -:104E300041E05EE261EF7CE088EF9CE00F941D248E -:104E40000FB6F894DEBE0FBECDBEDF91CF911F919D -:104E50000F91FF90EF90DF90CF9008950F948E10F8 -:104E600010924F09109274020E9473CD882351F062 -:104E70008091A21782FD06C082E697E09093F30826 -:104E80008093F2080C94A6BB0F94B8390F947B3F23 -:104E9000862F0C9408BECF93DF9300D0CDB7DEB73A -:104EA0008FEF89838A838B83CE0101960E94F6CA95 -:104EB0000F900F900F90DF91CF910895CF93DF93D4 -:104EC00000D0CDB7DEB78FEF89831A821B82CE0167 -:104ED00001960E94F6CA0F900F900F90DF91CF912C -:104EE0000895CF93DF9300D0CDB7DEB78FEF8983DE -:104EF00089E18A831B82CE0101960E94F6CA0F9037 -:104F00000F900F90DF91CF910895CF93DF9300D052 -:104F1000CDB7DEB78FEF89838BE48A831B82CE0106 -:104F200001960E94F6CA0F900F900F90DF91CF91DB -:104F30000895CF93DF9300D0CDB7DEB719821A82E0 -:104F40008FEF8B83CE0101960E94F6CA0F900F90CF -:104F50000F90DF91CF910895CF93DF9300D0CDB71D -:104F6000DEB719828FEF8A838B83CE0101960E9470 -:104F7000F6CA0F900F900F90DF91CF910895CF93C5 -:104F8000DF9300D0CDB7DEB78FEF89831A828B8392 -:104F9000CE0101960E94F6CA0F900F900F90DF91FC -:104FA000CF910895CF93DF9300D01F92CDB7DEB796 -:104FB0000F947B3F0F94B63969837A838B839C83EC -:104FC000CE0101960E9414BC0F900F900F900F908D -:104FD000DF91CF9108950F94B8392AE037ED43E27D -:104FE0005DE30F94023F0C94D227CF92DF92EF92B1 -:104FF000FF92CF93DF9300D01F92CDB7DEB76B0146 -:105000007C0120E030E0A9010F94B13987FD1BC07D -:105010006DEB77E386E095E3A70196010F94083ED8 -:1050200069837A838B839C83CE0101960E9414BC92 -:105030000F900F900F900F90DF91CF91FF90EF9016 -:10504000DF90CF9008956DEB77E386E095EBE4CFAA -:105050000F94B8392AE037ED43E25DE30F94023F45 -:105060000C94F5270F94B8390C94F527CF92DF9262 -:10507000EF92FF926B017C0120E030E0A9010F94D8 -:10508000B13987FD26C06DEB77E386E095E3A70194 -:1050900096010F94083E6B017C0120E030E0A901ED -:1050A0000F94B13920E030E040E05FE387FF04C0B7 -:1050B00020E030E040E05FEBC701B6010F94083E0E -:1050C0000F94743FCB01FF90EF90DF90CF900C9442 -:1050D00013BD6DEB77E386E095EBD9CF0F94B8392C -:1050E0000C9436280C945B8F0C945B8F0C940D8F72 -:1050F0000C940D8F0C940D8F0C940D8FEF92FF92EA -:105100000F931F93CF93DF93EC018B017A018A8574 -:105110009B858617970731F0888199810F9419250F -:105120001B870A87B701888199810F948B152E817F -:105130003F81820F932F911D9F838E8390E080E0AB -:10514000DF91CF911F910F91FF90EF9008959F9263 -:10515000AF92BF92CF92DF92EF92FF920F931F9385 -:10516000CF93DF93EC018B01942EA52E8A859B852E -:105170008617970731F0888199810F9419251B872D -:105180000A8788859985019649F5BC800A818E81B8 -:10519000080FC880D980D6015596ED91FC91C601C3 -:1051A0001995B80EE92CFA2C10E0F70121917F0136 -:1051B000211127C08E819F81810F911D9F838E8336 -:1051C00090E080E0DF91CF911F910F91FF90EF90E1 -:1051D000DF90CF90BF90AF909F9008950E811F8178 -:1051E000692D7A2D888199810F948B15800F912FCD -:1051F000911D288539852817390738F681E090E018 -:10520000E1CF4B2D602FC6010F947125080F180FA9 -:10521000CCCFDF92EF92FF920F931F93CF93DF9348 -:10522000EC01D62E1CAD0BAD7C0184E0E80EF11C28 -:10523000E98DFA8DC7011995412F480F2D2D602F4B -:10524000C7010F9471259BAD890F8BAF81E090E072 -:10525000DF91CF911F910F91FF90EF90DF90089514 -:10526000AF92BF92DF92EF92FF920F931F93CF9373 -:10527000DF938C01EB01D42E79018FE0481709F4FC -:1052800088C0A5E14A17C1F1BAE04B130EC0EC810A -:10529000FD8130E020E042E061E0C801199542E282 -:1052A00056E0BE01C8010F941C260A80DB81C02D88 -:1052B000F2E3DF1609F4E4C0FD1508F493C085E1BC -:1052C000D81609F4E2C0A7E1DA1609F4FCC0B4E18B -:1052D000DB127DC0EE81FF818D8190E0880F991FE8 -:1052E0008E0F9F1F11928E179F07E1F71A828881F8 -:1052F00081508B831C826BC0AA80BB804DE056E03E -:10530000C8010F941C26F5014481440F406BBE0177 -:10531000C8010F94042641E0BE01C8010F940C2679 -:10532000D50116962D913C911797EC81FD8115962C -:105330004C9166E0C801199540E0BE01C8010F9488 -:1053400014264DE056E0BE01C8010F941C26F5015D -:105350004481440F4F5F406BBE01C8010F94042687 -:1053600041E0BE01C8010F940C26D50115964C9161 -:10537000159716962D913C91240F311DEC81FD81DE -:1053800066E0C801199540E0BE01C8010F941426DB -:105390008CCF41E0C8010F94142640E0BE01C80143 -:1053A0000F940C2641E8BE01C8010F940426F701B2 -:1053B000408150E05595479555954795BE01C801E8 -:1053C0000F94042640E0BE01C8010F94142681E02A -:1053D000DF91CF911F910F91FF90EF90DF90BF90E1 -:1053E000AF900895E6E4DE1609F47CC0F7E4DF161A -:1053F00009F47CC08BE3D812EACFD70111969C91B7 -:10540000119713968C9138E0390F813031F0833049 -:1054100011F0392F02C0392F985021E04B814917E4 -:1054200008F420E041E0391708F040E091E05A81AB -:10543000351708F490E0322F342B932311F42423F2 -:1054400031F2F701128100E0D12C843048F490E071 -:10545000FC01EC55FD4FD08080569D4FDC010C9136 -:1054600017FF04C0B701CE010F941222F70180810B -:105470008D0D80838181800F8183110F89F7A7CFE4 -:10548000B701CE010F941222A2CF88819A81980F82 -:105490009A832981921770F59C819F5F9C839B81E1 -:1054A000890F821710F08FEF820F8B83EE81FF81BF -:1054B0008D8190E0880F991F8E0F9F1F11928E177C -:1054C0009F07E1F784CFD7011C928A8111968C93B4 -:1054D00011978D81815012968C9312978B81139620 -:1054E0008C9375CF8D81F701808371CF8981D7012E -:1054F0008C936DCF80E06CCF8F929F92AF92BF92D2 -:10550000CF92DF92EF92FF920F931F93CF93DF938F -:10551000CDB7DEB760970FB6F894DEBF0FBECDBF34 -:105520008B0140E050E068EC72E449875A876B8752 -:105530007C8740E050E060EA70E44D875E876F87CB -:10554000788B8130B9F1823009F462C020E030E01C -:1055500040E050E460917E0270917F028091800271 -:10556000909181020F94083E4B017C0120E030E0D5 -:1055700046E153E40F946840181634F4812C912CC2 -:1055800086E1E82E93E4F92EF801A084B184C28468 -:10559000D3849401A701B501C6010F946840181681 -:1055A00014F054016701C501D60189839A83AB8346 -:1055B000BC8351C0BE01635F7F4FC80108960E9443 -:1055C000C4B488E0F801DE01119601900D928A952D -:1055D000E1F7AE01475F5F4FBE016B5F7F4FCE01CA -:1055E00001960E94A2B40E94BBB860960FB6F894D0 -:1055F000DEBF0FBECDBFDF91CF911F910F91FF9006 -:10560000EF90DF90CF90BF90AF909F908F900895D4 -:10561000F801208531854285538560917E02709125 -:105620007F0280918002909181020F94083E6B016D -:105630007C0120E030E046E153E40F94B13987FD6E -:1056400006C0C12CD12C26E1E22E23E4F22EC98221 -:10565000DA82EB82FC82BE01635F7F4FCE0101964E -:10566000AECF0F931F930F941E1D0091CB08109186 -:10567000CC082091CD083091CE08011511052105E7 -:105680003105D9F5209131162223A1F1E0912F1691 -:1056900021502093311621E02E0F20932F163091A8 -:1056A0003216231302C010922F1624E0E29FF0015D -:1056B0001124ED5CF94E0081118122813381009328 -:1056C000C7081093C8082093C9083093CA08600F10 -:1056D000711F811D911D6093CB087093CC0880933E -:1056E000CD089093CE088091C9089091CA08892B63 -:1056F00009F0409A1F910F910895601B710B820B66 -:10570000930B97FDF7CF40981092CB081092CC08DE -:105710001092CD081092CE08EDCF0F931F93CF9328 -:10572000DF938C01EB019091311620913216921388 -:1057300005C00E94312B0E94A591F5CF80913016B3 -:1057400034E0839FF0011124ED5CF94E1183008356 -:10575000D383C2839F5F909331168F5F281739F0F0 -:1057600080933016DF91CF911F910F910895109281 -:105770003016F8CF63E972E084E690E00E948D2B4A -:1057800070E060E08AE090E00E948D2B6AEB72E0AE -:1057900084E690E00C948D2B0E947CB90C94BA2B7B -:1057A00081110C94BA2B68E270E080E991E00C94CE -:1057B0008D2B0E94648B0C94D02B0E940FC50C94EF -:1057C000D02B4FE350E0BC0184EF98E00D940242EF -:1057D0000F931F93CF93DF93CDB7DEB72C970FB600 -:1057E000F894DEBF0FBECDBF80914709282F082E49 -:1057F000000C330B3F938F9385E99BE09F938F932E -:105800008E010F5F1F4F1F930F930F944839C801EC -:105810000E94E12B0F900F900F900F900F900F9020 -:105820002C960FB6F894DEBF0FBECDBFDF91CF919F -:105830001F910F9108950C94E82B0F931F93CF9312 -:10584000DF93CDB7DEB72C970FB6F894DEBF0FBE4F -:10585000CDBF80914709282F082E000C330B3F93B2 -:105860008F938CE89BE09F938F938E010F5F1F4F68 -:105870001F930F930F944839C8010E94E12B0F909A -:105880000F900F900F900F900F902C960FB6F894EA -:10589000DEBF0FBECDBFDF91CF911F910F91089555 -:1058A0000C941D2C0F931F93CF93DF93CDB7DEB7CE -:1058B0002F970FB6F894DEBF0FBECDBF809147097A -:1058C000282F082E000C330B3F938F9380E89BE02A -:1058D0009F938F938E010F5F1F4F1F930F930F9412 -:1058E0004839C8010E94E12B0F900F900F900F9044 -:1058F0000F900F902F960FB6F894DEBF0FBECDBF5E -:10590000DF91CF911F910F9108950C94522CEF923B -:10591000FF920F931F93CF93DF9300D000D000D05E -:105920001F921F92CDB7DEB77C0120919205422FC6 -:10593000022E000C550B80919305833089F1843041 -:1059400041F185E999E05F932F939F938F938E01A7 -:105950000F5F1F4F1F930F930F944839609192056B -:10596000C7010E94DCCCC8010E94E12B0F900F9070 -:105970000F900F900F900F902B960FB6F894DEBFFC -:105980000FBECDBFDF91CF911F910F91FF90EF9090 -:10599000089581EA99E027FDD6CF8CE899E0D3CF2E -:1059A0008AEA99E0D0CFE091470986E0E802F00169 -:1059B0001124EE50FA4F808191810C94872CE09154 -:1059C000470987E1E89FF0011124E15CF94F8085E8 -:1059D00091850C94872C2F923F924F925F926F92F9 -:1059E0007F928F929F92AF92BF92CF92DF92EF926F -:1059F000FF920F931F93CF93DF9300D000D0CDB7CA -:105A0000DEB71C017A8369832B833C834D835E83DD -:105A10002701380181E080939F050E94532483E091 -:105A20008093750230928E0520928D0589819A812E -:105A300090938C0580938B058B819C81AD81BE8179 -:105A40008093870590938805A0938905B0938A0574 -:105A50004092830550928405609285057092860578 -:105A6000F12CE12CC0923B09D0923C09E0923D0917 -:105A7000F0923E09B0924416A0924316909282058D -:105A8000809281058C8D8093800526960FB6F894C0 -:105A9000DEBF0FBECDBFDF91CF911F910F91FF9061 -:105AA000EF90DF90CF90BF90AF909F908F907F90BE -:105AB0006F905F904F903F902F90089520E040E0CE -:105AC00070E060E08DEC94E60C9493230E9497CDF7 -:105AD0000E94B4850C945E2DCF93DF93782FC62F50 -:105AE000D42F67FD36C086E06802F0011124EE5025 -:105AF000FA4F408151811416150684F4E72FF0E027 -:105B0000EE0FFF1FE054FD4F808191810F974817E2 -:105B100059070CF4CA01672F0E94DCCCD7FF1BC0C9 -:105B2000E0915109E23008F0E0E0F0E0EE52FA4F87 -:105B300086E0C802D0011124AE50BA4F14968D9160 -:105B40009C918F3F910519F010F08FEF90E08083CA -:105B50001AC047FD18C086E0D802F0011124EE50AB -:105B6000FA4F82819381181619065CF484369105E8 -:105B700014F084E690E090933706809336060E94F6 -:105B800022C6C7FFCDCFDF91CF910C945E2D0F932E -:105B90001F93CF93DF93C6E3D9E0E88186E0E80264 -:105BA000F0011124EE50FA4F0081118160E0C8012C -:105BB0000E94DCCC61E0C8010E94DCCC48816FEF20 -:105BC00080E0DF91CF911F910F910C946C2D0C947C -:105BD000C72D60913609462F809147090C946C2D92 -:105BE0000C94E92D4FEF60913609809147090C9490 -:105BF0006C2D0C94F22D409136096FEF80E00C94DF -:105C00006C2D89E79FE00E949B790E945E2D0D9488 -:105C10008E10611160931A02409300048C3008F0DA -:105C20003AC0E82F880FFF0B8827E65EF14D8F4FB3 -:105C30000D945C414D2E262E312E502E342E372EB3 -:105C40003A2E462E3D2E4B2E402E432E8CE094E4D1 -:105C500021E02093400920E040E070E060E00C94F7 -:105C6000932384E194E4F4CF88E194E4F1CF8CE1D0 -:105C700094E4EECF80E294E4EBCF84E294E4E8CFC6 -:105C800088E294E4E5CF8CE294E4E2CF10924E09EE -:105C90008CE995E2DDCF0C945E2D88E094E4D8CFBA -:105CA00080E194E4D5CFCF930E947CB90E94648BAD -:105CB000C82F882319F080E00E942E8A8C2F0E9422 -:105CC000D02BCF910C945E2D8CE598E09093F30847 -:105CD0008093F2080C945E2DCF93DF93C0918F05D3 -:105CE000CC23B9F0C150C0938F0589E0C89FE00173 -:105CF0001124C65BDA4F6A817B812F814E818881B6 -:105D000099810E949323888580934009DF91CF91E8 -:105D10000895DF91CF910C945E2DEF92FF920F9337 -:105D20001F93CF93DF9361E081E00E943223C09103 -:105D3000A10585E0F82EFC0ED2E0DC1B11E01C1B57 -:105D4000EC2EE194C1112BC00091A0050023A1F01D -:105D500080917502882349F081E0011180E024E000 -:105D60004AEA5EE06E2D0F941E15CF5FFC12EACF5B -:105D700083E080939E050CC080913F0910923F09FB -:105D8000882331F30E946C2E80919F05882301F3B4 -:105D9000DF91CF911F910F91FF90EF900895C13047 -:105DA00001F50091A005013069F08091750288230A -:105DB000E1F281E0013009F080E023E04BE95EE0B0 -:105DC000612FD1CF80913F0910923F09882369F359 -:105DD00084E49BE40E947D2480919F05882329F31D -:105DE000D7CFC23011F60091A005023071F080913A -:105DF0007502882309F4B9CF81E0023009F080E010 -:105E000023E04DE85EE06D2FAECF80913F09109208 -:105E10003F09882361F382E99CE40E947D248091FC -:105E20009F05882321F3B4CF2F923F924F925F9228 -:105E30006F927F928F929F92AF92BF92CF92DF929A -:105E4000EF92FF920F931F93CF93DF9300D01F9297 -:105E5000CDB7DEB70091360961E081E00E943223C0 -:105E60002091A1052B8310E0000F111F075E114F39 -:105E7000422E2B5F2983842D81958A8341E0E42E75 -:105E80004EE0F42E51EFC52E5DE0D52E63EEA62E2A -:105E90006DE0B62E85E0582E541875ED872E7DE006 -:105EA000972E2B81211114C08091A0058C8388230B -:105EB00009F4E3C080917502882351F081E09C8150 -:105EC000911180E024E04DE05EE06A810F941E15A0 -:105ED000612C21E02C833B8034188B819C818913B9 -:105EE0002DC0E0913609F0E0EE0FFF1FE75EF14FA5 -:105EF000859194916092470990934B0980934A0948 -:105F000010924909109248097090A0052B817216D1 -:105F100009F4D8C080917502882381F01F92FF9206 -:105F2000EF923F9281E09C81791280E08F930E94F2 -:105F30007D250F900F900F900F900F907C80872DF4 -:105F40008F5F2B8182132CC0E0913609F0E0EE0FB9 -:105F5000FF1FE75EF14F85919491609247099093FE -:105F60004B0980934A0910924909109248092090E0 -:105F7000A005221609F4B5C080917502882381F02E -:105F80001F92DF92CF923F9281E09B81291280E0A5 -:105F90008F930E947D250F900F900F900F900F9080 -:105FA00063942C812E5F2C83253009F096CF8B8152 -:105FB000853041F5F80185919491109247099093AD -:105FC0004B0980934A09109249091092480990910F -:105FD000A0059C83953009F493C0809175028823B5 -:105FE00089F01F92BF92AF925F9281E02C812530A1 -:105FF00009F080E08F930E947D250F900F900F9005 -:106000000F900F9083E0870D9B8189132BC0F801BF -:10601000859194911092470990934B0980934A0976 -:1060200010924909109248092091A0052C838B8178 -:10603000281709F474C080917502882399F01F9283 -:106040009F928F928B8184198F9381E09C812B8109 -:10605000921380E08F930E947D250F900F900F90F8 -:106060000F900F908B818F5F8B839981891319CF4C -:1060700084E0870D80939E050EC080913F091092A9 -:106080003F09882309F416CF0E946C2E80919F054A -:10609000882309F40FCF0F900F900F900F90DF918E -:1060A000CF911F910F91FF90EF90DF90CF90BF9015 -:1060B000AF909F908F907F906F905F904F903F90A8 -:1060C0002F90089580913F0910923F09882309F489 -:1060D00021CF0E94E92D80919F05882309F41ACFD2 -:1060E000DACF80913F0910923F09882309F444CF09 -:1060F0000E94F22D80919F05882309F43DCFCBCFDC -:1061000080913F0910923F09882309F466CF0E94CD -:10611000C72D80919F05882309F45FCFBCCF809164 -:106120003F0910923F09882309F485CF4091360931 -:106130006FEF80E00E946C2D80919F05882309F409 -:106140007ACFA9CF6F927F928F929F92AF92BF9298 -:10615000CF92DF92EF92FF920F931F93CF93DF9333 -:1061600061E081E00E943223C091A1059C2E85E070 -:10617000C82ECC0E9EE9A92E9DE0B92ED6E0DC1BE0 -:10618000EE24E39422E0D22E15E01C1B04E00C1B4D -:1061900083E0F82EFC1A8D2C8C1A7E2C7C1AC111EF -:1061A00034C06090A0056620A9F080917502882314 -:1061B00051F0692D619581E0611080E024E040EDAF -:1061C0005DE00F941E15CF5FCC11E9CF87E080937F -:1061D0009E050CC080913F0910923F09882329F346 -:1061E0000E946C2E80919F058823F9F2DF91CF9158 -:1061F0001F910F91FF90EF90DF90CF90BF90AF90E5 -:106200009F908F907F906F900895C13001F56090BE -:10621000A00581E0681661F080917502882399F2EB -:1062200081E0681280E023E046EC5DE0672DC9CF95 -:1062300080913F0910923F09882371F381E092E336 -:106240000E947D2480919F05882331F3CFCFC230F7 -:1062500009F0B9C09091A005923071F0809175025B -:10626000882309F4B0CF81E0923009F080E020E289 -:1062700048EB5DE0682DA5CF80913F0910923F0962 -:10628000882361F322EC3DE03093F3082093F20879 -:1062900080919F05882311F3A9CF1092470910928E -:1062A0004B0910924A09109249091092480990919D -:1062B000A005933071F080917502882309F483CF93 -:1062C00081E0933009F080E020E24CEA5DE06F2D40 -:1062D00078CF80913F0910923F09882361F323EB27 -:1062E0003DE03093F3082093F20880919F058823C6 -:1062F00011F37CCFE092470910924B0910924A09A2 -:1063000010924909109248099091A005943071F0BB -:1063100080917502882309F456CF81E0943009F00A -:1063200080E020E24CEA5DE0602F4BCF80913F0996 -:1063300010923F09882361F327EA3DE03093F30888 -:106340002093F20880919F05882311F34FCFD092BC -:10635000470910924B0910924A091092490910926C -:1063600048099091A005953071F0809175028823BD -:1063700009F429CF81E0953009F080E020E24CEA71 -:106380005DE0612F1ECF80913F0910923F09882365 -:1063900061F322EA3DE03093F3082093F208809104 -:1063A0009F05882311F322CF80913F0910923F0966 -:1063B0008823C9F0B092F308A092F20880919F055B -:1063C000882389F013CFC33009F467CFC43009F4B0 -:1063D00091CFC53009F4BBCFC63009F0F4CE90910F -:1063E000A005963009F380917502882309F4EBCE5D -:1063F00081E0963009F080E020E24DE85DE06D2F0D -:10640000E0CE8F929F92AF92BF92CF92DF92EF92A7 -:10641000FF920F931F93CF93DF9361E081E00E947F -:106420003223C091A10585E0B82EBC0ED1E016E064 -:106430001C1B05E00C1B84E0F82EFC1A92E0D92E00 -:1064400083E0E82EEC1AAD2CAC1A9D2E9C1A8C2EF3 -:106450008194C11131C0C090A005CC20A1F08091E1 -:106460007502882349F081E0C11080E024E046E80D -:106470005DE0682D0F941E15CF5FCB11EACF87E04A -:1064800080939E050CC080913F0910923F0988239C -:1064900031F30E946C2E80919F05882301F3DF91D8 -:1064A000CF911F910F91FF90EF90DF90CF90BF9011 -:1064B000AF909F908F900895C13051F51092470989 -:1064C00010924B0910924A091092490910924809FA -:1064D000C090A00581E0C81661F080917502882304 -:1064E00059F281E0C81280E023E04FE75DE0692DBA -:1064F000C1CF80913F0910923F09882371F388E052 -:1065000095E30E947D2480919F05882331F3C7CFB6 -:10651000C23009F0B5C0D093470910924B091092D0 -:106520004A091092490910924809C090A00592E0CA -:10653000C91671F080917502882309F49DCF81E01E -:1065400092E0C91280E023E04FE75DE06A2D92CF30 -:1065500080913F0910923F09882361F381E095E320 -:106560000E947D2480919F05882321F398CFD092AB -:10657000470910924B0910924A091092490910924A -:106580004809C090A00583E0C81671F0809175029B -:10659000882309F471CF81E093E0C91280E023E001 -:1065A0004FE75DE06E2D66CF80913F0910923F0965 -:1065B000882361F38AEF94E30E947D2480919F05F4 -:1065C000882321F36CCFC090A00584E0C81671F039 -:1065D00080917502882309F44FCF81E094E0C912BD -:1065E00080E023E041E75DE06F2D44CF80913F09DB -:1065F00010923F09882361F386E896E20E947D2489 -:1066000080919F05882321F34ACF10924709109269 -:106610004B0910924A091092490910924809C090FA -:10662000A00585E0C81671F080917502882309F4F1 -:1066300023CF81E095E0C91280E023E04AE65DE0E7 -:10664000602F18CF80913F0910923F09882361F392 -:1066500084EF94E30E947D2480919F05882321F399 -:106660001ECF80913F0910923F09882321F18EEEC1 -:1066700094E30E947D2480919F058823E1F00FCF51 -:10668000C33009F474CFC43009F49DCFC53009F488 -:10669000BCCFC63009F0F0CED093470910924B0919 -:1066A00010924A091092490910924809C090A00519 -:1066B00086E0C816B1F280917502882309F4DCCE19 -:1066C00081E096E0C91280E023E04AE65DE0612FB8 -:1066D000D1CE7F928F929F92AF92BF92CF92DF9254 -:1066E000EF92FF920F931F93CF93DF93F82E842E98 -:1066F00070939D0560939C0561E081E00E943223C8 -:10670000C091A10585E0982E9C0ED1E007E21DE026 -:1067100085E0E82EEC1A84E0D82EDC1A83E0C82E3F -:10672000CC1A82E0B82EBC1A7D2E7C1AAC2EA19415 -:1067300083E0F81609F44EC0C11196C0F0924709E3 -:1067400010924B0910924A09109249091092480977 -:10675000DD23D9F08091A0051816BCF040913B09CB -:1067600050913C0960913D0970913E094F5F5F4F28 -:106770006F4F7F4F40933B0950933C0960933D0915 -:1067800070933E098F5F8093A005809175028823E6 -:1067900031F043E06FE77DE08A2D0F94931482E09F -:1067A000F8125BC0C530A1F41092470910934B0951 -:1067B00000934A091092490910924809D091A00506 -:1067C000D53009F4D9C0809175028111E6C0D0E0BE -:1067D00086E044C08091820290918302A09184025D -:1067E000B09185028093980590939905A0939A059E -:1067F000B0939B05C11138C08092470910924B0994 -:1068000010924A091092490910924809DD23D9F0E3 -:106810008091A0051816BCF040913B0950913C09AD -:1068200060913D0970913E094F5F5F4F6F4F7F4F01 -:1068300040933B0950933C0960933D0970933E0996 -:106840008F5F8093A00580917502882331F043E02B -:106850006AE67DE08A2D0F94931485E0CF5F9C1249 -:1068600067CF80939E0522C0C13071F5D091A005FD -:10687000D13081F080917502882351F081E0D130D0 -:1068800009F080E024E046EC5DE0672D0F941E15D2 -:10689000D0E085CF80913F0910923F09882351F3C2 -:1068A0000E946C2E80919F05882321F3DF91CF9168 -:1068B0001F910F91FF90EF90DF90CF90BF90AF901E -:1068C0009F908F907F900895C23009F071C0D09151 -:1068D000A005D23069F0809175028823C9F281E069 -:1068E000D23009F080E023E041E45DE06B2DCECFB3 -:1068F00080913F0910923F09882369F38AE394E26B -:106900000E947D2480919F05882329F3CFCF809119 -:106910003F0910923F09882309F452C081E294E2B2 -:106920000E947D2480919F05882309F449C0BECF31 -:10693000C43009F034CFD091A005D43071F08091EB -:106940007502882309F4A4CF81E0D43009F080E0F7 -:1069500023E04DE25DE06D2D99CF80913F091092CB -:106960003F09882361F388E094E20E947D248091AE -:106970009F05882321F39ACF80913F0910923F0908 -:10698000882309F420CF8FEE93E20E947D2480912A -:106990009F05882309F417CF89CF81E0D53009F00E -:1069A00080E023E04EE15DE06E2D0F941E150FCFC9 -:1069B000C33009F0BDCFD091A005D33009F4A7CFE3 -:1069C00080917502882309F463CF81E0D33009F008 -:1069D00080E023E048E35DE06C2D58CF41E06CE4BB -:1069E00075E483E00C94693340E06FE475E483E080 -:1069F0000C9469334091510963E377E482E00C948D -:106A000069334091510966E377E481E00C9469337E -:106A10004091510969E377E480E00C946933409137 -:106A2000510962E575E483E00C9469332F923F923B -:106A30004F925F926F927F928F929F92AF92BF928E -:106A4000CF92DF92EF92FF920F931F93CF93DF933A -:106A500000D000D01F92CDB7DEB70E9462CD482E85 -:106A600061E081E00E9432237090A105572C25E05F -:106A7000270D298382E087198A8381E087198B8318 -:106A8000872D81958C8309ED1BE29EE3E92E99E029 -:106A9000F92E2CECC22E2BE2D22E3FE1A32E39E0B0 -:106AA000B32E4DED842E4BE2942E711000C19091C7 -:106AB000A0059D83992309F4D3C080917502882392 -:106AC00009F4A3C181E02D81211180E024E047E891 -:106AD00059E06C810F941E1582E041103AC183E0A9 -:106AE0008D838D81871115C09091A0059E83981785 -:106AF00009F437C180917502882359F0672D651913 -:106B000081E02E81271180E023E04CE559E00F94CD -:106B10001E156D8063941F821E82272C2518761007 -:106B200025C0EE81FF81EE0FFF1FE75EF14F8591DB -:106B300094912E812093470990934B0980934A09A1 -:106B400010924909109248093090A005371409F4B1 -:106B50001EC180917502882349F081E0361080E0E3 -:106B600023E04DE459E0622D0F941E15362C662467 -:106B70006394630C8E819F81019709F003C16710B4 -:106B80001EC08091A005871509F412C1809175027D -:106B90008823A9F01F930F93FF92EF92872D8519F9 -:106BA0008F9381E09091A005971180E08F930E94D0 -:106BB0007D250F900F900F900F900F900F9082E017 -:106BC000830D411046C0871120C08091A005871514 -:106BD00009F4FDC0809175028823B9F09F928F92CD -:106BE00080E399E09F938F93872D85198F9381E0A0 -:106BF0009091A005971180E08F930E947D250F90C2 -:106C00000F900F900F900F900F9083E0830D8711DE -:106C10001EC08091A005871509F4E8C08091750217 -:106C20008823A9F0DF92CF92BF92AF92872D85196A -:106C30008F9381E09091A005971180E08F930E943F -:106C40007D250F900F900F900F900F900F9084E084 -:106C5000830D73949981971128CF80939E050EC060 -:106C600080913F0910923F09882309F426CF0E94A2 -:106C70006C2E80919F05882309F41FCF27960FB6AD -:106C8000F894DEBF0FBECDBFDF91CF911F910F9162 -:106C9000FF90EF90DF90CF90BF90AF909F908F903C -:106CA0007F906F905F904F903F902F90089591E06C -:106CB000791214C02091A0052D83213001F180911B -:106CC0007502882359F081E09D81913009F080E0C0 -:106CD00023E045E759E06B810F941E1541103BC03E -:106CE00022E072123BC08091A0058D838230B1F00A -:106CF00080917502811121C093E09D830ACF80911C -:106D00003F0910923F098823D1F287EB93E50E9457 -:106D10007D2480919F05882391F2B0CF80913F0917 -:106D200010923F09882321F386E096E50E947D2496 -:106D300080919F058823E1F2A1CF81E02D8122304F -:106D400009F080E023E048E659E06A810F941E15BF -:106D500083E08D83DECE92E09D83C3CE23E02D833E -:106D6000C0CE80913F0910923F09882309F4C2CE1A -:106D70008FEE97E50E947D2480919F05882309F47A -:106D8000B9CE7CCF81E090E09F838E83C8CE809186 -:106D90003F0910923F09882309F4DBCE8EEB98E57A -:106DA0000E947D2480919F05882309F4D2CE66CF6E -:106DB00080913F0910923F09882309F4E7CE0E9491 -:106DC000D92B80919F05882309F4E0CE57CF80917D -:106DD0003F0910923F09882309F4FCCE0E94DD2B65 -:106DE00080919F05882309F4F5CE48CF80913F0913 -:106DF00010923F09882309F411CF0E94CC2B809177 -:106E00009F05882309F40ACF39CF442009F474CFB1 -:106E100022E02D837ECE2F923F924F925F926F920F -:106E20007F928F929F92AF92BF92CF92DF92EF921A -:106E3000FF920F931F93CF93DF9300D0CDB7DEB7B0 -:106E40000E9481CD8111EEC082E0809336090E94BC -:106E500062CD682E61E081E00E9432232091A1057D -:106E60002A83722E2B5F2983572C51949FE0C92EC1 -:106E70009AE0D92E28E0A22E2AE0B22E3FEF832EF0 -:106E800039E0932E8A81811114C09091A0059B83D3 -:106E9000992309F4C9C080917502882351F081E0DB -:106EA000EB81E11180E024E041E25AE0652D0F948E -:106EB0001E150FE316E07801F1E0FB834A804A9447 -:106EC0003A803718F701808591850E94F7CC882396 -:106ED00009F4E2C0FA812B81F2131DC040924709E8 -:106EE00010924B0910924A091092490910924809D0 -:106EF0002090A0052F1609F4BEC08091750288234A -:106F000051F081E09A81291280E023E04FE05AE0BD -:106F1000632D0F941E158B818F5F97E1E90EF11C95 -:106F2000EB81E23009F0A4C0611073C08B838FE362 -:106F3000E82E86E0F82E412C3A803718F70180853C -:106F400091850E94F7CC882309F4F1C0FA812B8146 -:106F5000F2131DC04092470910924B0910924A0942 -:106F600010924909109248092090A0052F1609F4A3 -:106F7000CDC080917502882351F081E09A81291259 -:106F800080E023E048E05AE0632D0F941E158B81CA -:106F90008F5F97E1E90EF11CEB81EF5FEB83F1E08E -:106FA0004F12B1C08B83F12CEA80E718F80180857D -:106FB00091850E94F7CC882309F404C1FA812B81C2 -:106FC000F2131DC0F092470910924B0910924A0922 -:106FD00010924909109248094090A0054F1609F4F3 -:106FE000E0C080917502882351F081E09A814912B6 -:106FF00080E023E04FEF59E06E2D0F941E158B813A -:107000008F5F095E1F4F9B819F5F9B83E1E0FE12B4 -:10701000C5C0FA81FF5FFA8329812F1333CF809394 -:107020009E0510C081E011CF80913F0910923F0969 -:10703000882309F430CF0E946C2E80919F0588230D -:1070400009F429CF0F900F900F90DF91CF911F91EE -:107050000F91FF90EF90DF90CF90BF90AF909F90F7 -:107060008F907F906F905F904F903F902F900895FA -:1070700022E02B8327CF80913F0910923F0988237C -:1070800009F43BCF82EB93E50E947D2480919F051C -:10709000882309F432CFD6CFEA81FB81EF133BCFAF -:1070A0004092470910924B0910924A0910924909DF -:1070B000109248098091A0058E17C1F08091750249 -:1070C000882309F428CF1F92DF92CF923F9281E06C -:1070D0009091A0052A81921380E08F930E947D25D4 -:1070E0000F900F900F900F900F9015CF80913F0948 -:1070F00010923F09882311F30E94522C80919F0522 -:107100008823E1F29FCF4424439418CF80913F0914 -:1071100010923F09882309F42CCF8DEA93E50E9451 -:107120007D2480919F05882309F423CF8BCFEA81AA -:10713000FB81EF132CCF4092470910924B0910921C -:107140004A0910924909109248098091A0058E17AA -:10715000C1F080917502882309F419CF1F92BF9264 -:10716000AF923F9281E09091A0052A81921380E036 -:107170008F930E947D250F900F900F900F900F908E -:1071800006CF80913F0910923F09882311F30E9496 -:107190001D2C80919F058823E1F254CFFF24F394A6 -:1071A00005CF80913F0910923F09882309F419CF38 -:1071B00088EA93E50E947D2480919F05882309F445 -:1071C00010CF40CFEA81FB81EF1319CFF09247092E -:1071D00010924B0910924A091092490910924809DD -:1071E0008091A0058E17C1F080917502882309F463 -:1071F00006CF1F929F928F92EF9281E09091A0050F -:107200002A81921380E08F930E947D250F900F902A -:107210000F900F900F90F3CE80913F0910923F098D -:10722000882311F30E94E82B80919F058823E1F2C7 -:1072300009CF8F929F92AF92BF92CF92DF92EF923F -:10724000FF920F931F93CF93DF9361E081E00E9441 -:107250003223C091A1051C2F85E0882E8C0ED1E031 -:107260009FEBC92E97E2D92E09E00C1B88E0F82E7F -:10727000FC1A87E0E82EEC1A86E0B82EBC1A85E0EE -:10728000A82EAC1A84E0982E9C1AC1112FC0DD23C1 -:10729000D9F08091A0051816BCF040913B0950919F -:1072A0003C0960913D0970913E094F5F5F4F6F4F00 -:1072B0007F4F40933B0950933C0960933D09709385 -:1072C0003E098F5F8093A00580917502882339F075 -:1072D00043E066E17CE0812F81950F949314CF5FAA -:1072E0008C12D3CF8AE080939E0523C0C13071F504 -:1072F000D091A005D13089F080917502882359F092 -:1073000061E0611B81E0D13009F080E024E04CEFC6 -:107310005BE00F941E15D0E0E2CF80913F09109200 -:107320003F09882349F30E946C2E80919F05882392 -:1073300019F3DF91CF911F910F91FF90EF90DF90A4 -:10734000CF90BF90AF909F908F900895C23009F07A -:1073500029C18091A0058230B9F0809175028823FF -:10736000D1F28BE497E29F938F9389EC9BE09F93FC -:107370008F9382E0811B8F9381E09091A0059230E2 -:1073800009F42EC180E02CC180913F0910923F0981 -:10739000882319F30E944B2780919F058823E9F2E7 -:1073A000C8CF80913F0910923F09882309F402C198 -:1073B0000E945E2780919F05882309F4FBC0B9CF06 -:1073C000C43029F58091A0058430A1F08091750228 -:1073D000882309F4A0CF81E797E29F938F938EEBE8 -:1073E0009BE09F938F939F9281E09091A0059430B2 -:1073F00049F6F6C080913F0910923F09882331F386 -:107400000E94712780919F05882301F392CFC53098 -:1074100031F58091A0058530A9F08091750288230F -:1074200009F479CF85E897E29F938F9387EB9BE0F0 -:107430009F938F93AF9281E09091A005953009F0D2 -:10744000A1CFCEC080913F0910923F09882329F334 -:107450000E94852780919F058823F9F26ACFC63064 -:1074600051F58091A0058630A9F08091750288239E -:1074700009F451CF85EF9BEC9F938F9381EB9BE0B9 -:107480009F938F93BF9281E09091A005963009F071 -:1074900079CFA6C080913F0910923F09882329F334 -:1074A00085EF9BEC892B11F00E94F5CB80919F0515 -:1074B0008823D9F23ECFC73031F58091A0058730BF -:1074C000A9F080917502882309F425CF89E997E214 -:1074D0009F938F938CEA9BE09F938F93EF9281E031 -:1074E0009091A005973009F04DCF7AC080913F0967 -:1074F00010923F09882329F30E94992780919F05C4 -:107500008823F9F216CFC83031F58091A005883074 -:10751000A9F080917502882309F4FDCE8CEA97E2E8 -:107520009F938F9385EA9BE09F938F93FF9281E0D7 -:107530009091A005983009F025CF52C080913F0965 -:1075400010923F09882329F30E94AC2780919F0560 -:107550008823F9F2EECEC93009F0C1CE8091A005A2 -:10756000893099F080917502882309F4D4CEDF9296 -:10757000CF928EE99BE09F938F930F9381E0909140 -:10758000A005993009F0FECE2BC080913F091092E2 -:107590003F09882339F30E94BF2780919F058823E4 -:1075A00009F3C7CEC33009F00BCF8091A00583301B -:1075B00009F4F7CE80917502882309F4ACCE8EE5EC -:1075C00097E29F938F9385EC9BE09F938F9383E04B -:1075D000811B8F9381E09091A005933009F0D2CE6A -:1075E0008F930E947D250F900F900F900F900F901A -:1075F0000F9091CECF93DF93CDB7DEB78E81282F3A -:10760000082E000C330B909144129217130609F0C8 -:107610008CF4809344129E01275F3F4F4F81588521 -:107620006AE270E089E192E10F94783910921812C1 -:1076300010921712DF91CF9108950F931F93CF935C -:10764000DF938C016F3F19F41092441260E0209197 -:107650004412862F062E000C990B2817190609F0E4 -:1076600014F560934412C8010F94FE38800F911FE7 -:10767000EC01C01BD10BCB32D1053CF00197FC01D2 -:107680002491207C2038D1F3F3CFDD27AE01B8015F -:1076900089E192E10F941F39C75EDD4E1882109286 -:1076A000181210921712DF91CF911F910F91089528 -:1076B000CF9380914205811109C087E597E09093AF -:1076C00091058093900581E0809342050E945324A8 -:1076D00020E040E070E060E08FE396E20E949323B8 -:1076E000C1E0C09340090E947F8F109240090E9420 -:1076F0006C2EC093400960E081E79CE30E941D3B33 -:107700004091510961E080E00E94092E8DE497E0EC -:107710009093F3088093F208CF9108952F923F92AF -:107720004F925F926F927F928F929F92AF92BF9291 -:10773000CF92DF92EF92FF920F931F93CF93DF933D -:1077400000D000D01F92CDB7DEB780919A06412CB1 -:10775000811103C00E944FCD482E8091A21784FB57 -:10776000222720F92983312C84FF03C00E9473CD86 -:10777000382E61E081E00E9432238091A1058E8342 -:10778000582E8B5F8A8380E00EEA1CE091E0792E10 -:107790007518952D91959B8398E5E92E9BE3F92E1D -:1077A0002BECC22E2CE0D22E92E095199C8393E014 -:1077B00095199D833BE4A32E3CE0B32E42E7842E33 -:1077C0004CE0942E9A812E81921709F463C22223F1 -:1077D00039F1411079C00E9481CD882309F4B2C1EA -:1077E0008E81813009F47DC192E09F832E818F814B -:1077F000281398C12090A005221609F4A5C18091F4 -:107800007502882309F48EC16E81651981E09E811D -:10781000291280E023E047EA5CE00F941E1582C144 -:107820006090A005662059F180917502882389F245 -:1078300081E0611080E024E047ED5CE06B810F9413 -:107840001E15442041F224E02F838F819E818913ED -:107850005EC02090A005281609F487C180917502AA -:10786000882309F454C06E81651981E02E812212AB -:1078700080E023E04BE95CE00F941E1548C0809146 -:107880003F0910923F09882379F20E946C2E809163 -:107890009F05882349F227960FB6F894DEBF0FBEE6 -:1078A000CDBFDF91CF911F910F91FF90EF90DF90AF -:1078B000CF90BF90AF909F908F907F906F905F9090 -:1078C0004F903F902F9008958E81813009F4A8C089 -:1078D000823009F4D0C09E81933009F0B4CF8091FA -:1078E000A0058F83833009F4EBC080917502882353 -:1078F00009F4A9CF81E09F81933009F080E023E073 -:107900004BEB5CE06D810F941E1524E02F838F817B -:107910008F5F9E81891314C02090A005291609F459 -:1079200035C180917502882359F06E81651981E017 -:107930002E81221280E023E04DE85CE00F941E15BA -:107940008F818E5F9E81891314C02090A005291617 -:1079500009F42DC180917502882359F06E81651953 -:1079600081E02E81221280E023E04DE75CE00F945D -:107970001E158F818D5F9E81891314C02090A005F4 -:10798000291609F425C180917502882359F06E816A -:10799000651981E02E81221280E023E046E75CE059 -:1079A0000F941E158F818C5F9981992309F444C12E -:1079B000311032C02E81821314C09091A00592170D -:1079C00009F417C180917502882359F06E816519F9 -:1079D00081E02E81921380E020E245E65CE00F9486 -:1079E0001E158F818B5F9E81891314C02090A00586 -:1079F000291609F410C180917502882359F06E810F -:107A0000651981E02E81221280E023E044E55CE0EC -:107A10000F941E158F818A5F9E819F5F9E83D2CEB9 -:107A20008091A0058130D1F080917502882309F4FE -:107A30000ACFFF92EF92DF92CF927F9281E09091F6 -:107A4000A005913009F080E08F930E947D250F9072 -:107A50000F900F900F900F900F90F5CE80913F09EF -:107A600010923F09882301F30E94583B80919F05A3 -:107A70008823D1F210CF2091A0052F83223089F0E6 -:107A800080917502882309F4DECE81E09F819230D7 -:107A900009F080E023E040EC5CE06C810F941E155F -:107AA000D2CE80913F0910923F09882349F38FEA93 -:107AB00096E20E947D2480919F05882309F3EBCEF6 -:107AC00080913F0910923F09882309F40ECF8AEF75 -:107AD00098E40E947D2480919F05882309F405CFB6 -:107AE000DACE8091A005813001F180917502882362 -:107AF00009F47ACE8EE297E29F938F931F930F93B0 -:107B00007F9281E09091A005913009F080E08F9301 -:107B10000E947D250F900F900F900F900F900F9067 -:107B200082E08F832F812F5F8FCE80913F0910924B -:107B30003F098823D1F20E942E2780919F05882338 -:107B4000A1F2A9CE91E051CE80913F0910923F0958 -:107B5000882309F454CE82EA90E30E947D24809128 -:107B60009F05882309F44BCE96CE80913F09109251 -:107B70003F09882309F472CE8FE19EE40E947D24A0 -:107B800080919F05882309F469CE85CE80913F09B5 -:107B900010923F09882309F4C4CE86E195E30E9440 -:107BA0007D2480919F05882309F4BBCE74CE8091FB -:107BB0003F0910923F09882309F4CCCE8BE097E36C -:107BC0000E947D2480919F05882309F4C3CE63CE53 -:107BD00080913F0910923F09882309F4D4CE84E2B2 -:107BE00091E50E947D2480919F05882309F4CBCEE6 -:107BF00052CE80913F0910923F09882309F4E2CECA -:107C00009092F3088092F20880919F05882309F4EE -:107C1000D9CE8E8101CF80913F0910923F098823F0 -:107C200009F4E9CE83EF9DE60E947D2480919F05B3 -:107C3000882309F4E0CEEDCF9E8189131DC0909179 -:107C4000A0052E819217D9F0809175028823A1F0AA -:107C50001F921F92BF92AF928E8185198F9381E000 -:107C60002E81921380E08F930E947D250F900F90BC -:107C70000F900F900F900F908F818B5FCDCE8091E2 -:107C80003F0910923F098823F9F280919F058823CC -:107C9000D9F2BFCF80939E05FECD10924F0910926E -:107CA00074020E9473CD9091A21780FB97F9909374 -:107CB000A21760E08FE397E00E941D3B0C945E2DBD -:107CC0000F931F930F941E1D00913E0510913F05C9 -:107CD0002091400530914105601B710B820B930B85 -:107CE00097FD0BC086B18295817091E08927369B04 -:107CF0008260329B84608093FF038091FF038170D8 -:107D00009091FF0391FD826090913D05981749F095 -:107D1000813029F148F0823089F08330A1F08093DE -:107D20003D051F910F910895913089F09230B9F778 -:107D300090913C0520911B02921B0EC0992339F0B3 -:107D40009330B1F3ECCF913099F3923041F79091A9 -:107D50003C0520911B02920F90933C05E0CF9923A4 -:107D600039F39330E1F6F3CFFC0180E0309749F02E -:107D70009491992331F0907C903809F08F5F31967F -:107D8000F7CF0895AF92BF92CF92DF92EF92FF921A -:107D90000F931F93CF93DF93EC015B018A01FB01EB -:107DA000199587FD16C0C82ED12CF12CE12C2196F7 -:107DB000F801C082D182E282F382CE01DF91CF91BD -:107DC0001F910F91FF90EF90DF90CF90BF90AF90F9 -:107DD0000895982F907E903CA9F48F7190E0B0E0C8 -:107DE000A0E06C017D0156E0CC0CDD1CEE1CFF1CFC -:107DF0005A95D1F7CE010196F50119958F73C82ACE -:107E00002296D6CF982F907F903E11F58F7090E0FC -:107E1000B0E0A0E06C017D0136E0CC0CDD1CEE1C76 -:107E2000FF1C3A95D1F7CE010196F50119958F7394 -:107E3000C82A46E0CC0CDD1CEE1CFF1C4A95D1F78D -:107E4000CE010296F50119958F73C82A2396B0CFFB -:107E5000982F987F903F79F5877090E0B0E0A0E090 -:107E60006C017D0186E0CC0CDD1CEE1CFF1C8A95AC -:107E7000D1F7CE010196F50119958F73C82A96E0C6 -:107E8000CC0CDD1CEE1CFF1C9A95D1F7CE0102969E -:107E9000F50119958F73C82A26E0CC0CDD1CEE1C69 -:107EA000FF1C2A95D1F7CE010396F50119958F7322 -:107EB000C82A24967DCF982F907C903841F4807CFE -:107EC000803869F42196CE01F5011995F8CF8E7F9F -:107ED0008D3F28F02196CE01F5011995F8CFC12CE0 -:107EE000D12C760165CF9CE0899F802D112491E0F3 -:107EF000980F909304052CE0280F2093460930E05A -:107F00002E5F3F4F40917D164217130619F014F073 -:107F100080E0089520917F169217D0F7662341F0F4 -:107F20008E5F0F947423809146098E5F0F947423A3 -:107F30008091460990917D16891750F320917F1604 -:107F400090910405291720F31092801680938116D2 -:107F500081E0089520910205022E000C330B821758 -:107F6000130641F0809302056CEE7EE089E496E111 -:107F70000D94192508951F93CF93DF931F92CDB7CA -:107F8000DEB710912E0280918216811105C081E02A -:107F9000809382160F94492260914B1670914C1673 -:107FA00019839E012F5F3F4F4FE089E496E10F94C4 -:107FB00045220F90DF91CF911F910895CF9380912B -:107FC000030581114FC010928016109281161092F5 -:107FD000821610924E1610924D1610925016109254 -:107FE0004F161092521681E08093511682E28093D0 -:107FF00053161092581610925716ECE6F6E12AE73F -:1080000036E18FEF81932E173F07E1F7C1E0C09370 -:10801000691622E132E030935F1620935E16C0931A -:108020006016109261161092621690E49093631697 -:10803000109264162AE231E030937B1620937A1670 -:1080400028E032E030934C1620934B1691E1909348 -:108050006E1690E190936D1680936C160F944922E2 -:10806000C0930305099A11988FE19EE40197F1F7F7 -:1080700000C00000119A8FE19EE40197F1F700C063 -:108080000000C1E0C09382160F9449228FEF8093C5 -:108090002E020E94BB3FC093FA038DE096E09093BE -:1080A000880F8093870F10928A0F1092890FCF91BB -:1080B00008950E94DE3F3C98449A3E98469A3A982A -:1080C000429A0E94603E10923C050D948E10EF92F1 -:1080D000FF920F931F93CF93DF93CDB7DEB72C970B -:1080E0000FB6F894DEBF0FBECDBFFC016081718179 -:1080F000828193816F3F71058105910509F0C0F47C -:1081000085E496E10E940929E0914D16F0914E1602 -:108110003196849190E02C960FB6F894DEBF0FBE96 -:10812000CDBFDF91CF911F910F91FF90EF900895F8 -:1081300010918016009181162091FA0321110FC031 -:108140004DEE55E0602F812F0F94DD2590E080E00B -:10815000180F10938016009381169927DCCFE090BA -:108160004D16F0904E1629E436E13A832983212FEB -:1081700030E03C832B83202F30E03E832D83188614 -:108180001F822FEF3FEF3A8729871C861B8627EA3D -:1081900038E2AE014F5F5F4FBF01C7010F948B0FF5 -:1081A000B70189E496E10F9419258F819885D0CF86 -:1081B0004F925F926F927F928F929F92BF92CF92D7 -:1081C000DF92EF92FF920F931F93CF93DF9300D034 -:1081D00000D01F921F92CDB7DEB77C016A01490122 -:1081E000FB0190818CE0989F800D1124982FF7015E -:1081F0002081822F880F820F880F809380169093A2 -:1082000081164115510579F1FA82E9827C836B83ED -:10821000011122C0AE014B5F5F4FB401C6010E9445 -:10822000C23E6C018D819E81AF81B885892B8A2BDE -:108230008B2BC9F0CE0105960E946740F701808123 -:108240008F5F8083853130F3CE0101960E948B24AD -:10825000E1CFB12C860129C08A01B12C26C0452866 -:1082600046284728B1F728960FB6F894DEBF0FBE10 -:10827000CDBFDF91CF911F910F91FF90EF90DF90D5 -:10828000CF90BF909F908F907F906F905F904F9016 -:108290000895B39407C0B1102EC001151105C9F29D -:1082A0000F5F1F4F01151105A9F2AE014B5F5F4F24 -:1082B000B401C6010E94C23E6C014D805E806F8099 -:1082C00078844114510461047104A9F0F0E24F165E -:1082D000510461047104F9F2D301C2018D97A1091F -:1082E000B1090297A105B10530F04BE244165104E3 -:1082F0006104710471F6F7018081482F4B0D5527F9 -:10830000551F4631510534F0853020F0CE010196DD -:108310000E948B2481E0411451046104710409F42A -:1083200080E0B80EF70180818B0D8083BB2009F4BB -:1083300096CFBA94AE014B5F5F4FB401C8010E9463 -:10834000C23E8C01CE0105960E946740EFCF6F922E -:108350007F928F929F92AF92BF92CF92DF92EF92D5 -:10836000FF920F931F93CF93DF9300D000D01F9203 -:108370001F92CDB7DEB77C01162F5A014901862F17 -:10838000660F990B9C0124563D4F690186E0682ECB -:10839000712C10160CF046C0AE014B5F5F4F61EAC6 -:1083A00074E2C7010E94C23E7C018D819E81AF8133 -:1083B000B8850097A105B105A9F18D339105A105F7 -:1083C000B10509F480C08E379105A105B10509F406 -:1083D0007AC08A329105A105B105D1F517FF12C007 -:1083E00083E596E01E3F11F08FE496E036E003024D -:1083F000B00111240E947FC766E070E00F944841ED -:10840000061B9BC085E490E0A0E0B0E089839A83DE -:10841000AB83BC83CE0101960E946740015009F0F6 -:1084200054C000E0802F28960FB6F894DEBF0FBE30 -:10843000CDBFDF91CF911F910F91FF90EF90DF9013 -:10844000CF90BF90AF909F908F907F906F90089546 -:1084500084329105A105B105D1F48114910461F034 -:10846000E6E00E02B0011124C4010E947FC7B301EF -:108470000F944841061B8DCFA114B104F1F0F6E032 -:108480000F02B0011124C5010E94DDC7F0CF803476 -:108490009105A105B10589F40150F6018081082EEE -:1084A000000C990BAA0BBB0B89839A83AB83BC830B -:1084B000CE0101960E9467406CCFCE0105960E94C6 -:1084C0006740015066CF17FD8BCF81E04D815E8103 -:1084D0006F8178854D3351056105710509F480E0A0 -:1084E000810F8A30CCF001506AE00F942641D92EDA -:1084F000082E000C990BC096092E000CAA0BBB0B82 -:1085000089839A83AB83BC83CE0101960E94674026 -:10851000002309F486CF8D2D082E000C990BC096F0 -:10852000092E000CAA0BBB0B89839A83AB83BC83F7 -:10853000CE0101960E9467400150002309F471CFDB -:1085400086E00802B0011124C7010E947FC766E0DF -:1085500070E00F944841061B65CF6FEF7FEF0C94DE -:10856000DDC72F923F924F925F926F927F928F92D0 -:108570009F92AF92BF92CF92DF92EF92FF920F93B2 -:108580001F93CF93DF9300D000D01F92CDB7DEB7FB -:108590004C010F94FE3801966401C80ED91EC60125 -:1085A0000F94FE3801961601280E391ED601EC9064 -:1085B00001E0E11001C000E0F101408077247394F4 -:1085C000411001C0712C11E0E11010E060E085E085 -:1085D0000E9432235090A105F52C9EE0A92EB12CCB -:1085E000F52DF195FF83812F90E00196080F192F4B -:1085F000111D9801270D311D3E832D83F1101BC0E5 -:1086000080917502882391F0E0911A02E2506AE4A9 -:108610007AE0E33038F4F0E0EE0FFF1FE654FD4F50 -:108620006081718143E08F810F94931401E0E11028 -:1086300011C002E00FC002E0E11001E00F110AC01A -:1086400080917502882331F041E0B401802F8519B3 -:108650000F94931411E0100F7F2C7518EE2069F021 -:108660001F1109C080917502882329F041E0B601ED -:10867000872D0F94931412E0100F442061F01F1106 -:1086800009C080917502882329F041E0B101872D4E -:108690000F9493141F5F4D815E81433051050CF49C -:1086A0001F5F1F1190C080917502882309F488C054 -:1086B00042E067E57AE0872D0F9493149EEF9A0DC0 -:1086C00080917D168A151B0411F00CF079C0209161 -:1086D0007F1683EF8A0D821708F072C000910004A4 -:1086E00025E430E040E050E029833A834B835C830B -:1086F0003EE33093801690938116CE0101960E943E -:10870000674081E3800F082E000C990BAA0BBB0B6E -:1087100089839A83AB83BC83CE0101960E94674014 -:1087200080E290E0A0E0B0E089839A83AB83BC83D1 -:10873000CE0101960E946740602E712C97E1969DB4 -:10874000F001979DF00D1124E15CF94F20E030E03D -:1087500040E05FE364817581868197810F94083ED4 -:108760000F94743FCB010E9492BD0E94AD422FE254 -:1087700030E040E050E029833A834B835C83CE01B4 -:1087800001960E9467400E94F22481110BC035E0DF -:10879000369DF001379DF00D1124E25EF94F848182 -:1087A00081110EC047E1469DF001479DF00D112457 -:1087B000E15CF94F808591850E9492BD0E94AD4297 -:1087C00052E0509375028CE0A80EB11CF3949AE429 -:1087D000A916B10409F012CF1F5F10939E052796CA -:1087E0000FB6F894DEBF0FBECDBFDF91CF911F91C2 -:1087F0000F91FF90EF90DF90CF90BF90AF909F9040 -:108800008F907F906F905F904F903F902F90089542 -:1088100082E69AE00C94B1428FE69AE00C94B14261 -:1088200081E99AE00C94B1428CE29BE00C94B14255 -:1088300087EE9AE00C94B14284E19BE00C94B14243 -:1088400087E69BE00C94B1428AE49BE00C94B14231 -:108850008AEC9AE00C94B1428BEA9AE00C94B14213 -:108860008F929F92AF92BF92CF92DF92EF92FF9240 -:108870000F931F93CF93DF9300D01F92CDB7DEB736 -:108880004C016B0181E080931B02C4010E94B43E45 -:10889000A82EC6010E94A724B12C23E130E0790163 -:1088A000E81AF10815E2EA14FB040CF41FE1812F29 -:1088B00090E09C012E5F3F4F40917D1642171306BA -:1088C00011F00CF04AC0099720917F16281719065D -:1088D0000CF443C020914A0930914B09409148095A -:1088E00050914909609147091092801610938116A2 -:1088F00005E1C4010E94A74101E0C114D104E1F0E7 -:108900008AE390E0A0E0B0E089839A83AB83BC83E4 -:10891000CE0101960E946740EA14FB0404F5145F3F -:1089200080917D16181740F020917F16412F4950F5 -:10893000550B24171506ACF40F900F900F900F9065 -:10894000DF91CF911F910F91FF90EF90DF90CF902B -:10895000BF90AF909F908F90089500E0CECF0023FE -:1089600059F380E290E0A0E0B0E089839A83AB8382 -:10897000BC838E2D880FE80EEE0CE09280161093CB -:108980008116CE0101960E946740C6010E94AD4249 -:10899000D3CF1F93CF93DF9300D01F92CDB7DEB715 -:1089A000182F80913F0910923F09882361F010929F -:1089B00040090E946C2E0F900F900F900F90DF9146 -:1089C000CF911F91089560913B0970913C0980916E -:1089D0003D0990913E09611571058105910569F187 -:1089E0000F94B83920911C0230911D0240911E0253 -:1089F00050911F020F94173A209182023091830206 -:108A000040918402509185020F94083E6093820247 -:108A1000709383028093840290938502612F83E098 -:108A20000E94B82481E08093750210923B09109255 -:108A30003C0910923D0910923E09809175028823ED -:108A400009F4B9CF1093470910924B0910924A09C3 -:108A50001092490910924809209198053091990582 -:108A600040919A0550919B0560918202709183021A -:108A700080918402909185020F94073E69837A83E6 -:108A80008B839C83CE0101960E9497BCBC018AE631 -:108A90009DE00E9430448FCF81E00C94C94480E077 -:108AA0000C94C944809151090C94C9443F924F924F -:108AB0005F926F927F928F929F92AF92BF92CF926E -:108AC000DF92EF92FF920F931F93CF93DF9300D02B -:108AD00000D000D01F92CDB7DEB7382E80913F096D -:108AE00010923F098823E1F0109240090E946C2EF9 -:108AF0002A960FB6F894DEBF0FBECDBFDF91CF919F -:108B00001F910F91FF90EF90DF90CF90BF90AF90AB -:108B10009F908F907F906F905F904F903F900895BF -:108B200060913B0970913C0980913D0990913E090B -:108B3000611571058105910509F459C0209137022D -:108B4000222309F4B9C0209138022111B5C021E0D7 -:108B5000321609F48FC0A2E03A1609F49CC0C09006 -:108B60003902D0903A02E0903B02F0903C024090F3 -:108B700045025090460260904702709048020F9460 -:108B8000B83920911C0230911D0240911E02509173 -:108B90001F020F94173A6F83788789879A87B4E00A -:108BA0003B9E80011124F801EA58FD4FFE83ED83BE -:108BB00020813181428153810F94083E4B015C0139 -:108BC000A3019201C701B6010F94B139811183C08D -:108BD000F801EA58FD4F80829182A282B3826091AF -:108BE0005109832D0E94B82481E080937502109270 -:108BF0003B0910923C0910923D0910923E09809168 -:108C00007502882309F474CF30924709F4E03F9E3F -:108C1000C0011124FC01EA58FD4F8359904FDC013B -:108C20002D913D914D915C91608171818281938103 -:108C30000F94083E6B017C01C982DA82EB82FC82D0 -:108C40002DEC3CEC4CEC5DE360911C0270911D023C -:108C500080911E0290911F020F94684087FD66C0AC -:108C6000CE0101960E9497BCBC018FE79DE00E9457 -:108C700030443ECFC0903D02D0903E02E0903F0293 -:108C8000F09040024090490250904A0260904B029E -:108C900070904C0274CFC0904102D0904202E0909C -:108CA0004302F090440240904D0250904E0260907A -:108CB0004F027090500263CF412C20E5522E23ECDE -:108CC000622E27E4722EC12C30E5D32E33ECE32E36 -:108CD00037ECF32E54CF20E030E0A9016F81788586 -:108CE00089859A850F94B13987FF10C0A701960135 -:108CF000C501B4010F94B13987FF6ACFAD81BE8140 -:108D0000CD92DD92ED92FC92139769CFA30192016F -:108D1000C501B4010F94684018160CF059CFED81CD -:108D2000FE81408251826282738259CF20E030E01E -:108D300040E251E4C701B6010F94173A20E030E059 -:108D40004AE754E40F94173A4B015C0120E030E00D -:108D5000A901C701B6010F94B13920E030E040EA23 -:108D600050E487FF04C020E030E040EA50ECC50149 -:108D7000B4010F94083E20E030E040E251E40F944B -:108D8000023F0F94743F6B017C01F7FC62C020EA44 -:108D900036E841E050E00F94C63DCA01B9012AE02F -:108DA00030E040E050E00F94C63D605D6093A20566 -:108DB000C701B60120E137E240E050E00F94C63D24 -:108DC0008AE0882E912CA12CB12CCA01B901A501F1 -:108DD00094010F94C63D605D6093A305C701B60181 -:108DE00028EE33E040E050E00F94C63DCA01B901DF -:108DF000A50194010F94C63D605D6093A4058EE2C9 -:108E00008093A505C701B60124E630E040E050E0BC -:108E10000F94C63DCA01B901A50194010F94C63D46 -:108E2000605D6093A605C701B601A50194010F948A -:108E3000C63D162FCA01B901A50194010F94C63D84 -:108E4000605D6093A705105D1093A80582EA95E028 -:108E50000BCFF094E094D094C094C11CD11CE11CC1 -:108E6000F11C6DE2A3CF82E00C94564581E00C9496 -:108E7000564580E00C9456450F931F93CF93DF9394 -:108E8000FC01EB0180913B0990913C09A0913D09C7 -:108E9000B0913E09B7FF08C010923B0910923C09FF -:108EA00010923D0910923E098091830590918405AE -:108EB000A0918505B091860540913B0950913C09F0 -:108EC00060913D0970913E0984179507A607B70781 -:108ED00044F480933B0990933C09A0933D09B093DF -:108EE0003E09809175028823E1F060913B09709101 -:108EF0003C0980913D0990913E09009187051091B0 -:108F000088052091890530918A05600F711F821FA5 -:108F1000931F1995BC0180918D0590918E050E943B -:108F2000304480913F09811108C0809180058823D9 -:108F3000D1F1809175028823B1F180918B059091D8 -:108F40008C050097B1F040913B0950913C0960912C -:108F50003D0970913E090091870510918805209187 -:108F6000890530918A05400F511F621F731FFE0152 -:108F70001995E0918105F0918205309741F080913B -:108F80008005811103C080913F098111199580915D -:108F90003F0910923F09882331F0DF91CF911F9153 -:108FA0000F910C946C2EDF91CF911F910F9108952A -:108FB00062EF7EE18FE895E20C943C4760E57FE14B -:108FC00084E497E20C943C4760EB70E28AE695E219 -:108FD0000C943C4767ED70E28AE295E20C943C47C2 -:108FE00068EE72E28CEF92E20C943C4762E972E226 -:108FF00086EA92E20C943C4760EB72E28BEE97E2D9 -:109000000C943C4766EC72E288E298E20C943C4790 -:109010006AED72E282E398E20C943C4766E073E208 -:1090200083E695E20C943C4769EC70E28EE698E2A8 -:109030000C943C4764E173E288E293E20C943C4771 -:109040004F925F926F927F928F929F92AF92BF9258 -:10905000CF92DF92EF92FF920F931F93CF93DF9304 -:10906000CDB7DEB72C970FB6F894DEBF0FBECDBFDD -:10907000982F862F5A017901D02E692F0E94733FB5 -:10908000882309F49CC01091FA03C701002309F456 -:1090900041C00E94B43EC82E80904D1690904E164E -:1090A000111155C01FEF03E10C1920914A093091AD -:1090B0004B09409148095091490960914709C50100 -:1090C0000E94A741CC2009F47AC0B6E08B9F5001E2 -:1090D00011248AE390E0A0E0B0E089839A83AB8317 -:1090E000BC83CE0101960E94674080E2482E512C3D -:1090F000612C712C57E0A516B10408F445C04982D3 -:109100005A826B827C82CE0101960E946740A81A27 -:10911000B90AF0CF0E94A724C82E80904D169090D7 -:109120004E16112309F4BECFFE0133968AE0DF010B -:109130001D928A95E9F789E496E19A8389830EE77F -:1091400018E29E012F5F3F4F44EA54E212C0FE0135 -:1091500033968AE0DF011D928A95E9F789E496E16A -:109160009A8389830EE718E29E012F5F3F4F41EA01 -:1091700054E2B701C4010F945010B40189E496E1A0 -:109180000F9419251F818FCF40914609212F30E080 -:10919000A6E0CA9EC00111242E5F3F4F2817390751 -:1091A0000CF49C0180E8821B80938016409381160A -:1091B000DD20E1F06FEF7FEFC7010E947FC72C96A3 -:1091C0000FB6F894DEBF0FBECDBFDF91CF911F91D8 -:1091D0000F91FF90EF90DF90CF90BF90AF909F9056 -:1091E0008F907F906F905F904F900895C7010E947D -:1091F000AD42E5CF6F927F928F929F92AF92BF92D6 -:10920000CF92DF92EF92FF920F931F93CF93DF9352 -:1092100061E081E00E943223C091A105DC2FF5E0DE -:10922000AF2EAC0E81E0D82EDC1A9C2E9194A7E1D3 -:10923000BA2E8824839484E0C82ECC1AC11142C16E -:109240001091A005112309F420C180917502882393 -:1092500049F081E0111180E024E047EE5EE0692DE5 -:109260000F941E15F12CE12CE2E07E2E6C2E6D1A6F -:10927000C7112BC0E092470910924B0910924A097E -:1092800010924909109248098091A0058C1709F4A1 -:1092900051C1809175028823C1F011E08091A00531 -:1092A000871110E0BE9CF001BF9CF00D1124E15C21 -:1092B000F94F808591850E9492BD00E09C0148EDA8 -:1092C0005EE0662D812F0E942048872D9FEFE91ACE -:1092D000F90A63E0762E833059F6C430E9F48091C0 -:1092E000A005843009F44DC1809175028823A1F056 -:1092F00011E08091A005843009F010E080913606DD -:10930000909137060E9492BD00E09C0144ED5EE022 -:109310006C2D812F0E9420488091D20580933609C0 -:10932000C53031F51092470910924B0910924A0945 -:1093300010924909109248098091A005853009F4DE -:109340003BC180917502882399F0FC2EFD1A11E033 -:109350008091A0058C1310E0809136090E942ABEEE -:1093600000E09C0148EC5EE06F2D812F0E942048B8 -:109370008091D30580933609C63031F58092470934 -:1093800010924B0910924A0910924909109248090B -:109390008091A005863009F424C18091750288234C -:1093A00099F0FC2EFD1A11E08091A0058C1310E0BD -:1093B000809136090E942ABE00E09C0148EC5EE0E4 -:1093C0006F2D812F0E942048C73019F58091A0058C -:1093D000873009F41BC1809175028823D1F0FC2EDF -:1093E000FD1A11E08091A0058C1310E0E091510965 -:1093F000F0E0EE0FFF1FEE5DFD4F808191810E9436 -:1094000092BD00E09C0143EC5EE06F2D812F0E9435 -:10941000204838E0732EF12CE12C6C2E6D1AC71108 -:1094200029C0E092470910924B0910924A09109204 -:109430004909109248098091A0058C1709F408C1C8 -:10944000809175028823B1F011E08091A005871109 -:1094500010E0F701EE0FFF1FEE5DFD4F808191815F -:109460000E9492BD00E09C014CEB5EE0662D812FD6 -:109470000E9420487394EA94EF2809F0E5C0CF5F7A -:10948000AC12DCCE70929E050EC080913F09109206 -:109490003F09882309F4D9CE0E946C2E80919F0544 -:1094A000882309F4D2CEDF91CF911F910F91FF90C5 -:1094B000EF90DF90CF90BF90AF909F908F907F9074 -:1094C0006F900895C13009F0CDCE8091A005813014 -:1094D000D1F080917502882309F4C4CE11E0809107 -:1094E000A005813009F010E08091200290912102C6 -:1094F0000E9492BD00E09C0141EE5EE06D2D812F47 -:109500000E942048AFCE80913F0910923F098823E6 -:1095100001F310E000E027EE33E04AE050E060E2C3 -:1095200072E081EE9EE00F94CC1680919F05882317 -:1095300081F2B9CF80913F0910923F09882309F445 -:10954000A8CE0F94BF15F701EE0FFF1FE054FD4F9B -:10955000208131812F503109BE9CB001BF9C700D1C -:109560001124695B794F0BE815E250E040E088ED8B -:109570009EE00F94CC1680919F05882309F489CE34 -:1095800092CF80913F0910923F09882309F4ACCE15 -:109590000F94BF1502E216EC24E630E050E040E004 -:1095A00066E376E084ED9EE00F94CC1680919F05F3 -:1095B000882309F499CE77CF80913F0910923F0913 -:1095C000882309F4BECE0F94BF1566E07FE188ECD6 -:1095D0009EE00F94A41780919F05882309F4B1CED3 -:1095E00062CF80913F0910923F09882309F4D5CEBC -:1095F0000F94BF1566E07FE188EC9EE00F94A417FE -:1096000080919F05882309F4C8CE4DCF80913F09F2 -:1096100010923F09882309F4DECE6091510970E071 -:10962000660F771F6E5D7D4F0EEB1EE127EE33E078 -:109630004AE050E083EC9EE00F94CC1680919F05A9 -:10964000882309F4C8CE2FCFEE24E394F12CE7CE83 -:1096500080913F0910923F09882309F4F1CEB701A8 -:10966000660F771F6E5D7D4F0AE81EE127EE33E03F -:109670004AE050E08CEB9EE00F94CC1680919F0561 -:10968000882309F4DDCE0FCFAF92BF92CF92DF9245 -:10969000EF92FF920F931F93CF93DF9361E081E0EE -:1096A0000E943223C091A10585E0B82EBC0ED5E002 -:1096B000DC1B14E01C1B83E0F82EFC1A82E0E82E71 -:1096C000EC1A81E0D82EDC1AAC2EA194C1112FC067 -:1096D000C090A005CC20A1F080917502882349F0AC -:1096E00081E0C11080E024E04DE65EE06A2D0F9439 -:1096F0001E15CF5FCB11EACF86E080939E050CC08C -:1097000080913F0910923F09882331F30E946C2E0B -:1097100080919F05882301F3DF91CF911F910F91D5 -:10972000FF90EF90DF90CF90BF90AF900895C13041 -:1097300089F58091A0058130D1F080917502882350 -:10974000C1F2CC24C3948091A005813009F0C12CD2 -:109750008091E8159091E9150E94C7BD00E09C0139 -:1097600048E55EE06D2D8C2D0E942048C2CF80918F -:109770003F0910923F09882301F346E756E268EE5D -:1097800075E188E59EE00F94141880919F05882369 -:10979000A1F2C2CFC23009F0A0C08091A0058230F2 -:1097A000C1F080917502882309F4A3CFCC24C3941F -:1097B0008091A005823009F0C12C8091AC15909168 -:1097C000AD150E94C7BD00E09C0146E55EE06E2D30 -:1097D000CACF80913F0910923F09882311F34EE6CA -:1097E00056E26CEA75E186E59EE00F9414188091CC -:1097F0009F058823B1F290CF8091A0058330C1F0FE -:1098000080917502882309F474CFCC24C39480918D -:10981000A005833009F0C12C8091701590917115CD -:109820000E94C7BD00E09C0144E55EE06F2D9BCF28 -:1098300080913F0910923F09882311F346E656E2D2 -:1098400060E775E184E59EE00F94141880919F0510 -:109850008823B1F261CF8091A0058430C1F080915E -:109860007502882309F445CFCC24C3948091A005C8 -:10987000843009F0C12C80913415909135150E94E7 -:10988000C7BD00E09C0141E55EE0612F6CCF809197 -:109890003F0910923F09882311F34EE556E264E335 -:1098A00075E181E59EE00F94141880919F0588234F -:1098B000B1F232CF80913F0910923F098823D1F055 -:1098C00046E556E268EF74E18EE49EE00F941418CA -:1098D00080919F05882371F01FCFC33009F48CCF8E -:1098E000C43009F4B8CFC53009F003CF8091A0058A -:1098F000853001F380917502882309F4FACECC24D7 -:10990000C3948091A005853009F0C12C8091F81492 -:109910009091F9140E94C7BD00E09C014EE45EE006 -:109920006D2F21CF7F928F929F92AF92BF92CF9255 -:10993000DF92EF92FF920F931F93CF93DF9361E03B -:1099400081E00E943223C091A1059C2E85E0A82EC3 -:10995000AC0ED1E011E093E0F92E86E0E82EEC1A8F -:1099600085E0D82EDC1A84E0C82ECC1A8F2C8C1AF5 -:1099700082E0B82EBC1A7D2E7C1AC1112FC0DD23C7 -:10998000D9F08091A0051816BCF040913B09509188 -:109990003C0960913D0970913E094F5F5F4F6F4FE9 -:1099A0007F4F40933B0950933C0960933D0970936E -:1099B0003E098F5F8093A00580917502882339F05E -:1099C00041E069E77EE0892D81950F949314CF5F84 -:1099D000AC12D3CF87E080939E0522C0C13071F5D1 -:1099E000D091A005D13081F080917502882351F08B -:1099F00081E0D13009F080E024E04DE65EE0672DA3 -:109A00000F941E15D0E0E3CF80913F0910923F09DB -:109A1000882351F30E946C2E80919F05882321F3A7 -:109A2000DF91CF911F910F91FF90EF90DF90CF903A -:109A3000BF90AF909F908F907F900895C23009F0B3 -:109A4000DEC08091A0058230C9F080917502882324 -:109A5000C9F281E09091A005923009F080E09091E8 -:109A6000EA1528E63EE0911102C024E63EE001E05E -:109A70004BE65EE06B2D0E942048C4CF80913F09E9 -:109A800010923F09882309F38091EA15812780937A -:109A9000EA15F09275020E94542680919F05882352 -:109AA000A1F2BECF80913F0910923F09882309F4AB -:109AB000AEC08091AE1581278093AE15C09375021C -:109AC0000E94522680919F05882309F4A0C0A8CF48 -:109AD000C43081F58091A0058430C1F08091750279 -:109AE000882309F48FCF81E09091A005943009F08C -:109AF00080E09091721528E63EE0911102C024E6C4 -:109B00003EE001E040E65EE06C2DB5CF80913F097C -:109B100010923F09882311F3809172158127809359 -:109B20007215F09275020E94502680919F0588233D -:109B3000A9F276CFC53081F58091A0058530C1F0BE -:109B400080917502882309F45DCF81E09091A00592 -:109B5000953009F080E09091361528E63EE09111AD -:109B600002C024E63EE001E04DE55EE06D2D83CFCE -:109B700080913F0910923F09882311F38091361597 -:109B8000812780933615F09275020E944E268091AF -:109B90009F058823A9F244CFC63009F018CF8091E1 -:109BA000A0058630C1F080917502882309F42ACF80 -:109BB00081E09091A005963009F080E09091FA1430 -:109BC00028E63EE0911102C024E63EE001E04AE5CD -:109BD0005EE06E2D50CF80913F0910923F0988239F -:109BE00011F38091FA1481278093FA14F092750290 -:109BF0000E944C2680919F058823A9F211CFC33083 -:109C000009F066CF8091A005833009F44BCF809195 -:109C10007502882309F4F6CE81E09091A005933077 -:109C200009F080E09091AE1528E63EE0911102C067 -:109C300024E63EE001E042E65EE0682D1CCF2F9274 -:109C40003F924F925F926F927F928F929F92AF92CC -:109C5000BF92CF92DF92EF92FF920F931F93CF9319 -:109C6000DF9300D0CDB7DEB78091470690914806CC -:109C700077247394892B39F480915E0690915F0666 -:109C8000892B09F4712C61E081E00E9432238091DC -:109C9000A1058A838B83982F9B5F9983382E3194FB -:109CA00083E0582EEA815E1A55E0452E66E6A62E20 -:109CB0006DE2B62E7DE1872E7EE0972EFA81F111BE -:109CC00012C01091A005112309F43DC180917502C5 -:109CD000882349F081E0111180E024E049E45EE04E -:109CE000632D0F941E154FE3C42E46E0D42EF12CA5 -:109CF000E12C662463942A808B81281AF6018085E2 -:109D000091859093370980933609FA81F61126C020 -:109D1000E092470910924B0910924A0910924909A2 -:109D2000109248098091A0058F1709F430C18091E5 -:109D30007502882399F011E08091A005861110E04A -:109D400080913609909137090E9492BD00E09C01F4 -:109D500040E45EE0622D812F0E942048862D9FEF17 -:109D6000E91AF90AE7E1CE0ED11C22E0622E823018 -:109D700029F6FA81F330E9F48091A005833009F4E3 -:109D800028C1809175028823A1F011E08091A0057F -:109D9000833009F010E080913606909137060E94DA -:109DA00092BD00E09C014CE35EE0652D812F0E9496 -:109DB00020488091D205809336098A81843041F50C -:109DC0001092470910924B0910924A0910924909C2 -:109DD000109248098091A005843009F415C1809142 -:109DE00075028823A9F0FA809B81F91A11E080910D -:109DF000A005EA818E1310E0809136090E942ABEE8 -:109E000000E09C0140E35EE06F2D812F0E9420481E -:109E10008091D30580933609FA814F1229C081E0E1 -:109E20008093470910924B0910924A0910924909F0 -:109E3000109248098091A005841509F4FAC0809118 -:109E400075028823A9F0FA809B81F91A11E08091AC -:109E5000A005EA818E1310E0809136090E942ABE87 -:109E600000E09C0140E35EE06F2D812F0E942048BE -:109E700096E0F92E09E11EE0E12CDA80FB81DF1A81 -:109E8000E09236098A818F1120C0F8018591949162 -:109E90001092470990934B0980934A0910924909FF -:109EA00010924809C090A0059A81C91609F4D9C03A -:109EB00080917502882349F081E0CF1080E023E093 -:109EC00046E25EE06D2D0F941E15CF2CF3940E5FCD -:109ED0001F4FE1E0EE12C2C0809136069091370626 -:109EE000892B11F4772031F1FA81FF121EC01091F5 -:109EF000A0051F1709F4C6C0809175028823A9F038 -:109F0000BF92AF929F928F928A819B81891B8F9380 -:109F100081E0EA811E1380E08F930E947D250F90DF -:109F20000F900F900F900F900F9082E0F82EFC0C86 -:109F300077247394FA81FF5FFA838981F813BECE88 -:109F4000F0929E050EC080913F0910923F09882330 -:109F500009F4BCCE0E946C2E80919F05882309F4E1 -:109F6000B5CE0F900F900F90DF91CF911F910F9171 -:109F7000FF90EF90DF90CF90BF90AF909F908F9029 -:109F80007F906F905F904F903F902F9008958091B9 -:109F90003F0910923F09882309F4C9CE0F94BF15D9 -:109FA000F701EE0FFF1FE054FD4F208131812F504C -:109FB00031090EE716E250E040E066E379E080E424 -:109FC0009EE00F94CC1680919F05882309F4AFCEB4 -:109FD000C8CF80913F0910923F09882309F4D1CE60 -:109FE0000F94BF1502E216EC24E630E050E040E0AA -:109FF00066E376E08CE39EE00F94CC1680919F059B -:10A00000882309F4BECEADCF80913F0910923F095D -:10A01000882309F4E4CE0F94BF1566E07FE180E366 -:10A020009EE00F94A41780919F05882309F4D7CE52 -:10A0300098CF80913F0910923F09882309F4FFCE01 -:10A040000F94BF1566E07FE180E39EE00F94A417B4 -:10A0500080919F05882309F4F2CE83CFEE24E39408 -:10A060000FCF80913F0910923F09882309F420CF38 -:10A0700084E19FE20E947D2480919F05882309F45A -:10A0800017CF6FCF80913F0910923F09882309F4C1 -:10A0900033CF0E94662D80919F05882309F42CCF31 -:10A0A00060CFCF92DF92EF92FF920F931F93CF93E7 -:10A0B000DF9361E081E00E943223C091A10585E039 -:10A0C000D82EDC0ED3E0DC1B12E01C1B81E0F82E46 -:10A0D000FC1ACC2EC194C1112DC0E090A005EE2039 -:10A0E000A1F080917502882349F081E0E11080E0C1 -:10A0F00024E04CEF5BE06C2D0F941E15CF5FCD116B -:10A10000EACF84E080939E050CC080913F091092B5 -:10A110003F09882331F30E946C2E80919F0588238C -:10A1200001F3DF91CF911F910F91FF90EF90DF909E -:10A13000CF900895C13069F58091A0058130C1F0BC -:10A14000809175028823D1F2EE24E3948091A005DA -:10A15000813009F0E12C809183160E9408BE00E056 -:10A160009C014EEE5BE06F2D8E2D0E942048C6CFE5 -:10A1700080913F0910923F09882311F363E876E14B -:10A180008EEE9BE00F94E81780919F058823C1F223 -:10A19000C8CFC230E1F58091A0058230B1F0809146 -:10A1A0007502882309F4AACFEE24E3948091A005D8 -:10A1B000823009F0E12C809184160E9408BE00E0F4 -:10A1C0009C014EED5BE0612FCFCF80913F09109253 -:10A1D0003F09882321F364E876E18EED9BE00F943C -:10A1E000E81780919F058823D1F29BCF80913F098A -:10A1F00010923F09882391F065E876E18FEC9BE0AF -:10A200000F94E81780919F05882341F08ACFC330CF -:10A2100009F074CF8091A005833041F380917502DD -:10A22000882309F46BCFEE24E3948091A00583305A -:10A2300009F0E12C809185160E9408BE00E09C0187 -:10A240004FEC5BE06D2F90CF5F926F927F928F9279 -:10A250009F92AF92BF92CF92DF92EF92FF920F93B5 -:10A260001F93CF93DF9361E081E00E943223C0917E -:10A27000A1056C2E85E0782E7C0ED4E0DC1B93E0EB -:10A28000892E582C5C1A21EFE22E2BECF22E34E2B0 -:10A29000C32E3CE0D32E12E01C1B4CE0A42E4CEC51 -:10A2A000B42E81E0982E9C1AC11113C00091A00514 -:10A2B000002329F180917502882309F4DFC0662DFF -:10A2C000619581E0011180E024E04AE35CE00F94B5 -:10A2D0001E1580910B0680933609C13009F055C0D8 -:10A2E0009091A005913039F180917502811138C0AB -:10A2F000CF5F7C12D9CF85E080939E050CC0809102 -:10A300003F0910923F098823A9F20E946C2E809188 -:10A310009F05882379F2DF91CF911F910F91FF90D4 -:10A32000EF90DF90CF90BF90AF909F908F907F90F5 -:10A330006F905F90089590913F0910923F09992383 -:10A3400099F28C278093360980927502A114B1048A -:10A3500011F00E940CCC80919F05882329F2DBCF5D -:10A3600081E09091A005913009F080E0909136094C -:10A3700020E33CE0911102C02CE23CE001E043E329 -:10A380005CE0692D0E942048B3CFC23071F5809106 -:10A39000A0058230D1F080917502882309F4A8CFFE -:10A3A000FF92EF92DF92CF921F9381E09091A005F0 -:10A3B000923009F080E08F930E947D250F900F90DE -:10A3C0000F900F900F900F9093CF80913F091092B4 -:10A3D0003F09882301F3E114F10411F00E94F1CB4D -:10A3E00080919F058823B9F296CFC33091F50091F3 -:10A3F000A005033081F080917502882309F478CF9D -:10A4000081E0033009F080E023E046E15CE0652D67 -:10A410000F941E156DCF80913F0910923F0988233C -:10A4200051F389E199E30E947D2480919F0588235F -:10A4300011F371CF80913F0910923F09882381F079 -:10A4400081E590E50E947D2480919F05882341F05D -:10A4500062CFC43009F04CCF0091A005043051F315 -:10A4600080917502882309F443CF81E0043009F01C -:10A4700080E023E048E05CE06D2FCACF80910B06BE -:10A480008093360935CF2F923F924F925F926F9211 -:10A490007F928F929F92AF92BF92CF92DF92EF9274 -:10A4A000FF920F931F93CF93DF9300D000D01F92A2 -:10A4B000CDB7DEB7482E662E809393056093920544 -:10A4C00020914709298361E081E00E943223709046 -:10A4D000A10527E1362D3202C0011124AC01495BF0 -:10A4E000594F6A01572C55E0570D5A833324339442 -:10A4F000832D87198D8333EDA32E3CE2B32E40EFDD -:10A50000842E49E0942EE62CF12CEE0CFF1CF70172 -:10A51000E054FD4F7F01562D5203A0011124495BE9 -:10A52000594F5F834E8371107FC03320D9F08091E3 -:10A53000A0051816BCF040913B0950913C09609170 -:10A540003D0970913E094F5F5F4F6F4F7F4F4093C2 -:10A550003B0950933C0960933D0970933E098F5F1E -:10A560008093A00580917502882389F083E063EDD4 -:10A5700079E0481639F094E063EC79E0491611F07F -:10A5800063EB79E043E0852D81950F94931409E105 -:10A590001EE022E0222EFEEFF70DFB83272D25196A -:10A5A0002C83721018C0F801859194913B813093EF -:10A5B000470990934B0980934A09109249091092D8 -:10A5C00048098091A005871509F46BC08091750238 -:10A5D000811176C0312C822D0E5F1F4F93E0292E02 -:10A5E0008330F9F654E0751214C060924709109256 -:10A5F0004B0910924A09109249091092480980911A -:10A60000A005843009F471C08091750281118AC05F -:10A61000312C7394FA81F71186CF85E080939E05E3 -:10A6200029812093470919C0E1E07E12B0CF109133 -:10A63000A005113031F080917502811127C0312CB5 -:10A64000A6CF80913F0910923F098823A1F30E9471 -:10A650006C2E80919F05882371F327960FB6F8948E -:10A66000DEBF0FBECDBFDF91CF911F910F91FF9045 -:10A67000EF90DF90CF90BF90AF909F908F907F90A2 -:10A680006F905F904F903F902F90089581E0113030 -:10A6900009F080E024E04AEF59E06D810F941E1527 -:10A6A000CECF80913F0910923F09882309F48ECFC5 -:10A6B0000E94D32C80919F05882309F487CFCDCFAA -:10A6C000BF92AF929F928F924C814F9381E0909175 -:10A6D000A005921180E08F930E947D250F900F902E -:10A6E0000F900F900F900F9075CF80913F091092AF -:10A6F0003F09882309F488CF0F94BF15F701208103 -:10A7000031812F5031090FED1CE24AEA50E0B601C9 -:10A7100081EE99E00F94CC1680919F05882309F46F -:10A7200073CF9BCF11E08091A005843009F010E039 -:10A73000EE81FF81808191810E9492BD64E0651964 -:10A7400000E09C0141EE59E0812F0E94204860CF3B -:10A750006091470984E00C9443526091470983E07B -:10A760000C9443526091470982E00C9443522F921B -:10A770003F924F925F926F927F928F929F92AF9291 -:10A78000BF92CF92DF92EF92FF920F931F93CF93DE -:10A79000DF9300D000D0CDB7DEB70E9462CD482E47 -:10A7A00061E081E00E9432232091A1052D834420A5 -:10A7B00069F185E08E837D80272D2B5F298385E0DD -:10A7C00087198A8384E087198B8383E087198C83B8 -:10A7D00082E0682E671881E0582E5718272C2194A4 -:10A7E0002D8121113BC01091A005112391F0809182 -:10A7F0007502882309F451C081E0111180E024E042 -:10A8000049ED58E0622D0F941E1547C096E09E83D7 -:10A81000D2CF80913F0910923F09882341F30E94D3 -:10A820006C2E80919F05882311F326960FB6F8941D -:10A83000DEBF0FBECDBFDF91CF911F910F91FF9073 -:10A84000EF90DF90CF90BF90AF909F908F907F90D0 -:10A850006F905F904F903F902F9008958D81813041 -:10A8600009F096C01091A005113009F47CC08091C8 -:10A870007502882391F01F9288EC98E09F938F9344 -:10A880005F9281E0113009F080E08F930E947D2576 -:10A890000F900F900F900F900F904110B1C02D812D -:10A8A000253009F0ADC01091A005153009F402C1A2 -:10A8B0008091750281110FC116E081E0810F9D81A9 -:10A8C000891314C03090A005391609F42CC1809169 -:10A8D0007502882359F06D81671981E02D8132124C -:10A8E00080E023E04CE758E00F941E1582E0810FD2 -:10A8F0009D81891314C03090A005391609F424C134 -:10A9000080917502882359F06D81671981E02D814E -:10A91000321280E023E043E758E00F941E1583E0F5 -:10A92000810F9D81891315C09091A0052D819217EB -:10A9300009F41BC180917502882359F06D81671954 -:10A9400081E02D81921380E023E041E658E00F94EE -:10A950001E158D818F5F8D839981981341CF1C5F68 -:10A9600010939E0562CF80913F0910923F09882382 -:10A9700009F47DCF8CE598E09093F3088093F2087A -:10A980000E945E2D80919F05882309F470CF4DCFE2 -:10A990008D81823009F012C11091A005123071F042 -:10A9A00080917502882309F478CF81E0123009F094 -:10A9B00080E023E047EB58E0662D25CF80913F09EA -:10A9C00010923F09882361F383E69AE50E947D2473 -:10A9D00080919F05882321F328CF1091A005133083 -:10A9E000F1F080917502882309F457CF81E013308C -:10A9F00009F080E023E04AEA58E06C810F941E15CC -:10AA00008E819D81891309C01091A005181709F442 -:10AA10006DC08091750281117AC01E814ECF8091E8 -:10AA20003F0910923F098823E1F28CE09CE50E94E7 -:10AA30007D2480919F058823A1F2F7CE80913F0964 -:10AA400010923F09882309F4C6C020E030E04AE7AD -:10AA500054E46091FE057091FF058091000690918D -:10AA600001060F94173A20E030E040E85FE30F94CE -:10AA7000073E0F947B3F1F92912C812C8AE1A82ED8 -:10AA800088E4B82E6B011BE2E12EFF24F39400E072 -:10AA900010E021E030E040E050E06EEF75E08DE93D -:10AAA00098E00E94EB2C0F9080919F05882309F479 -:10AAB00092C0BBCE80913F0910923F09882309F4D0 -:10AAC000F7CE84E19FE50E947D2480919F05882335 -:10AAD00009F4EECEAACE81E0153009F080E023E043 -:10AAE00044E958E06A810F941E15E6CE80913F0933 -:10AAF00010923F09882309F48CCF8DE89EE20E94D2 -:10AB00007D2480919F05882309F483CF8ECE6D81AB -:10AB1000671981E02D81121380E023E048E858E0B6 -:10AB20000F941E157ACF80913F0910923F09882318 -:10AB300009F4CDCE84E693E60E947D2480919F05A2 -:10AB4000882309F4C4CE71CE80913F0910923F0949 -:10AB5000882309F4D5CE83E790E60E947D24809176 -:10AB60009F05882309F4CCCE60CE80913F091092D6 -:10AB70003F09882309F4DECE0E94532420E040E000 -:10AB800070E060E088EC96E226960FB6F894DEBF9F -:10AB90000FBECDBFDF91CF911F910F91FF90EF902E -:10ABA000DF90CF90BF90AF909F908F907F906F90ED -:10ABB0005F904F903F902F900C9493232D812330E2 -:10ABC00009F40BCF243009F068CE3090A00594E052 -:10ABD000391609F433CF80917502882309F45DCECC -:10ABE0006091FE057091FF0580910006909101062D -:10ABF0000E94E6219C0181E094E0391280E000E0AF -:10AC00004DE958E06B810E942048FACE2F923F9286 -:10AC10004F925F926F927F928F929F92AF92BF926C -:10AC2000CF92DF92EF92FF920F931F93CF93DF9318 -:10AC300000D0CDB7DEB761E081E00E9432232091E1 -:10AC4000A1052A832B5F298384E09A81891B8B834A -:10AC500066246394B2E05B2E83E0782E791A452C4B -:10AC6000491A362C391A292E21942A8121113DC0E6 -:10AC70001091A0051123B9F080917502882349F045 -:10AC800081E0111180E024E041E159E0622D0F9450 -:10AC90001E159A819F5F9A8329819213E6CF85E0E2 -:10ACA00080939E050CC080913F0910923F09882334 -:10ACB00019F30E946C2E80919F058823E9F20F9072 -:10ACC0000F900F90DF91CF911F910F91FF90EF9018 -:10ACD000DF90CF90BF90AF909F908F907F906F90BC -:10ACE0005F904F903F902F9008958A81813009F0B6 -:10ACF0006BC01092470910924B0910924A091092AA -:10AD00004909109248098091A0058130F1F08091A5 -:10AD10007502882309F4BDCF11E08091A005813030 -:10AD200009F010E060917A0670917B0680917C06B4 -:10AD300090917D060E94651F00E09C014FEE58E057 -:10AD4000632D812F0E942048A4CF80913F0910924B -:10AD50003F098823E1F20F94BF1520E030E048EC72 -:10AD600052E460917A0670917B0680917C06909106 -:10AD70007D060F94173A20E030EB4AE156E40F9439 -:10AD8000083E0F947B3F1F92E3EF8E2EE0E29E2E53 -:10AD9000F0EFAF2EF7E4BF2E6B0118E5E12E1DE4B6 -:10ADA000F12E00E010E024E539ED4FEF5FEF6AE7A8 -:10ADB00076E08FEE98E00E94EB2C0F9080919F053B -:10ADC000882309F4A4CF7BCF9A81923009F0DDC0AB -:10ADD0006092470910924B0910924A091092490952 -:10ADE000109248098091A0058230D9F080917502B7 -:10ADF000882309F44ECF11E08091A005823009F03C -:10AE000010E060917E0670917F068091800690919F -:10AE100081060E94651F00E09C014FEE58E0642D02 -:10AE200090CF80913F0910923F098823F9F20F9447 -:10AE3000BF1520E030E048EC52E460917E0670914E -:10AE40007F0680918006909181060F94173A20E04A -:10AE500030EB4AE156E40F94083E0F947B3F1F927B -:10AE600033EF832E30E2932E40EFA42E47E4B42E2E -:10AE70006B0118E5E12E1DE4F12E00E010E024E561 -:10AE800039ED4FEF5FEF6EE776E08FEE98E00E94CE -:10AE9000EB2C0F9080919F05882309F4A7CF0FCF4B -:10AEA0005092470910924B0910924A091092490991 -:10AEB000109248098091A0058330D9F080917502E5 -:10AEC000882309F4E6CE11E08091A005833009F0D3 -:10AED00010E06091820670918306809184069091C3 -:10AEE00085060E94651F00E09C014FEE58E0672D2B -:10AEF00028CF80913F0910923F098823F9F20F94DF -:10AF0000BF1520E030E048EC52E460918206709179 -:10AF1000830680918406909185060F94173A20E06D -:10AF200030E048E453E40F94083E0F947B3F1F92B7 -:10AF300083EF882E80E2982E90EFA92E97E4B92E09 -:10AF40006B0110EBE12E14E0F12E00E010E028E39D -:10AF50003FEF4FEF5FEF62E876E08FEE98E00E9400 -:10AF6000EB2C0F9080919F05882309F4A7CFA7CEE3 -:10AF700080913F0910923F09882391F00E94D92BBC -:10AF800080919F05882361F09ACE8A81833009F4ED -:10AF900087CF843009F07DCE8091A005843041F3C5 -:10AFA00080917502882309F474CE89ED9BE29F930A -:10AFB0008F938EE399E09F938F938B818F9381E0A2 -:10AFC0009091A005943009F080E08F930E947D2538 -:10AFD0000F900F900F900F900F900F905ACE5F929E -:10AFE0006F927F928F929F92AF92BF92CF92DF9299 -:10AFF000EF92FF920F931F93CF93DF9361E081E075 -:10B000000E943223C091A10525E0722E7C0ED1E072 -:10B01000DC1B6C2E6194C11134C01091A00511236A -:10B02000A1F080917502882349F081E0111180E040 -:10B0300024E041E159E0662D0F941E15CF5F7C128C -:10B04000EACF82E080939E050CC080913F09109268 -:10B050003F09882331F30E946C2E80919F0588233D -:10B0600001F3DF91CF911F910F91FF90EF90DF904F -:10B07000CF90BF90AF909F908F907F906F905F9098 -:10B080000895C130D9F65090A00581E0581609F412 -:10B0900047C080917502882389F211E0511210E0B7 -:10B0A000C0908606D0908706E0908806F0908906CA -:10B0B00020E030E0A901C701B6010F94B1392DEBB2 -:10B0C00037E346E055EB87FD04C02DEB37E346E060 -:10B0D00055E3C701B6010F94083E6B017C0120E0E7 -:10B0E00030E0A9010F94B13920E030E040E05FEB9F -:10B0F00087FD04C020E030E040E05FE3C701B60117 -:10B100000F94083E0F94743FCB010E9492BD00E063 -:10B110009C0147EE58E06D2F812F0E9420488ECF72 -:10B1200080913F0910923F09882309F4B2CF6091C2 -:10B1300086067091870680918806909189060F9403 -:10B140007B3F1F92912C812C8AEEA82E87E4B82E8B -:10B150006B011AE0E12EF12C00E010E020E030E07D -:10B16000A90166E876E087EE98E00E94EB2C0F904C -:10B1700080919F05882309F48CCF73CF2F923F9243 -:10B180004F925F926F927F928F929F92AF92BF92F7 -:10B19000CF92DF92EF92FF920F931F93CF93DF93A3 -:10B1A00000D000D01F921F92CDB7DEB72091470983 -:10B1B000288761E081E00E9432233091A1053F831E -:10B1C000E8858E2F90E0880F991F9C01275E314FF4 -:10B1D0003C832B8336E0E39FC0011124FC01EC503B -:10B1E000FA4FFA83E9839C012E503A4F79015F8030 -:10B1F00035E0432E450C11E0312E3518252C2194D5 -:10B20000FE82ED82570134E0A30EB11C49EDC42E3D -:10B210004BE2D42E85E0782E75184701E2E08E0EC1 -:10B22000911C82E0682E6518FF81F11161C0112325 -:10B23000D9F08091A0051816BCF040913B095091BF -:10B240003C0960913D0970913E094F5F5F4F6F4F20 -:10B250007F4F40933B0950933C0960933D097093A5 -:10B260003E098F5F8093A00580917502882341F08D -:10B27000EB81FC816591749143E0822D0F949314CE -:10B28000F501808180933609FF81F23009F080C09A -:10B2900028852093470910924B0910924A09109271 -:10B2A0004909109248098091A005823009F45DC0D7 -:10B2B00080917502882391F011E08091A005823081 -:10B2C00009F010E0809136090E942ABE00E09C013E -:10B2D00047E059E0662D812F0E94204810E02F8121 -:10B2E0002F5F2F834212A0CF86E080939E0519C066 -:10B2F0002F81213029F61091A005113031F0809175 -:10B300007502811127C010E0BBCF80913F091092D8 -:10B310003F098823A1F30E946C2E80919F0588230A -:10B3200071F328960FB6F894DEBF0FBECDBFDF9144 -:10B33000CF911F910F91FF90EF90DF90CF90BF9032 -:10B34000AF909F908F907F906F905F904F903F90C5 -:10B350002F90089581E0113009F080E024E041E170 -:10B3600059E0632D0F941E15CECF80913F091092A6 -:10B370003F09882309F49CCF65EE70E287E099E0ED -:10B380000F94A41780919F05882309F491CFC9CF0A -:10B390003F81333091F58091A0058330C1F08091D9 -:10B3A0007502882309F49ACF11E08091A0058330BB -:10B3B00009F010E0ED81FE81808191810E9492BDB3 -:10B3C00063E0651900E09C0140E059E084CF809182 -:10B3D0003F0910923F09882311F310E000E025EFA8 -:10B3E00030E045E050E0B70180E099E00F94CC16E2 -:10B3F00080919F05882399F294CFFF81F43091F5D5 -:10B400008091A0058430B9F080917502882309F4F9 -:10B4100065CF11E08091A005843009F010E0F401BF -:10B42000808191810E9492BD64E0651900E09C01D9 -:10B430004CEF58E050CF80913F0910923F0988238C -:10B4400019F310E000E024E630E045E050E06981C7 -:10B450007A818CEF98E00F94CC1680919F05882319 -:10B4600099F25FCFFF81F53009F039CF8091A005C7 -:10B470008530E1F080917502882309F42FCFDF92A7 -:10B48000CF928EE399E09F938F937F9281E090918A -:10B49000A005953009F080E08F930E947D250F90E4 -:10B4A0000F900F900F900F900F9018CF80913F0941 -:10B4B00010923F098823F1F20E94D92B80919F05B9 -:10B4C0008823C1F22ECF5F926F927F928F929F92CC -:10B4D000AF92BF92CF92DF92EF92FF920F931F93A2 -:10B4E000CF93DF93CDB7DEB760970FB6F894DEBF8A -:10B4F0000FBECDBF80E1ECE8F2E0DE0111960190D5 -:10B500000D928A95E1F761E081E00E943223D090AC -:10B51000A1059D2C65E0862E8D0C7D2C719473E029 -:10B52000672ED11012C01091A005112309F4CEC0CE -:10B5300080917502882349F081E0111180E024E0B8 -:10B540004CE358E0672D0F941E15AA24A394B12C48 -:10B550005D2C5918DA102FC08FEF8A0D80934709A0 -:10B5600010924B0910924A09109249091092480909 -:10B570008091A0058D1509F4CDC0809175028823B6 -:10B58000D1F011E08091A0058D1110E0F501EE0FD2 -:10B59000FF1FEE0FFF1FEB5AF64F60A171A182A1B2 -:10B5A00093A10E94F52700E09C014CEE57E0652D29 -:10B5B000812F0E942048CA2C81E08A0D9FEFA91A92 -:10B5C000B90A94E0A916B10429F68D112CC0609235 -:10B5D000470910924B0910924A091092490910929A -:10B5E00048098091A0058D1509F4BEC080917502AF -:10B5F0008823C9F0BD2CB91811E08091A0058D11E8 -:10B6000010E0609185097091860980918709909179 -:10B6100088090E94F52700E09C014CEE57E06B2D55 -:10B62000812F0E94204882E08C0D8D1122C08091D4 -:10B63000A0058D1509F4B6C0809175028823C9F064 -:10B64000BD2CB91811E08091A0058D1110E060911A -:10B6500095097091960980919709909198090E9497 -:10B66000F52700E09C014FED57E06B2D812F0E94E4 -:10B67000204883E08C0D8D1121C08091A0058D158F -:10B6800009F4ADC0809175028823C1F011E080916A -:10B69000A0058D1110E06091990970919A0980912F -:10B6A0009B0990919C090E94F52700E09C014EECBB -:10B6B00057E06D2D6919812F0E942048D3948D1079 -:10B6C00030CF84E08C0D80939E050EC080913F09A1 -:10B6D00010923F09882309F42BCF0E946C2E809191 -:10B6E0009F05882309F424CF60960FB6F894DEBF37 -:10B6F0000FBECDBFDF91CF911F910F91FF90EF90C3 -:10B70000DF90CF90BF90AF909F908F907F906F9081 -:10B710005F90089580913F0910923F09882309F4B2 -:10B720002CCF0F94BF15B501660F771F660F771FDB -:10B73000FB01349781E090E08C0F9D1FE80FF91F0B -:10B74000E080F180028113816B58764F20E030E079 -:10B7500040E85FE38CEE97E00F94CB1580919F0556 -:10B76000882309F40ACFC0CF80913F0910923F0986 -:10B77000882309F43BCF0F94BF15E12C1CE3F12E75 -:10B780000CE116E420E030E040E85FE365E879E0B2 -:10B790008CEE97E00F94CB1580919F05882309F4D8 -:10B7A00025CFA2CF80913F0910923F09882309F449 -:10B7B00043CF0F94BF15E12C1CE3F12E0CE116E4EE -:10B7C00020E030E0A90165E979E08FED97E00F9482 -:10B7D000CB1580919F05882309F42ECF85CF8091CA -:10B7E0003F0910923F09882309F44CCF0F94BF15ED -:10B7F000E12C1CE3F12E0CE116E420E030E0A9017D -:10B8000069E979E08EEC97E00F94CB1580919F0564 -:10B81000882309F437CF68CF2F923F924F925F92DF -:10B820006F927F928F929F92AF92BF92CF92DF9250 -:10B83000EF92FF920F931F93CF93DF93CDB7DEB7B5 -:10B840002C970FB6F894DEBF0FBECDBFC09059093C -:10B85000D0905A09E0905B09F0905C0980915D09F5 -:10B8600090915E09A0915F09B09160098C159D05CA -:10B87000AE05BF0510F4D701C601C0905509D090A0 -:10B880005609E0905709F0905809BC01CD016C159C -:10B890007D058E059F0510F4C701B6010F94B639DA -:10B8A0002B013C0161E081E00E9432232091A1053F -:10B8B0002C872E83822F8B5F8D8387E0821B8F8363 -:10B8C00086E0821B888785E0821B898784E0821B53 -:10B8D0008A8783E0821B8B8742E0242E221A322E35 -:10B8E00031942C85211140C01091A0051123B9F08D -:10B8F00080917502882349F081E0111180E024E0F5 -:10B900004CE358E0632D0F941E159C859F5F9C8728 -:10B910002D812913E6CF88E080939E050CC080918D -:10B920003F0910923F09882319F30E946C2E8091E1 -:10B930009F058823E9F22C960FB6F894DEBF0FBE60 -:10B94000CDBFDF91CF911F910F91FF90EF90DF90CE -:10B95000CF90BF90AF909F908F907F906F905F90AF -:10B960004F903F902F9008958C85813009F081C0D1 -:10B970008091A0058130F9F080917502882329F229 -:10B9800011E08091A005813009F010E060918909F3 -:10B9900070918A0980918B0990918C090E94F527FA -:10B9A00061E02E81621B00E09C014BE258E0812F98 -:10B9B0000E942048AACF80913F0910923F09882316 -:10B9C000D9F20F94BF152AE037ED43E25DE3C301DE -:10B9D000B2010F94173A4B015C0120E030E040E0E7 -:10B9E0005FE40F94B13987FD05C0812C912CA12C07 -:10B9F0003FE4B32E2AE037ED43E25DE3609189092D -:10BA000070918A0980918B0990918C090F94173A53 -:10BA100020E030E040E85FE30F94073E0F947B3F67 -:10BA200069837A838B839C83C501B4010F94743F2F -:10BA30007B018C0121E0E21AF108010911091F9232 -:10BA4000912C812C22E0A22E28E4B22EC980DA802B -:10BA500021E030E040E050E069E879E08BE298E0F6 -:10BA60000E94EB2C0F9080919F05882309F484CFCE -:10BA700062CF8C85823009F0A6C18091A00582300A -:10BA8000D9F080917502882309F43FCF11E08091AD -:10BA9000A005823009F010E060918D0970918E0947 -:10BAA00080918F09909190090E94F52700E09C01F8 -:10BAB0004DE158E0622D7BCF80913F0910923F0904 -:10BAC0008823F9F20F94BF156091610970916209A2 -:10BAD00080916309909164090F94B6397B018C01C0 -:10BAE00020E030E048EC52E46DE879E08DE198E048 -:10BAF0000F94CB1580919F05882319F21CCF80915C -:10BB0000A0058330D9F080917502882309F4FDCE19 -:10BB100011E08091A005833009F010E06091910957 -:10BB20007091920980919309909194090E94F52750 -:10BB300000E09C0140E158E06B8539CF80913F09DE -:10BB400010923F098823F9F20F94BF152AE037EDD0 -:10BB500043E25DE3C301B2010F94173A4B015C016C -:10BB600020E030E040E05FE40F94B13987FD05C08C -:10BB7000812C912CA12C9FE4B92E2AE037ED43E2D1 -:10BB80005DE3609191097091920980919309909180 -:10BB900094090F94173A20E030E040E85FE30F94F7 -:10BBA000073E0F947B3F69837A838B839C83C50117 -:10BBB000B4010F94743F7B018C0121E0E21AF1087B -:10BBC000010911091F92912C812C82E0A82E88E492 -:10BBD000B82EC980DA8021E030E040E050E061E931 -:10BBE00079E080E198E00E94EB2C0F9080919F0516 -:10BBF000882309F488CF9FCE1092470910924B09F1 -:10BC000010924A0910924909109248098091A005A2 -:10BC10008430E9F080917502882309F476CE11E032 -:10BC20008091A005843009F010E060915509709171 -:10BC3000560980915709909158090F94B6390E947E -:10BC4000D22700E09C0144E058E06A85B0CE8091A4 -:10BC50003F0910923F098823E9F20F94BF150CE7C2 -:10BC600018E224E630E040E050E065E579E084E069 -:10BC700098E00F94541680919F05882359F25BCE6B -:10BC800081E08093470910924B0910924A09109263 -:10BC90004909109248098091A0058530E9F080910A -:10BCA0007502882309F431CE11E08091A00585301A -:10BCB00009F010E06091590970915A0980915B096F -:10BCC00090915C090F94B6390E94D22700E09C0144 -:10BCD00044E058E069856BCE80913F0910923F099E -:10BCE0008823E9F20F94BF150AE718E224E630E052 -:10BCF00040E050E069E579E084E098E00F94541664 -:10BD000080919F05882359F216CE82E080934709DF -:10BD100010924B0910924A09109249091092480951 -:10BD20008091A0058630E9F080917502882309F49E -:10BD3000ECCD11E08091A005863009F010E0609113 -:10BD40005D0970915E0980915F09909160090F947F -:10BD5000B6390E94D22700E09C0144E058E0688593 -:10BD600026CE80913F0910923F098823E9F20F9473 -:10BD7000BF1508E718E22AE030E040E050E06DE54A -:10BD800079E084E098E00F94541680919F05882311 -:10BD900059F2D1CD80913F0910923F09882339F1A2 -:10BDA0000F94BF1506E718E224E630E040E050E0CB -:10BDB00061E679E088EF97E00F94541680919F0533 -:10BDC0008823A9F0B8CD8C85833009F498CE8430CF -:10BDD00009F412CF853009F453CF863009F495CF9A -:10BDE000873009F092CD8091A005873099F280913B -:10BDF0007502882309F489CD11E08091A005873070 -:10BE000009F010E060916109709162098091630905 -:10BE1000909164090F94B6390E94D22700E09C01EA -:10BE200048EF57E06F81C3CD2F923F924F925F92C0 -:10BE30006F927F928F929F92AF92BF92CF92DF923A -:10BE4000EF92FF920F931F93CF93DF9300D01F9237 -:10BE50001F92CDB7DEB761E081E00E94322380916E -:10BE6000A1058C838A83982F9B5F9983E82FE195A6 -:10BE7000EB8384E0482EFC814F1A8C81811114C021 -:10BE80009091A0059D83992309F489C08091750242 -:10BE9000882351F081E0ED81E11180E024E04CE362 -:10BEA00058E06B810F941E1565E5662E69E0762ECD -:10BEB000F1E0FD833C803A942C808A81281A9C8191 -:10BEC000ED819E1328C03092470910924B091092C1 -:10BED0004A0910924909109248098091A0058917D2 -:10BEE00009F483C0809175028823A9F011E0809144 -:10BEF000A005FD818F1310E0F3016489758986899F -:10BF000097890E94052100E09C0141E358E0622DE1 -:10BF1000812F0E9420485D80F4E06F0E711C81E04B -:10BF2000850D8D83843059F69C81943069F5E3E06A -:10BF3000E093470910924B0910924A09109249095F -:10BF4000109248098091A005843009F48CC080913A -:10BF500075028823C9F0F1E0FD838091A00584304B -:10BF600009F01D82609175097091760980917709B9 -:10BF7000909178090E94052100E09C0141E358E07E -:10BF8000642D8D810E9420488C818F5F8C839981E4 -:10BF9000981373CF5394539450929E050EC0809182 -:10BFA0003F0910923F09882309F470CF0E946C2E3C -:10BFB00080919F05882309F469CF0F900F900F900F -:10BFC0000F900F90DF91CF911F910F91FF90EF9005 -:10BFD000DF90CF90BF90AF909F908F907F906F90A9 -:10BFE0005F904F903F902F90089580913F0910925D -:10BFF0003F09882309F476CF0F94BF1520E030E085 -:10C0000040E251E4F30164897589868997890F9428 -:10C01000173A20E030E048E452E40F94073E0F94D2 -:10C020007B3F1F9234E7832E38E2932E46EFA42EF7 -:10C0300047E4B42E6B0114E6E12E16E8F12E01E080 -:10C0400010E022E330E040E050E0B3016C5E7F4F4F -:10C0500081E398E00E94EB2C0F9080919F0588234C -:10C0600009F440CFAACF80913F0910923F0988235D -:10C0700009F46DCF0F94BF1520E030E040E251E4A9 -:10C08000609175097091760980917709909178098E -:10C090000F94173A20E030E048E452E40F94073E52 -:10C0A0000F947B3F1F9282E7882E88E2982E96EFAE -:10C0B000A92E97E4B92E6B0114E6E12E16E8F12EB5 -:10C0C00001E010E022E330E040E050E065E779E095 -:10C0D00081E398E00E94EB2C0F9080919F058823CC -:10C0E00009F435CF6ACF2F923F924F925F926F92B1 -:10C0F0007F928F929F92AF92BF92CF92DF92EF92F8 -:10C10000FF920F931F93CF93DF9300D000D0CDB752 -:10C11000DEB761E081E00E9432232091A1052D83EA -:10C120002E83322F3B5F398381E0922F821B8A83DB -:10C1300091959B8382E0821B8C83FD81F11185C1E7 -:10C140001091A005112309F459C18091750288232B -:10C1500049F081E0111180E024E04CE358E06B816C -:10C160000F941E158091F105882309F437C2FD81D3 -:10C17000F23029F58091A005823009F4A2C18091A6 -:10C1800075028823E1F011E08091A005823009F06A -:10C1900010E0E091510924E0E29FF0011124E75101 -:10C1A000FA4F60817181828193810E94E62100E0D3 -:10C1B0009C0144E957E06C81812F0E942048712C3A -:10C1C000612C13E0312E2D803E81231A8D81831145 -:10C1D0002EC06092470910924B0910924A091092A2 -:10C1E0004909109248098091A0059D81891709F499 -:10C1F000B1C1809175028823D1F011E08091A00532 -:10C20000831110E0F301EE0FFF1FEE0FFF1FE75148 -:10C21000FA4F60817181828193810E94E62100E062 -:10C220009C0148E857E0622D812F0E942048FFEFD3 -:10C230006F1A7F0A24E032128AC115E03D81131380 -:10C2400029C08091A005811709F4CAC180917502A7 -:10C25000882301F16D809E81691A772473948091FF -:10C26000A005ED818E13712CE091510928E0E29F29 -:10C27000F0011124E752FA4F60817181828193812C -:10C280000E94362800E09C014EE757E0662D872D7E -:10C290000E94204844244394410E712C612C3D801F -:10C2A0003E81331A8D8184112FC06092470910920C -:10C2B0004B0910924A09109249091092480980913D -:10C2C000A0059D81891709F4AAC180917502882370 -:10C2D000D9F011E08091A005841110E0F30133E062 -:10C2E000EE0FFF1F3A95E1F7E752FA4F6081718137 -:10C2F000828193810E94362800E09C0145E757E047 -:10C30000632D812F0E942048542C44244394450CD3 -:10C310006A94672809F07FC1FD814F1228C080917F -:10C32000A0058F1709F496C1809175028823F9F052 -:10C330007D803E81731A11E08091A0059D81891353 -:10C3400010E0E091510928E0E29FF0011124E7524A -:10C35000FA4F64817581868197810E94362800E0BA -:10C360009C014DE657E0672D812F0E942048539491 -:10C370005394712C612C4D803E81431A8D8185111F -:10C380002FC06092470910924B0910924A091092EF -:10C390004909109248098091A0059D81891709F4E7 -:10C3A00078C1809175028823D9F011E08091A005B1 -:10C3B000851110E0F30183E0EE0FFF1F8A95E1F78E -:10C3C000E752FA4F64817581868197810E943628F1 -:10C3D00000E09C0146E657E0642D812F0E94204832 -:10C3E00053946A94672809F050C1FD81FF5FFD8373 -:10C3F00029812F13A2CE50929E050EC080913F0935 -:10C4000010923F09882309F4A0CE0E946C2E8091DF -:10C410009F05882309F499CE26960FB6F894DEBFBF -:10C420000FBECDBFDF91CF911F910F91FF90EF9085 -:10C43000DF90CF90BF90AF909F908F907F906F9044 -:10C440005F904F903F902F9008952D81213009F0FB -:10C4500089CE8091A0058130D1F08091750288232A -:10C4600009F480CE81E09091A005913009F080E040 -:10C470009091F10522EC37E0911102C02EEB37E0EC -:10C4800001E04EE957E06A810E9420486BCE80911E -:10C49000F10590913F0910923F099923F1F23D81F6 -:10C4A00083278093F10583E080937502E7EEF1E73F -:10C4B000EF2B11F00E94E77180919F05882369F2AC -:10C4C000ABCF80913F0910923F09882309F457CEE2 -:10C4D0000F94BF156090510924E0629E3001112431 -:10C4E000C30187519A4F3C0120E030E04AE754E411 -:10C4F000FC0160817181828193810F94173A20E061 -:10C5000030E84BEB54E40F94073E0F947B3F1F92AF -:10C5100007EE802E01E7902E8AE1A82E88E4B82E3F -:10C520006B0116EDE12E16E0F12E00E010E02CED8F -:10C5300035E040E050E0B30184E997E00E94EB2C45 -:10C540000F9080919F05882309F419CE65CFB4E040 -:10C550003B2E3CCE80913F0910923F09882309F47D -:10C5600048CE0F94BF15C301880F991F880F991FDC -:10C57000FC01E751FA4F2F0120E030E04AE754E494 -:10C5800060817181828193810F94173A20E030E8B5 -:10C590004BEB54E40F94073E0F947B3F1F92E7EE62 -:10C5A0008E2EE1E79E2EFAE1AF2EF8E4BF2E6B014E -:10C5B00016EDE12E16E0F12E00E010E02CED35E056 -:10C5C00040E050E0B20188E897E00E94EB2C0F9029 -:10C5D00080919F05882309F40CCE1ECF12E02ECE49 -:10C5E00080913F0910923F09882309F42FCE0F94C0 -:10C5F000BF156091510988E0689FB001112467520E -:10C600007A4F8EE797E00F946A1780919F058823F1 -:10C6100009F41CCE01CF66246394712C43CE809123 -:10C620003F0910923F09882309F44FCE0F94BF159C -:10C63000B30143E0660F771F4A95E1F767527A4FDF -:10C6400085E797E00F946A1780919F05882309F486 -:10C650003CCEE2CE80913F0910923F09882309F435 -:10C6600063CE0F94BF156091510928E0629FB0011D -:10C67000112463527A4F8DE697E00F946A178091E8 -:10C680009F05882309F450CEC7CE66246394712C8D -:10C6900075CE80913F0910923F09882309F481CE1D -:10C6A0000F94BF15B30193E0660F771F9A95E1F7DA -:10C6B00063527A4F86E697E00F946A1780919F0540 -:10C6C000882309F46ECEA8CE2F923F924F925F92AC -:10C6D0006F927F928F929F92AF92BF92CF92DF9292 -:10C6E000EF92FF920F931F93CF93DF9300D0CDB7BC -:10C6F000DEB761E081E00E9432232091A1052A8308 -:10C700002B5F298384E09A81891B8B8323E0522E3F -:10C71000352C391A82E0782E791A81E0682E691A50 -:10C72000292E21942A8121113DC01091A0051123A9 -:10C73000B9F080917502882349F081E0111180E001 -:10C7400024E04CE358E0622D0F941E152A812F5FE0 -:10C750002A8389812813E6CF85E080939E050CC04B -:10C7600080913F0910923F09882319F30E946C2E93 -:10C7700080919F058823E9F20F900F900F90DF9131 -:10C78000CF911F910F91FF90EF90DF90CF90BF90CE -:10C79000AF909F908F907F906F905F904F903F9061 -:10C7A0002F9008958A81813071F59091A005913084 -:10C7B000B9F080917502882349F281E0913009F047 -:10C7C00080E090916D0622EC37E0911102C02EEBD3 -:10C7D00037E001E045EC57E0662D0E942048B6CFD7 -:10C7E00080913F0910923F09882319F380916D06CB -:10C7F0002A81822780936D065092750280919F0551 -:10C800008823B9F2B9CF8A81823009F098C080912B -:10C81000A0058230C1F080917502882309F496CF7B -:10C8200011E08091A005823009F010E0809118029B -:10C83000909119020E9492BD00E09C0147EB57E0E5 -:10C84000672D812FCACF80913F0910923F0988231D -:10C8500011F310E000E025EF30E050E040E068E147 -:10C8600072E087EB97E00F94CC1680919F058823A8 -:10C8700091F282CF8091A0058330B9F0809175024A -:10C88000882309F463CF11E08091A005833009F07B -:10C8900010E080911602909117020E9492BD00E074 -:10C8A0009C0140EB57E0632DCCCF80913F09109263 -:10C8B0003F09882319F310E000E025EF30E050E055 -:10C8C00040E066E172E080EB97E00F94CC16809137 -:10C8D0009F05882399F250CF80913F0910923F091C -:10C8E0008823C9F120E030E048EC52E46091120264 -:10C8F0007091130280911402909115020F94173ACF -:10C900000F947B3F1F92912C812C80EFA82E87E4FF -:10C91000B82E6B0118EEE12E13E0F12E00E010E0CE -:10C9200020E030E0A90162E172E088EA97E00E942D -:10C93000EB2C0F9080919F05882369F01DCF9A8181 -:10C94000933009F497CF943009F000CF4090A005C0 -:10C9500094E0491609F280917502882309F4F6CE15 -:10C96000609112027091130280911402909115024D -:10C970000E94651F9C0181E094E0491280E000E084 -:10C9800048EA57E06B8129CFE5E4F6E183AF64AF75 -:10C990006FEF7FEFCA010C947FC72F923F924F92A7 -:10C9A0005F926F927F928F929F92AF92BF92CF923F -:10C9B000DF92EF92FF920F931F93CF93DF9300D0FC -:10C9C00000D01F921F92CDB7DEB710924509E091BB -:10C9D0001712F0911812309721F0199581110F94C8 -:10C9E0008E1080913F0910923F09882319F120E0B1 -:10C9F00040E070E060E08EE89BE30E9493230E9499 -:10CA0000DE3F28960FB6F894DEBF0FBECDBFDF9194 -:10CA1000CF911F910F91FF90EF90DF90CF90BF903B -:10CA2000AF909F908F907F906F905F904F903F90CE -:10CA30002F90089580919705882309F434C260915E -:10CA4000470670914806072E000C880B990B0F942F -:10CA5000B83911E0209143063091440640914506D3 -:10CA6000509146060F94684018160CF010E0609143 -:10CA70005E0670915F06072E000C880B990B0F94D1 -:10CA8000B8399B01AC0160915A0670915B068091A8 -:10CA90005C0690915D060F94B13987FD12600E948B -:10CAA0003BC88111146010932E0520916D0F3091B9 -:10CAB0006E0F40916F0F5091700F609176027091E0 -:10CAC000770280917802909179020F94083E4B0191 -:10CAD0005C012091710F3091720F4091730F509152 -:10CAE000740F60917A0270917B0280917C02909128 -:10CAF0007D020F94083E6D837E838F8398872091FB -:10CB0000750F3091760F4091770F5091780F6091AB -:10CB10007E0270917F0280918002909181020F9439 -:10CB2000083E2B013C0120E030E040E251E40F944C -:10CB3000173A20E030E048EC52E40F94173A6B01CA -:10CB40007C0120E030E0A901C301B2010F94B139AA -:10CB500020E030E040EA50EC87FD04C020E030E007 -:10CB600040EA50E4C701B6010F94083E20E030E0EF -:10CB700040E251E40F94023F0F94743F2B013C01BB -:10CB800080E277FE09C07094609450944094411CF8 -:10CB9000511C611C711C8DE28093A20560E220E1B2 -:10CBA000421627E25206610471048CF0C301B201FF -:10CBB00020E137E240E050E00F94C63DCA01B901E0 -:10CBC0002AE030E040E050E00F94C63D605D6093A5 -:10CBD000A30560E238EE431633E0530661047104A6 -:10CBE0008CF0C301B20128EE33E040E050E00F9436 -:10CBF000C63DCA01B9012AE030E040E050E00F94A0 -:10CC0000C63D605D6093A405C301B20124E630E037 -:10CC100040E050E00F94C63D6AE0C62ED12CE12CD6 -:10CC2000F12CCA01B901A70196010F94C63D605DC0 -:10CC30006093A505C301B201A70196010F94C63DFB -:10CC4000162FCA01B901A70196010F94C63D112301 -:10CC500009F4F6C08EE28093A605605D6093A70597 -:10CC6000105D1093A80562EA75E086E295E00F94E6 -:10CC7000ED4120E030E0A901C501B4010F94B139C4 -:10CC800020E030E040E05FEB87FD04C020E030E0D2 -:10CC900040E05FE3C501B4010F94083E0F94743F78 -:10CCA000CB010E9413BDBC0181E295E00F94ED41E0 -:10CCB00020E030E0A9016D817E818F8198850F94FD -:10CCC000B13920E030E040E05FEB87FD04C020E0B8 -:10CCD00030E040E05FE36D817E818F8198850F9425 -:10CCE000083E0F94743FCB010E9413BDBC018CE140 -:10CCF00095E00F94ED418091A21714E683FD29C0C1 -:10CD00000E9473CD882309F4ADC080919A17909149 -:10CD10009B17A0919C17B0919D170097A105B10595 -:10CD200009F4A0C0BC01CD016D597F4F8F4F9F4FBB -:10CD300024E630E040E050E00F94A43D60919E175F -:10CD400070919F178091A0179091A1170F94A43D07 -:10CD5000122F0E94E4BA4B015C01062F80910F0252 -:10CD60008117A1F010930F0288E4189FB0011124DD -:10CD700090E080E00F94B6392AE037ED43E25CE3BF -:10CD80000F94173A0F947B3F60931B0580910E021E -:10CD9000081709F488C080920E02C501B40120E191 -:10CDA0003EE040E050E00F94A43DC22E732EE22EF0 -:10CDB000F32E5CE3252E312C412C512CC501B401FE -:10CDC000A20191010F94A43D062F672ECA01B9015B -:10CDD000A20191010F94A43D162FD72E90E8891639 -:10CDE00091E5990691E0A906B104F0F1C501B401FD -:10CDF00020E831E541E050E00F94A43D5901DF9275 -:10CE00001F93C70168E170E00F9434419F938F93A3 -:10CE10003F932F938FE796E09F938F938BE095E05E -:10CE20009F938F930F9448390FB6F894DEBF0FBECF -:10CE3000CDBF89E0BAE0AB16B10470F588E02CC034 -:10CE4000662351F08EE28093A605605D6093A7058E -:10CE500080E28093A80507CF80E28093A7058093A6 -:10CE6000A605F6CF10E075CFE114F10409F087C2F2 -:10CE70006F920F93DF921F9383E796E09F938F93B8 -:10CE80008BE095E09F938F930F9448390FB6F894F9 -:10CE9000DEBF0FBECDBF85E0982F990F990F891B7C -:10CEA000855A80930A050E94F224D82E81E00E94C0 -:10CEB000AA3F80912E05982F947042E102E082FFF4 -:10CEC00002C048E00CE080917D16843180F48091AE -:10CED0007F16841760F0992309F471C28BE197E003 -:10CEE0007C0123E060E589E496E10F94852680913A -:10CEF0007D168431B8F480917F16823098F0DD2061 -:10CF000009F460C28091D205882309F45BC28FEDD9 -:10CF100096E07C0102E123E042E068E689E496E1E4 -:10CF20000F94852680917D168C3108F0EAC02FE39E -:10CF3000222E26E0322E1FE0B12CA12C39E0432E08 -:10CF4000512C612C712C4CE1C42E3A2DD101149638 -:10CF50008D919D910D90BC91A02D8D839E83AF836B -:10CF6000B887F1018084918480917D16843118F511 -:10CF700080917F168830F8F062E2A11001C068E06D -:10CF8000F501E855FD4F208180912E0590E002C00B -:10CF9000959587953A95E2F7F501EE0FFF1F80FF13 -:10CFA00014C2EB55F94FE590F4900CE048E089E4A9 -:10CFB00096E10F94852680917D168830B0F4D110CB -:10CFC0000BC025E02A9DF0012B9DF00D1124E25E9F -:10CFD000F94F8481811109C097FEFAC14DE956E0ED -:10CFE00067E087EF810F0E94C46480917D168C31C9 -:10CFF000C8F480917F168431A8F020E030E040E052 -:10D000005FE36D817E818F8198850F94083E0F9438 -:10D01000743F77FF08C24DE956E06CE187EF810F5E -:10D020000E94C4643FEFA31AB30A87E1280E311CA3 -:10D03000165E133409F089CF809032069090330643 -:10D04000A0903406B090350680917D16883090F41B -:10D05000D11004C080912C0681110CC0809136063D -:10D060009091370697FF09C24DE956E067E081E5E8 -:10D070000E94C46480917D168C31B0F480917F163B -:10D08000843190F020E030E040E05FE3C501B4017E -:10D090000F94083E0F94743F77FF1DC24DE956E090 -:10D0A0006CE181E50E94C46480917D168C3148F565 -:10D0B00080917F16843128F18091D205882309F16F -:10D0C000E4E68E9FC001112481589F4F6FEF70E0FE -:10D0D0000F944841CB010E9492BD27E62093801611 -:10D0E0002CE1209381160E94AD4285E290E0A0E001 -:10D0F000B0E089839A83AB83BC83CE0101960E9402 -:10D1000067400E9473CD882379F180917D16843326 -:10D1100058F580917F168A3238F107E028E04AE21C -:10D120006AE289E496E10F94C72305E022E04CE22D -:10D1300062E389E496E10F94C72324E04AE061E3C7 -:10D140008AE20F948D2360914B1670914C1682E306 -:10D15000809365168BE28093661625E636E142E3FE -:10D1600089E496E10F94452280917D16853350F431 -:10D1700080917F16813330F024E04AE461E386E356 -:10D180000F948D2380917D16843368F480917F16EF -:10D19000823348F002E020911B0542E367E389E413 -:10D1A00096E10F94C72380917D16803378F48091A7 -:10D1B0007F16883258F080910A058093801680E3AC -:10D1C000809381168BE095E00E94AD4280917D16A0 -:10D1D000883208F06FC080917F168D3108F46AC0E4 -:10D1E0002BE040E86DE180E00F948D2380917D1667 -:10D1F000873208F05FC080917F168F3108F45AC0E3 -:10D2000088E590E0A0E0B0E089839A83AB83BC839B -:10D2100083E08093801616E210938116CE0101966A -:10D220000E9467408BE08093801610938116DD206A -:10D2300009F480C181E295E00E94AD4289E590E069 -:10D24000A0E0B0E089839A83AB83BC8388E28093BB -:10D25000801616E210938116CE0101960E94674057 -:10D2600080E38093801610938116DD2009F48AC133 -:10D270008CE195E00E94AD428AE590E0A0E0B0E04C -:10D2800089839A83AB83BC838DE48093801616E2F6 -:10D2900010938116CE0101960E94674085E5809328 -:10D2A000801610938116DD2009F494C186E295E082 -:10D2B0000E94AD4280917D168333A8F580917F1640 -:10D2C0008B3288F183E00E94AA3F86E090E0A0E0E4 -:10D2D000B0E089839A83AB83BC8383E0809380161C -:10D2E00013E310938116CE0101960E94674081E0FE -:10D2F0000E94AA3F80912002909121020E9492BD3B -:10D300002CE020938016109381160E94AD4285E296 -:10D3100090E0A0E0B0E089839A83AB83BC83CE0128 -:10D3200001960E94674080917D16813408F069CB98 -:10D3300080917F16863308F464CB109280168EE3BA -:10D340008093811689E192E10E94A724182F60E85A -:10D3500070E089E192E10E94DDC780E2C82ED12C05 -:10D36000E12CF12C153108F04CCBC982DA82EB822A -:10D37000FC82CE0101960E9467401F5FF3CFF4E666 -:10D38000EF16F10438F4DF921F937F92CF9287E675 -:10D3900096E074CDDF921F937F92CF928DE596E059 -:10D3A0009F938F938BE095E09F938F930F944839D1 -:10D3B0000FB6F894DEBF0FBECDBF86E06DCD85E120 -:10D3C00097E08ECD89EA96E0A4CDEF55F94FEBCDED -:10D3D000C4010E9492BDFC01808193E0803229F457 -:10D3E000818192E0803209F491E0892F880F880FC3 -:10D3F000392F381B832F810F8093801687E080930D -:10D400008116A3E0B0E0A91BB109CD018E0F9F1FCB -:10D410000E94AD4249825A826B827C82CE01019683 -:10D420000E946740E2CDCB010E9492BDFC01808149 -:10D4300093E0803229F4818192E0803209F491E016 -:10D44000892F880F880FB92FB81B8B2F810F8093DE -:10D450008016C092811623E030E0291B3109C901F2 -:10D460008E0F9F1F0E94AD4249825A826B827C823E -:10D47000CE0101960E946740D5CD0E9492BDFC016D -:10D48000808193E0803229F4818192E0803209F436 -:10D4900091E0892F880F880FA92FA81B8A2F865A01 -:10D4A0008093801687E08093811623E030E0291B6B -:10D4B0003109CF01820F931F0E94AD4289E090E0B5 -:10D4C000A0E0B0E089839A83AB83BC83CE01019650 -:10D4D0000E946740CFCDCB010E9492BDFC018081AC -:10D4E00093E0803229F4818192E0803209F491E066 -:10D4F000892F880F880FB92FB81B8B2F865A8093DE -:10D5000080168CE18093811623E030E0291B3109DD -:10D51000CF01820F931F0E94AD4289E090E0A0E00E -:10D52000B0E089839A83AB83BC83CE0101960E94CD -:10D530006740BACD0F94171180FF19C001E215E0C2 -:10D54000D8018D918D01882309F478CE8F320CF0AB -:10D550008FE3082E000C990BAA0BBB0B89839A83CF -:10D56000AB83BC83CE0101960E946740E9CF8091D6 -:10D57000E40880FD5FCE6FEF7FEF88E996E00E94C0 -:10D580007FC75CCE0F94171181FF19C00CE115E025 -:10D59000F80181918F01882309F46ECE8F320CF04F -:10D5A0008FE3082E000C990BAA0BBB0B89839A837F -:10D5B000AB83BC83CE0101960E946740E9CF809186 -:10D5C000E40881FD55CE6FEF7FEF88E996E00E9479 -:10D5D0007FC752CE0F94171182FF19C006E215E0E3 -:10D5E000D8018D918D01882309F464CE8F320CF01F -:10D5F0008FE3082E000C990BAA0BBB0B89839A832F -:10D60000AB83BC83CE0101960E946740E9CF809135 -:10D61000E40882FD4BCE6FEF7FEF80E996E00E9439 -:10D620007FC748CECF93DF93FC0125AD211104C005 -:10D6300021E025AF0F944922C0914B16D0914C1692 -:10D64000E0917A16F0917B1682E01995E0917A16B6 -:10D65000F0917B1681E0199530E020E044E1BE01B5 -:10D6600089E496E10F9445222CE736E147E1BE01BB -:10D6700089E496E10F944522E0917A16F0917B16A9 -:10D6800080E0DF91CF9119944F925F926F927F92D9 -:10D690008F929F92AF92BF92CF92DF92EF92FF92C2 -:10D6A0001F93CF93DF93CDB7DEB760970FB6F89493 -:10D6B000DEBF0FBECDBF0F941E1D6B017C0180919C -:10D6C00010028F3F09F44DC00F941E1D809030054D -:10D6D00090903105A0903205B09033056819790912 -:10D6E0008A099B0997FD3DC08091091690910A1601 -:10D6F0008F5F8F708917A9F18091100240E050E090 -:10D7000065E073E4843050F424E0829FF00111243A -:10D71000E655FD4F40815181628173814D875E875F -:10D720006F87788B19821A821B821C821D821E824F -:10D730001F82188619861A861B861C8640912F0523 -:10D74000833011F0409151099E012F5F3F4FBE0180 -:10D75000635F7F4F86E792E00E94ACA68FEF8093D5 -:10D7600010020E94603E8091FF0382FF33C08091CF -:10D770003B05811131C091E090933B0580914F09A9 -:10D78000892780933F0910924F0983E080937502A7 -:10D790001092FF030F941E1D6C507E4F8F4F9F4FB2 -:10D7A00060933E0570933F0580934005909341053B -:10D7B00068E873E182E090E00E948D2B16E0115042 -:10D7C00059F00E94312B62E070E080E090E00F940D -:10D7D000911CF5CF10923B058091FB039091FC03C7 -:10D7E000A091FD03B091FE03A7019601281B390B00 -:10D7F0004A0B5B0BDA01C901B7FF05C080919405A4 -:10D80000882309F4BDC1D701C6018C599F4FAF4F82 -:10D81000BF4F8093FB039093FC03A093FD03B09351 -:10D82000FE0360913C05062E000C770B77FF03C0CA -:10D8300071956195710990913C0580913A05981315 -:10D8400065C0633008F062C010923C0580913C05D1 -:10D8500080933A05653008F06BC080913F098111D3 -:10D86000E9C080914316909144168D5C944641F432 -:10D8700080911102882309F4EFC081508093110236 -:10D880000E943C958090CE059090CF05A090D00549 -:10D89000B090D10581110E944995D501C4013AE0AB -:10D8A000B695A795979587953A95D1F7009741E05A -:10D8B000A407B10520F08FEF9FEFA0E0B0E09695B0 -:10D8C0008795209175022111D9C0309194053111AD -:10D8D00086C180914316909144168D5C944609F45C -:10D8E00065C180914009811161C180913605909197 -:10D8F0003705A0913805B0913905C81AD90AEA0A46 -:10D90000FB0AF7FC61C10E945E2D5EC18DEF860FA0 -:10D91000823008F09BCF80913C0591E087FD9FEF1E -:10D92000892F880F880F890F80933C0565E08ECF83 -:10D930008091450921E030E040E050E0882309F47F -:10D9400056C08090410990904209A0904309B09040 -:10D95000440981149104A104B104E9F170E090E05C -:10D9600080E00F94B63920E030E040EA50E40F94B4 -:10D97000023F2B013C01C701B601681979098A09E8 -:10D980009B090F94B6399B01AC01C301B2010F94FE -:10D99000023F20E030E04AE754E40F94173A4B018D -:10D9A0005C0120E030E040EA52E40F94684024E655 -:10D9B00030E040E050E087FF12C020E030E040EF70 -:10D9C00051E4C501B4010F9468402AE030E040E022 -:10D9D00050E087FF04C021E030E040E050E0C0921A -:10D9E0004109D0924209E0924309F0924409A09182 -:10D9F0003C050A2E000CBB0B0F94F03D25E030E0F7 -:10DA000040E050E00F94C63D80913B0990913C0965 -:10DA1000A0913D09B0913E09820F931FA41FB51F2D -:10DA200080933B0990933C09A0933D09B0933E0934 -:10DA300010923C05D701C6018856954CAF4FBF4F99 -:10DA40008093360590933705A0933805B093390538 -:10DA500081E08093750205CF8CE080931102809164 -:10DA6000340590913505009729F00197909335057D -:10DA70008093340581E08093750202CF009741F0D6 -:10DA800040913405509135054817590708F021CFCA -:10DA900080919405811112C0223038F0243008F4AE -:10DAA00041C0243011F41092750285E496E10E9481 -:10DAB000126B81E0809397058093940583E00E9428 -:10DAC000AA3F81E080936916E0914316F0914416D5 -:10DAD00019951092970580919405811127C0109295 -:10DAE0003F0980914316909144168D5C944609F04D -:10DAF000F8CE0F941E1DDC01CB018C199D09AE09D7 -:10DB0000BF098090340590903505B12CA12C881662 -:10DB10009906AA06BB0608F0DCCE909335058093E3 -:10DB20003405D7CE81E080937502BFCF89E496E1BA -:10DB30000F94E72491E0811101C090E09093940547 -:10DB4000882369F280914316909144168D5C944627 -:10DB5000B9F40F941E1DDC01CB018C199D09AE098F -:10DB6000BF09C0903405D0903505F12CE12CC816C2 -:10DB7000D906EA06FB0620F4909335058093340518 -:10DB800060960FB6F894DEBF0FBECDBFDF91CF9188 -:10DB90001F91FF90EF90DF90CF90BF90AF909F903C -:10DBA0008F907F906F905F904F90089548E9C40EDA -:10DBB0004AE3D41EE11CF11CC0923605D092370511 -:10DBC000E0923805F0923905809194058111D8CF03 -:10DBD000809175028130A1F610927502D1CF009725 -:10DBE00009F46CCF4DCF3F924F925F926F927F922C -:10DBF0008F929F92AF92BF92CF92DF92EF92FF925D -:10DC00000F931F93CF93DF93CDB7DEB7EB970FB68C -:10DC1000F894DEBF0FBECDBF8FEF80931B028091C3 -:10DC20009705882369F18091A21700E010E084FF36 -:10DC300023C089E894E10E945F808BE1E9E8F4E188 -:10DC4000DE01919601900D928A95E1F710E000E0D7 -:10DC5000BE016F5F7F4FCE0181960F946C0E181638 -:10DC60003CF4CE0101960E94F579080F111DF0CF0A -:10DC7000CE0181960E9464800093950510939605CD -:10DC800061E081E00E9432231091A105412E85E0E0 -:10DC9000582E510E312E319491E1A92E9FE1B92ECB -:10DCA00024E1822E2DE0922E81E0682E611A11115E -:10DCB00011C00091A005002329F1809175028823ED -:10DCC00049F081E0011180E024E049E15DE0632D4D -:10DCD0000F941E158091A21786FD59C084FF57C06E -:10DCE000113009F052C00091A005013079F1809106 -:10DCF0007502811138C082E01F5F5112D8CF809326 -:10DD00009E050CC080913F0910923F098823A9F21B -:10DD10000E946C2E80919F05882379F2EB960FB6B6 -:10DD2000F894DEBF0FBECDBFDF91CF911F910F9151 -:10DD3000FF90EF90DF90CF90BF90AF909F908F902B -:10DD40007F906F905F904F903F90089580913F0932 -:10DD500010923F09882359F20E94111F80919F055C -:10DD6000882329F2DBCFBF92AF929F928F926F925E -:10DD700081E0013009F080E08F930E947D250F90B3 -:10DD80000F900F900F900F900F9082E001C081E0F4 -:10DD900090917502992309F4AFCF082FD12CC12C93 -:10DDA000712E7418802FE0909505F0909605CE1492 -:10DDB000DF0408F0A1CF0113A9C081E0E81AF1083F -:10DDC000EC18FD0889E894E10E945F808BE1E9E8A6 -:10DDD000F4E1DE01919601900D928A95E1F7F12C24 -:10DDE000BE016F5F7F4FCE0181960F946C0E1816A7 -:10DDF0007CF4CE0101960E94F579882389F3EF1017 -:10DE00006BC0BE016F5F7F4F89E79FE00E94127A6F -:10DE1000CE0181960E9464808091A217F090A005A7 -:10DE200085FF79C0F11263C080913F0910923F09CC -:10DE3000882309F45CC019821C8280918C1464EAE6 -:10DE400074E1882311F069E874E121E049E75FE0BB -:10DE5000CE0101960E946A80882309F43FC08BE1BD -:10DE6000FE013196A9E8B4E101900D928A95E1F79F -:10DE70008091A2178F7B8093A217A0919717AA3049 -:10DE800080F481E08A0F809397178BE18A9FD001FD -:10DE90001124A757B94EE9E8F4E101900D928A9553 -:10DEA000E1F7CE0101960E9464801092A10582E004 -:10DEB00090E0A0E0B0E080933B0990933C09A093F0 -:10DEC0003D09B0933E0981E080939F05109294052F -:10DED00083E08093750222CFF39482CF0E940FD803 -:10DEE00069E77FE08EEF9CE00F94E226DACF809125 -:10DEF0007502882359F0EE24E394F112E12C6E2D83 -:10DF0000872D0E94733F41E0811116C08FEFC81A20 -:10DF1000D80A0F5F47CFF116A1F0809175028823D0 -:10DF2000A9F3EE24E394F112E12C6E2D872D0E94CB -:10DF3000733F882359F340E0672D8E2D0F944014D2 -:10DF4000E5CF80913F0910923F09882331F381EE9C -:10DF500096E20E947D2480919F058823F1F2DECE17 -:10DF6000DC01680F791F90E080E02D91E92FFF27F9 -:10DF7000E227EE0FFF1FE656FB4D25913491982FB7 -:10DF80008827822793276A177B0779F708950F93CD -:10DF90001F93CF93DF93CDB7DEB760970FB6F8949A -:10DFA000DEBF0FBECDBF8C01DC01ED91FC91028084 -:10DFB000F381E02DBE016F5F7F4F1995882309F42F -:10DFC00064C08981807CC9F56F81637070E0762FB1 -:10DFD0006627770F770F8885B4E08B9FC0011124E7 -:10DFE000682B792B89858295869586958370682B19 -:10DFF0006F5F7F4F90E080E02A852370220F3B8582 -:10E0000037FB332730F9232B3E813F70230F332713 -:10E01000331F2750310904C0660F771F881F991FCF -:10E020002A95D2F760960FB6F894DEBF0FBECDBF2B -:10E03000DF91CF911F910F910895803419F5688574 -:10E040006695669570E090E080E0CB0177276627C3 -:10E050002A85622B098510E0102F0027012E000C65 -:10E06000220B330B602B712B822B932B6F5F7F4F17 -:10E070008F4F9F4F4AE0660F771F881F991F4A9561 -:10E08000D1F7D0CF8BE0F801848360E070E0CB0162 -:10E09000C9CF0895FC0182810895CF93DF93E09169 -:10E0A000390687E1E89FF0011124E15CF94FC08552 -:10E0B000D18581E0CE31D105C4F020E030E040E0F0 -:10E0C0005FE364817581868197810F94083E0F9488 -:10E0D000743F6C1B7D0B77FF03C0719561957109CF -:10E0E00081E0633071050CF080E0DF91CF910895FD -:10E0F000FC0190E1AFEAB7E001900D929A95E1F74B -:10E100000895BC012091A0073091A1074091A0077C -:10E110005091A1072417350731F481E026173707FE -:10E1200009F080E008959A01F1CFEF92FF920F93EA -:10E130001F93E0920306F0920406009305061093E5 -:10E1400006066093070670930806809309069FEF02 -:10E15000FF27621B730B840B30F4809570956195DB -:10E16000790B890B992790930E08A6E06A9F00927D -:10E170000208512DEE277A9F500DE11D8A9FE00D78 -:10E1800050930308E0930408AFE06A9F00920608EA -:10E19000512DEE277A9F500DE11D8A9FE00D50937F -:10E1A0000708E0930808AAE06A9F00920A08512D28 -:10E1B000EE277A9F500DE11D8A9FE00D50930B08CA -:10E1C000E0930C081F910F91FF90EF90089580E06D -:10E1D00008959F92AF92BF92CF92DF92EF92FF92FB -:10E1E0000F931F93CF93DF9300D01F921F92CDB751 -:10E1F000DEB7EBEBF6E10027BB27462F572FA82F02 -:10E20000AA2341F4A52F542FB85FAA2319F4A52FF0 -:10E210005527B85FA03138F45295A295452F4F701D -:10E22000507FA42BBC5FA03428F4550FAA1F550FB4 -:10E23000AA1FBE5FA03818F4550FAA1FB395550F3B -:10E24000AA1FEA0FF01F449151E0AA27B85081F1AC -:10E25000C8F0B0FF02C0440F551FB1FF04C0440F07 -:10E26000551F440F551FB2FF06C052954295142FFB -:10E270001F70407F512BB3FF1BC0A52F542F442785 -:10E280000C945871B195B0FF02C055954795B1FFF8 -:10E2900004C05595479555954795B2FF05C05295D1 -:10E2A000407F4295452B5F70B3FF02C0452F552735 -:10E2B000DD24CC24BB24B2E0649FD018C108B00A8E -:10E2C000B00B749FC018B108B00B849FB018B1098F -:10E2D000659FC018B108B00B759FB018B109859F34 -:10E2E000B0196A9FB018B1097A9FB0194D9DA12C41 -:10E2F00099243327992722275D9DA00C911C301F5C -:10E30000901F201FAD9D900C311D901F201F4C9D14 -:10E31000A00C911C301F901F201F5C9D900C311D84 -:10E32000901F201FAC9D300D911D201F4B9D900C08 -:10E33000311D901F201F5B9D300D911D201FAB9D37 -:10E34000900D211D4B9F300D911D201F5B9F900D47 -:10E35000211DAB9F200DB1E0BB24CC24DD24639FA5 -:10E36000D018C108B00AB00B739FC018B108B00B29 -:10E37000839FB018B109699FC018B108B00B799F8D -:10E38000B018B109899FB019629FB018B109729F86 -:10E39000B019D61AC70AB80A20F0B1E03B0F901F97 -:10E3A000201F1124792F632F90E0822F0F900F9060 -:10E3B0000F900F900F90DF91CF911F910F91FF90D1 -:10E3C000EF90DF90CF90BF90AF909F9008957F9295 -:10E3D0008F929F92AF92BF92CF92DF92EF92FF9275 -:10E3E0000F931F93CF93DF937090F105C6EBD5E0A9 -:10E3F00092E2C92E92E0D92E26E2E22E22E0F22EFF -:10E4000009EE15E0772009F45EC0F8018080918064 -:10E41000A280B38020E030E0A901C501B4010F94CF -:10E42000B139882309F44FC020E030E040E05FE3D9 -:10E43000C501B4010F94173A9B01AC010F94173A30 -:10E440002BED3FE049E450E40F94173A9B01AC01F7 -:10E4500060E070E080E89FE30F94023F4B015C01B5 -:10E4600089929992A992B992F601619171916F0185 -:10E47000072E000C880B990B0F94B8392AE037ED62 -:10E4800043E25CE30F94173AA50194010F94173A05 -:10E49000F70161937193819391937F010C5F1F4FFB -:10E4A000F5E0CE3BDF0709F0ADCFDF91CF911F91B3 -:10E4B0000F91FF90EF90DF90CF90BF90AF909F9023 -:10E4C0008F907F900895812C912C80E8A82E8FE367 -:10E4D000B82EC6CFFC01908193FB882780F993FF6B -:10E4E0000E94E770811102C081E0089580E00895E4 -:10E4F000CF92DF92EF92FF920F931F93CF93DF9310 -:10E50000E82FF0E0EF01CC0FDD1FCC0FDD1F461729 -:10E5100039F0823009F049C0C12CD12C760117C0E6 -:10E520008230D1F3A09151098A2F90E0DC01AA0F2B -:10E53000BB1FA80FB91FAE0FBF1FAA0FBB1FAA0F8B -:10E54000BB1FA259B94FCD90DD90ED90FC908F018B -:10E55000000F111F000F111FF801E059FB4E25910C -:10E56000359145915491C95CDD4FC701B6010F94B7 -:10E57000083E6A837B838C839D83F801EC59FB4EB4 -:10E580002591359145915491C701B6010F94083EEC -:10E590006E877F87888B998BDF91CF911F910F9129 -:10E5A000FF90EF90DF90CF90089550E0DA01AA0F2E -:10E5B000BB1FA40FB51FAE0FBF1FAA0FBB1FAA0F13 -:10E5C000BB1FA259B94F862F90E0BC01660F771F81 -:10E5D000680F791FE60FF71FEE0FFF1FEE0FFF1FEB -:10E5E000E259F94F20813181428153816D917D91B2 -:10E5F0008D919C910F94073E6B017C01C95CDD4FAE -:10E60000AC019B016A817B818C819D810F94083EC6 -:10E610006A837B838C839D83A70196016E857F85AA -:10E6200088899989B3CFCF93DF93EC018D810E94C4 -:10E63000CFDD60E08B81DF91CF910D945D18AF92BB -:10E64000BF92DF92EF92FF920F931F93CF93DF93CE -:10E6500000D000D0CDB7DEB77C01D62E122F032F0D -:10E66000B42EA52E0E9413730F942A1D1E821D82A4 -:10E670008D2D80648983AA82BB820C831D838E01C9 -:10E680000F5F1F4FCE010696D801E0E02D91F0E01C -:10E69000EE0FFF1FE227E656FC4DE491A817B907DD -:10E6A000A9F7EE0FE160EE83580186E0A80EB11CD9 -:10E6B000F80181918F010E94C3DD0A151B05C1F786 -:10E6C000FCE0DF1202C00E94C8DD10E00E94C8DD3D -:10E6D000F701868387FF04C01F3F11F01F5FF6CF4D -:10E6E00026960FB6F894DEBF0FBECDBFDF91CF9157 -:10E6F0001F910F91FF90EF90DF90BF90AF90089522 -:10E7000061E0FC0183810F945D188FEF0C94C3DDF1 -:10E710000F931F93CF938C010E9413730F942A1DA4 -:10E72000C82F882371F08DEF0E94C3DD0F942A1D3E -:10E73000C82FC8010E9480738C2FCF911F910F9119 -:10E74000089582E1F8018483F4CF8F929F92AF9273 -:10E75000BF92CF92DF92EF92FF920F931F93CF93CE -:10E76000DF93EC016A017B01590120E030E0A9014F -:10E7700067E30E941F73A501980167E1CE010E9423 -:10E780001F73811127C08F81833039F089E0CC0C51 -:10E79000DD1CEE1CFF1C8A95D1F7A701960169E1EB -:10E7A000CE010E941F7311E0882319F010E087E06A -:10E7B0008C83CE010E948073812FDF91CF911F91B6 -:10E7C0000F91FF90EF90DF90CF90BF90AF909F9010 -:10E7D0008F90089589E08C8310E0EBCFEF92FF9249 -:10E7E0000F931F93CF93DF93EC01E62E8A0160E035 -:10E7F00072E0CA010E94B06FF82E892FEEBCF801BA -:10E8000098013E5F0DB407FEFDCF90819EBD0DB413 -:10E8100007FEFDCF91819EBD3296E217F30791F777 -:10E820000DB407FEFDCF0E94C3DD8F2D0E94C3DD16 -:10E830000E94C8DD8E838F71853069F083E18C83FF -:10E84000CE010E94807380E0DF91CF911F910F91E4 -:10E85000FF90EF90089581E0F7CF0F931F93CF9330 -:10E86000DF93EC018B010E9413730F942A1D811119 -:10E870000CC085E18C8310E0CE010E948073812F53 -:10E88000DF91CF911F910F910895A8016CEFCE01F8 -:10E890000E94EE73182F882361F3EECF0F931F931E -:10E8A000CF93DF93EC0189018F81833039F089E0C8 -:10E8B000440F551F661F771F8A95D1F79A01AB0148 -:10E8C00068E1CE010E941F7381112AC0A8016EEF7A -:10E8D000CE010E94EE73182F8823B1F00F942A1DE9 -:10E8E000182F8823D1F020E030E0A9016DE0CE019F -:10E8F0000E941F73882321F086E18C8310E004C0FE -:10E900000E94C8DD8111F8CFCE010E948073812F53 -:10E91000DF91CF911F910F91089587E18C83F4CF00 -:10E9200086E0EBCF1F93CF93DF93EC010E9413732C -:10E9300020E030E0A9016CE0CE010E941F7311E0DD -:10E94000882319F010E083E08C83CE010E9480734D -:10E95000812FDF91CF911F9108951F93CF93DF9364 -:10E96000EC018F81833039F089E0440F551F661F19 -:10E97000771F8A95D1F79A01AB0162E1CE010E941F -:10E980001F7311E0882319F010E085E08C83CE011D -:10E990000E948073812FDF91CF911F9108958F92F4 -:10E9A0009F92AF92BF92CF92DF92FF920F931F93ED -:10E9B000CF93DF93EC018B016A010F941E1D4B0175 -:10E9C0005C012CE2820E21E0921EA11CB11C0E946F -:10E9D000C8DD8E838F3F61F40F941E1D681979097D -:10E9E0008A099B0997FDF3CF81E18C8310E028C051 -:10E9F0008E3F09F040C0C60101972FEF2EBDF801F0 -:10EA00004FEF0DB407FEFDCF2EB521934EBD9F01F4 -:10EA1000201B310B28173907A0F30DB407FEFDCFDB -:10EA20002EB5800F911FFC0120830E94C8DDF82EB7 -:10EA30000E94C8DDB82E80915502811111C011E0ED -:10EA4000CE010E948073812FDF91CF911F910F9192 -:10EA5000FF90DF90CF90BF90AF909F908F900895E0 -:10EA6000B601C8010E94B06F3F2D2B2D821793076E -:10EA700031F38BE1BACF8FE0B8CF0F931F93CF93D1 -:10EA8000DF93EC018B010E94137340E052E0B80168 -:10EA9000CE01DF91CF911F910F910C94CF74AF9263 -:10EAA000BF92CF92DF92EF92FF920F931F93CF937B -:10EAB000DF93EC016A017B0159018F81833039F0CA -:10EAC00089E0CC0CDD1CEE1CFF1C8A95D1F713E00D -:10EAD00004E0A701960161E1CE010E941F73882323 -:10EAE00079F00C83CE010E9480731150E1F020E098 -:10EAF00030E0A9016CE0CE010E941F731C82E9CFB7 -:10EB000040E052E0B501CE010E94CF74882351F35A -:10EB1000DF91CF911F910F91FF90EF90DF90CF90F9 -:10EB2000BF90AF90089580E0F3CF8F929F92AF9205 -:10EB3000BF92CF92DF92EF92FF920F931F93CF93EA -:10EB4000DF93EC01162F1F821C824B830F941E1D36 -:10EB50006B017C0120EDC20E27E0D21EE11CF11CEE -:10EB6000A89561E08B810F945D1861E08B810F9413 -:10EB70002C1B209A289A219A2398229A81E00E949D -:10EB8000CFDD85E08D830E94CFDD0AE08FEF0E940C -:10EB9000C3DD0150D9F7A89520E030E0A90160E07D -:10EBA000CE010E941F738E83813081F00F941E1D51 -:10EBB0006C197D098E099F0997FDEECF81E08C834A -:10EBC000CE010E9480731A8280E078C021E030E09C -:10EBD00040E050E06BE3CE010E941F7391E0813072 -:10EBE00009F090E090935502A8952AEA31E040E0C0 -:10EBF00050E068E0CE010E941F73853041F581E04E -:10EC00008F83A8958F81812C912C5401823029F417 -:10EC1000812C912CA12C80E4B82E20E030E0A901B9 -:10EC200067E3CE010E941F73A501940169E2CE0142 -:10EC30000E941F738E838823F1F00F941E1D6C19A0 -:10EC40007D098E099F0997FDE8CF8AE0B8CF04E0DF -:10EC50000E94C8DD8E830150D9F78A3A11F482E010 -:10EC6000CFCF0F941E1D6C197D098E099F0997FD4A -:10EC7000BCCF82E0A4CF8F818230C1F420E030E0AD -:10EC8000A9016AE3CE010E941F73882311F088E076 -:10EC900096CF0E94C8DD807C803C11F483E08F8396 -:10ECA0000E94C8DD0E94C8DD0E94C8DDCE010E941E -:10ECB000807381E08A83173070F41D83DF91CF91D8 -:10ECC0001F910F91FF90EF90DF90CF90BF90AF908A -:10ECD0009F908F90089588E18C8376CF0F931F9338 -:10ECE000CF93DF93EC018B0120E030E0A90169E0D4 -:10ECF0000E941F7381110AC040E150E0B801CE01AB -:10ED0000DF91CF911F910F910C94CF7480E18C8390 -:10ED1000CE010E94807380E0DF91CF911F910F910F -:10ED200008950F930091020621E0022725E537E0C0 -:10ED30004CE050E0BC0183E597E00E9461CE0F916A -:10ED400008950F930091020621E0022725E537E0A0 -:10ED500041E050E0BC0183E597E00E9461CE0F9155 -:10ED600008950F930091020621E0022725E537E080 -:10ED700041E050E0BC0183E597E00E9461CE0F9135 -:10ED800008950F930091020621E0022725E537E060 -:10ED900048E050E0BC0183E597E00E9461CE0F910E -:10EDA00008950F930091020621E0022725E537E040 -:10EDB0004CE050E0BC0183E597E00E9461CE0F91EA -:10EDC00008950F930091020621E0022725E537E020 -:10EDD00044E050E0BC0183E597E00E9461CE0F91D2 -:10EDE00008950F9301E025E537E041E050E0BC01D4 -:10EDF00083E597E00E9461CE0F9108950F93AB01D8 -:10EE00000091020621E0022725E537E0BC0183E5F9 -:10EE100097E00E9461CE0F91089525E537E04CE020 -:10EE200050E0BC0183E597E00C9494DA25E537E0E7 -:10EE300041E050E0BC0183E597E00C9494DA25E5CD -:10EE400037E041E050E0BC0183E597E00C9494DAB0 -:10EE500025E537E04CE050E0BC0183E597E00C94F9 -:10EE600094DA25E537E044E050E0BC0183E597E023 -:10EE70000C9494DACF93C82FCB010E94ACCE85E3DB -:10EE800094E10E94ACCE86E294E1CC2311F08BE2B7 -:10EE900094E1CF910C9409DB2F923F924F925F92B5 -:10EEA0006F927F928F929F92AF92BF92CF92DF929A -:10EEB000EF92FF920F931F93CF93DF93CDB7DEB7FF -:10EEC0006C970FB6F894DEBF0FBECDBF8C015B010F -:10EED0005A834983FC01E95BFF4F208031804280E7 -:10EEE00053802D823E824F825886C201B1010F9419 -:10EEF000B6396B017C01D5012D913D914D915C910D -:10EF00000F94173A0F94E63E2B013C01E981FA81F8 -:10EF10002081318142815381C701B6010F94173A94 -:10EF20000F94E63E4B015C01C301B2010F947B3F9D -:10EF30006D877E878F87988B68377105810591056E -:10EF400048F438E7232E312C412C512C2D863E8657 -:10EF50004F86588AC501B4010F947B3F698B7A8B29 -:10EF60008B8B9C8B683771058105910548F428E7E8 -:10EF7000222E312C412C512C298A3A8A4B8A5C8AC8 -:10EF8000F801ED5AFF4F80809180A280B380D801B4 -:10EF900095962D903D904D905C90989729863A8655 -:10EFA0004B865C86C501B4010F94B8396D8B7E8B9E -:10EFB0008F8B988F89288A288B2809F49CC1A701F8 -:10EFC0009601C701B6010F94173A69837A838B8340 -:10EFD0009C836D857E858F8598890F94B6399B01BA -:10EFE000AC010F94173A698F7A8F8B8F9C8F2D8984 -:10EFF0003E894F89588D60E070E080E09FE30F9478 -:10F00000023F4B015C01298D3A8D4B8D5C8D6981EE -:10F010007A818B819C810F94073EA50194010F9406 -:10F02000173A6B017C010F94E63E0F947B3F1B0166 -:10F030002C0169897A898B899C890F94B6399B0147 -:10F04000AC010F94173A9B01AC0169817A818B81E5 -:10F050009C810F94073EA50194010F94173A4B0130 -:10F060005C010F94AA3F0F947B3F69837A838B8363 -:10F070009C83DC01CB01820D931DA41DB51D298548 -:10F080003A854B855C85281B390B4A0B5B0BDA01F3 -:10F09000C901B7FF61C069857A858B859C850F940E -:10F0A000B639A70196010F94083EA50194010F946B -:10F0B000073E20E030E040E05FE30F94173A0F9402 -:10F0C000E63E6B017C0120E030E0A9010F9468402E -:10F0D00018161CF0C12CD12C7601C701B6010F9473 -:10F0E0007B3F1B012C0149855A856B857C85421528 -:10F0F00053056405750510F41A012B0169857A859D -:10F100008B859C85621973098409950969837A83C3 -:10F110008B839C83C201B1010F94B6396B017C01D2 -:10F120002D893E894F89588DCA01B9010F94083E37 -:10F130009B01AC01C701B6010F94173A298D3A8D96 -:10F140004B8D5C8D0F94083E0F94B6400F947B3F1F -:10F150006D837E838F8398876D817E818F81988573 -:10F160002D853E854F855889621B730B840B950B4B -:10F170000F94B6392D893E894F89588D0F94023FDF -:10F1800020E034E244EF59E40F94173A0F947B3FA8 -:10F190006B017C016D817E818F81988529893A89F7 -:10F1A0004B895C89621B730B840B950B0F94B639EA -:10F1B0002D893E894F89588D0F94023F20E034E21B -:10F1C00044EF59E40F94173A0F947B3F4B015C01D5 -:10F1D0003FE6C316D104E104F10408F094C0F6013F -:10F1E000EE0FFF1FEE0FFF1FE150FB4E8591959133 -:10F1F000A591B4913C01AD8BB9874FE6841691047B -:10F20000A104B10408F087C0F401EE0FFF1FEE0F58 -:10F21000FF1FE150FB4E4591559165917491342F3C -:10F22000252FCB01D8019A962D923D924D925C925A -:10F230009D9795964D915D916D917C9198972980C0 -:10F240003A804B805C8042195309640975099E9687 -:10F250004D935D936D937C93D197F801E55BFF4FE0 -:10F260002D843E844F84588820823182428253828A -:10F27000D696CD92DD92ED92FC92D997F80182AEAE -:10F2800093AEA4AEB5AEFE96608271822D882282C6 -:10F2900039843382349630832183828393832D8013 -:10F2A0003E804F805884D2962D923D924D925C9232 -:10F2B000D5973D9629883A884B885C882082318290 -:10F2C000428253826C960FB6F894DEBF0FBECDBF5C -:10F2D000DF91CF911F910F91FF90EF90DF90CF9032 -:10F2E000BF90AF909F908F907F906F905F904F9066 -:10F2F0003F902F90089519821A821B821C82212C24 -:10F30000312C210129CFC701B6010E94E9703B01D0 -:10F310008D8B998772CFC501B4010E94E970362F99 -:10F32000272F80CF8091A21784FF04C08460877F3D -:10F330008093A2170895CF92DF92EF92FF920F93DE -:10F340001F93CF93DF93CDB7DEB7EDB6FEB6DC01EA -:10F350000D900020E9F79D01281B390B285F3F4FD6 -:10F36000EDB7FEB7E21BF30B0FB6F894FEBF0FBE6E -:10F37000EDBF0DB71EB70F5F1F4F9F938F9380E1B7 -:10F3800097E29F938F931F930F930F9448396801CF -:10F39000F4E0CF0ED11C0F900F900F900F900F90B4 -:10F3A0000F90D6018D916D01882349F0082E000C35 -:10F3B000990B0F94B141F60131978083F2CF6BE046 -:10F3C00077E2C8010F94E838C8010E94E12B0FB61C -:10F3D000F894FEBE0FBEEDBEDF91CF911F910F914D -:10F3E000FF90EF90DF90CF900895FC01938591FFFF -:10F3F00002C080E00895987121E0903109F020E08A -:10F400008091A21720FB85F98093A217903141F0DB -:10F410008085873471F781E091859E3751F3089597 -:10F4200081E0FDCFFC0120E03EE2DB014D91BD011A -:10F43000403249F0283011F430833196DB011197C6 -:10F440004C91408331962F5F2B3079F710820895CD -:10F45000CF9380914D14C1E08823C9F080914E1460 -:10F4600090914F1440914514509146146091471467 -:10F4700070914814DC01ED91FC910288F389E02D34 -:10F4800025E432E11995C82F811104C0C0E08C2F0A -:10F49000CF9108954091491450914A1460914B14B2 -:10F4A00070914C144115510561057105B9F08091B9 -:10F4B0004E1490914F14DC01ED91FC910288F38978 -:10F4C000E02D25E432E11995882301F310924914C7 -:10F4D00010924A1410924B1410924C1410924D1426 -:10F4E000D6CFCF92DF92EF92FF92CF936B017C0148 -:10F4F000C42F8091451490914614A0914714B09167 -:10F5000048148C159D05AE05BF0529F10E94287A87 -:10F51000811108C0C0E08C2FCF91FF90EF90DF9059 -:10F52000CF90089580914E1490914F14DC01ED918D -:10F53000FC910088F189E02D25E432E1B701A601B4 -:10F540001995882339F3C0924514D0924614E0925D -:10F550004714F0924814CC2321F081E080934D149D -:10F56000DACFC1E0D8CF4F925F926F927F928F92A5 -:10F570009F92AF92BF92CF92DF92EF92FF920F9342 -:10F580001F93CF93DF93EC01423051056105710564 -:10F5900090F480E0DF91CF911F910F91FF90EF9059 -:10F5A000DF90CF90BF90AF909F908F907F906F90A3 -:10F5B0005F904F90089589859A85AB85BC850196AB -:10F5C000A11DB11D84179507A607B70710F38F89F2 -:10F5D0008031C9F5852E962EA72EBB248B899C8958 -:10F5E000AD89BE89880E991EAA1EBB1E280139014D -:10F5F0006A017B0141E0C501B4010E94717A882350 -:10F6000041F29F89903181F5DD24EE24FF24F6013B -:10F61000EE0FFF1FEB5BFD4E118300839A89923042 -:10F6200008F4B8CF4D815E816F817885840E951E78 -:10F63000A61EB71E8092491490924A14A0924B14B1 -:10F64000B0924C14A7CF803209F0A3CF8B899C894C -:10F65000AD89BE894A015B01E7E0B694A79497940F -:10F660008794EA95D1F7BECFE894C7F8DD24EE245D -:10F67000FF24F601EE0FFF1FEE0FFF1FEB5BFD4EA9 -:10F680004082518262827382C9CFCF92DF92EF9221 -:10F69000FF920F931F93CF93DF93FC018185928597 -:10F6A000A385B4850196A11DB11D84179507A607F2 -:10F6B000B70750F480E0DF91CF911F910F91FF9039 -:10F6C000EF90DF90CF90089587898031A9F5BB270F -:10F6D000A72F962F852FC388D488E588F6888C0DB0 -:10F6E0009D1DAE1DBF1DE9016A017B018F01409187 -:10F6F0004514509146146091471470914814841732 -:10F700009507A607B70749F5F8018789803169F59C -:10F71000B701A601552766277727440F551F4B5B76 -:10F720005D4EFA0180819181B0E0A0E088839983E9 -:10F73000AA83BB8381E0BFCF803209F0BBCFC388EF -:10F74000D488E588F688DB01CA01C7E0B695A7959D -:10F7500097958795CA95D1F7C2CF40E0BC01CD01FE -:10F760000E94717A8111D0CFA5CFB701A6014F7742 -:10F77000552766277727440F551F440F551F4B5BAE -:10F780005D4EFA0180819181A281B381BF70CECF9D -:10F790004F925F926F927F92AF92BF92CF92DF9221 -:10F7A000EF92FF920F931F93CF93DF9300D01F929E -:10F7B000CDB7DEB78C0149835A836B837C835901B3 -:10F7C000C12CD12C7601412C82E0582E612C712C59 -:10F7D00049815A816B817C819E012F5F3F4FC80117 -:10F7E0000E94457B882319F1F8018585A3019201C8 -:10F7F00004C0220F331F441F551F8A95D2F7DA0128 -:10F80000C901C80ED91EEA1EFB1E49815A816B81AF -:10F810007C8187898031F1F481E0483F5F4F610549 -:10F820007105B0F2F501C082D182E282F3820F90BD -:10F830000F900F900F90DF91CF911F910F91FF903C -:10F84000EF90DF90CF90BF90AF907F906F905F90E0 -:10F850004F90089581E0483F5F4F6F4F7F4008F41D -:10F86000B7CFE0CF0F931F93CF93DF93FC0123819A -:10F87000222331F080E0DF91CF911F910F91089505 -:10F880008B01EC01FB018789803139F582E08B83A4 -:10F890001D8A1E8A1F8A188E808D918DB0E0A0E08F -:10F8A00025E0880F991FAA1FBB1F2A95D1F7898BC6 -:10F8B0009A8BAB8BBC8B1A8F098F81E0898318865A -:10F8C00019861A861B861C821D821E821F82188A38 -:10F8D0001C861D861E861F86CECF803259F683E099 -:10F8E0008B83428D538D648D758D4D8B5E8B6F8BAD -:10F8F000788F9E012F5E3F4FC8010E94C87B811107 -:10F90000DACFB8CF8F929F92AF92BF92CF92DF9211 -:10F91000EF92FF920F931F93CF93DF93EC018B81B4 -:10F9200081110EC080E0DF91CF911F910F91FF9068 -:10F93000EF90DF90CF90BF90AF909F908F90089501 -:10F9400009891A892B893C89041715072607370767 -:10F9500048F34A015B01823031F488869986AA8691 -:10F96000BB8681E0E0CF81149104A104B10449F485 -:10F97000188619861A861B861C821D821E821F828B -:10F98000F0CF088519852A853B85E98DFA8D858517 -:10F9900090E00996B901A801415051096109710926 -:10F9A000082E04C076956795579547950A94D2F727 -:10F9B00075016401E1E0CE1AD108E108F10804C044 -:10F9C000F694E794D794C7948A95D2F7C416D506CF -:10F9D000E606F70620F0012B022B032B11F58D898B -:10F9E0009E89AF89B88D8C839D83AE83BF838E0142 -:10F9F0000C5F1F4FC114D104E104F10409F4ADCF31 -:10FA00004C815D816E817F819801898D9A8D0E94E4 -:10FA1000457B91E0C91AD108E108F1088111EACFCC -:10FA200081CFC41AD50AE60AF70AE1CF2F923F9296 -:10FA30004F925F926F927F928F929F92AF92BF92FE -:10FA4000CF92DF92EF92FF920F931F93CF93DF93AA -:10FA5000EC014B017A018B81811115C08FEF9FEF73 -:10FA6000DF91CF911F910F91FF90EF90DF90CF909A -:10FA7000BF90AF909F908F907F906F905F904F90CE -:10FA80003F902F900895898180FFE8CF89899A89D6 -:10FA9000AB89BC89488559856A857B85841B950B14 -:10FAA000A60BB70BA70170E060E084179507A607C7 -:10FAB000B70708F47C0167011E0124E0220E311C07 -:10FAC000C114D10409F4A9C0488559856A857B858C -:10FAD0005A0181E0B822898D9A8D2A013B0129E0E3 -:10FAE00076946794579447942A95D1F72B81FC011B -:10FAF000223081F5628D738D848D958D640D751D19 -:10FB0000861D971D00E012E00A191B09C016D106D8 -:10FB100008F486010115E2E01E0771F440904514D7 -:10FB20005090461460904714709048146415750501 -:10FB30008605970509F04EC040E00E94717A88233F -:10FB400009F48CCFB5016B5B7D4EA801C4010F9405 -:10FB5000C64152C0148111501421A114B10471F492 -:10FB600011110CC0452B462B472B51F58D899E89D1 -:10FB7000AF89B88D8C839D83AE83BF83E98DFA8D69 -:10FB80004C805D806E807F8022E0421A51086108BF -:10FB90007108858504C0440C551C661C771C8A9529 -:10FBA000D2F786859785A089B189480E591E6A1EAD -:10FBB0007B1EC301B201610F711D811D911DA2CF7A -:10FBC0004C815D816E817F8191010E94457B811115 -:10FBD000D5CF44CFA0914E14B0914F14ED91FC912C -:10FBE00011970088F189E02D9401AB01BC01CD0192 -:10FBF0001995882309F432CF800E911E8885998546 -:10FC0000AA85BB85800F911FA11DB11D888799878B -:10FC1000AA87BB87C01AD10A53CFC70121CFCF9380 -:10FC2000DF93EC01462F41706C857D858E859F8525 -:10FC30000E94717A882351F0888920E2829FC00156 -:10FC400011248B5B9D4EDF91CF91089590E080E071 -:10FC5000FACFCF93DF93EC018B81882349F189811F -:10FC600087FF22C061E0CE010E940F7EFC01892B3C -:10FC7000F9F08081853EE1F08B81823040F4898902 -:10FC80009A89AB89BC89848F958FA68FB78F8D8910 -:10FC90009E89938F828F8D899E89AF89B88DB58B10 -:10FCA000A48B89818F778983DF91CF910C94287AF7 -:10FCB00081E0888380E0DF91CF910895CF93DF9337 -:10FCC000EC010E94297E1B82DF91CF910895109252 -:10FCD0009A068091A2178F778093A2170E9473CD06 -:10FCE000882321F080E594E10C945E7E0895CF9303 -:10FCF000C091A217C2FF10C0C7FD0EC00E9473CDF5 -:10FD000080FBC7F9C093A2178091A2178F7E8064F1 -:10FD10008093A217CF9108950E94677EF5CFCF936D -:10FD2000DF938091A2178F7E8093A2178091A714F2 -:10FD3000882321F084EA94E10E945E7E8091A317DB -:10FD40009091A417DC01ED91FC910190F081E02DE0 -:10FD500045E360E01995811112C00E940FD88FEF22 -:10FD600096E20E94ACCE8091A21784FF34C00F941B -:10FD7000022783E080937502DF91CF910895C091AF -:10FD8000A317D091A41761E0CE010F94DA0A811174 -:10FD90000BC060E0CE010F94DA0A811105C00E9409 -:10FDA0000BD88BEE96E2DDCF6BE674E184EA94E14A -:10FDB0000E94327C811105C00E940BD88AED96E228 -:10FDC000D0CF8091A21780618093A2170E940FD894 -:10FDD0008EEC96E2C6CF80913509882351F261E01E -:10FDE0008EEB96E20E941D3B0E945E2DC2CFCF9308 -:10FDF000DF93EB01FC012381211104C080E0DF913E -:10FE0000CF9108952250223028F48FE288831982FE -:10FE100081E0F5CF60E00E940F7E009779F3DC016E -:10FE200060E080E09EE22D91203299F0883031F43C -:10FE30009E01260F311DF90190836F5F9E01260FF1 -:10FE4000311DAD0141505109FA014081F901408352 -:10FE50006F5F8F5F8B3039F7FE01E60FF11D108267 -:10FE6000D7CFCF93DF93EC01CB01E881F98160819B -:10FE700071810E94F77E28813981D901ED91FC9131 -:10FE8000AA81BB818C919081992359F08936C8F45D -:10FE9000CF010196F901918380838C918F5F8C93C0 -:10FEA000EACF893670F48FE28083E881F98180811E -:10FEB0009181019691838083EA81FB8180818F5FAC -:10FEC0008083DF91CF9108953F924F925F926F921E -:10FED0007F928F929F92AF92BF92CF92DF92EF92DA -:10FEE000FF920F931F93CF93DF93CDB7DEB72C977D -:10FEF0000FB6F894DEBF0FBECDBF5C01DC01599692 -:10FF00008D909C90F40181859285A385B4859C0198 -:10FF1000AD012F5F3F4F4F4F5F4F29873A874B8788 -:10FF20005C87D50114964D905D906D907C901797ED -:10FF3000411451046104710409F459C0BFEF4B1A14 -:10FF40005B0A6B0A7B0A312C730162011D821E82DF -:10FF50001F821886F40181859285A385B4852D8141 -:10FF60003E814F815885281739074A075B0708F0FB -:10FF700056C089859A85AB85BC858C159D05AE05D7 -:10FF8000BF0550F482E0C82ED12CE12CF12C92E078 -:10FF9000492E512C612C712C9E012F5F3F4FB701D0 -:10FFA000A601C4010E94457B8823C9F189819A81F9 -:10FFB000AB81BC81892B8A2B8B2B01F12601370168 -:10FFC0009FEF491A590A690A790A2D813E814F81AA -:10FFD00058852F5F3F4F4F4F5F4F2D833E834F8399 -:10FFE00058873FEFC31AD30AE30AF30AB3CF40801E -:10FFF00051806280738033243394A6CFC414D50417 -:020000021000EC -:10000000E604F70411F70FEF1FEF2FEF3FE0B70102 -:10001000A601C4010E94B37A782E81111AC0712CF6 -:10002000872D2C960FB6F894DEBF0FBECDBFDF91A3 -:10003000CF911F910F91FF90EF90DF90CF90BF90E5 -:10004000AF909F908F907F906F905F904F903F9078 -:100050000895F501448155816681778141155105E7 -:100060006105710539F097018601C4010E94B37AD8 -:100070008823A9F2D5011496CD92DD92ED92FC92DF -:100080001797332051F0D701C6010196A11DB11D6C -:10009000F40180839183A283B383F50185899689D6 -:1000A000A789B08D892B8A2B8B2B09F0B9CFC58AF4 -:1000B000D68AE78AF08E818180688183B1CF40E063 -:1000C00050E0BA010C94827CFC01238121110C9434 -:1000D0005E7E08952F923F924F925F926F927F9231 -:1000E0008F929F92AF92BF92CF92DF92EF92FF9248 -:1000F0000F931F93CF93DF93CDB7DEB7C454D109CD -:100100000FB6F894DEBF0FBECDBF7C014B015A0184 -:10011000222E19821C821C8E1F8E6115710511F40E -:1001200010E0B3C1DC0113968C918111F9CFFA0173 -:1001300080818B018F32D1F4DB0113968C91139760 -:100140008250823060F059966D917C91CE014C9630 -:100150000E94327C8E01045E1F4F882309F3C50183 -:100160005C010196F50120812F32D1F39E012F5FB2 -:100170003F4F6901290130E2332E2496CFAE2497F8 -:100180002596DFAE25973E013CE1630E711C229659 -:100190003FAE229721963FAE21973FAE3EAE3DAE99 -:1001A0003CAE3BAE3AAE39AE38AE3FAA950190E0D8 -:1001B00047E0D9018D91882361F18F3251F18E3260 -:1001C00039F44A3009F4ACCF98E04AE09D01F1CF10 -:1001D000EAE9F6E22491222321F031968213FACF44 -:1001E0009FCF491708F49CCF813208F499CF8F37FD -:1001F00009F496CF3FE9380F3A3108F420EEE7E3EF -:10020000F0E0EC0FFD1FE90FF11D820F80839F5F6F -:10021000DDCF8FA9803209F483CF5901D9018C91A8 -:100220002F5F3F4F8F32C9F38823A9F008151905B6 -:1002300019F0C8010E945E7E24969FAD24972596F2 -:100240008FAD25974C145D0411F4962D872D8601F2 -:10025000C92ED82E9CCFF801818D928DD7015A9648 -:100260009C938E935997C8010E945F80C12CF8011E -:1002700080859185A285B385418952896389748976 -:1002800084179507A607B70708F053C025E0B69571 -:10029000A795979587952A95D1F7F82FFF70DF2EB0 -:1002A000D80113968C91823008F43ACF41E050E0A7 -:1002B000BE016E5B7F4FC8010E94167D019709F059 -:1002C0002FCFF80180859185A285B3854F96A11D1A -:1002D000B11D80879187A287B387F0E2DF9EB001CE -:1002E00011246B5B7D4E6115710509F419CFDB019B -:1002F0008C91882341F0853E09F04DC0CC2029F037 -:10030000CC24C394B4CFC1100EC0809145149091F9 -:100310004614A0914714B0914814F701848795873B -:10032000A687B787D08ADB018C918111E9CFCC24D5 -:10033000C394822D8274823409F0F2CECC2009F469 -:10034000C7C0F701D08861E0C7010E940F7E009707 -:1003500009F4E6CE20E2DC011D922A95E9F72BE0B4 -:10036000FE01F796DC0101900D922A95E1F721E25A -:1003700038E2FC01318B208B40E058E057874687FC -:10038000338B228B318F208F578B468B0E94287A9C -:1003900081110AC0C5CE4BE050E0CE01C7960F9444 -:1003A000B941892B09F063CF2D2D30E0F901B5E07B -:1003B000EE0FFF1FBA95E1F7DF01AB5BBD4E1B9659 -:1003C0008C91817121F0822D827109F020C1D701B9 -:1003D00059968D919C915A9740914514509146148D -:1003E00060914714709148141C964D935D936D93E2 -:1003F0007C931F975096DC925097EB5BFD4E848860 -:100400009588B12CA12C54019924882455968D925D -:100410009D92AD92BC925897428D538D70E060E0F2 -:10042000482959296A297B2955964D935D936D93E7 -:100430007C935897A5E0220F331FAA95E1F7D901C5 -:10044000AB5BBD4E1B962C91287109F0D2C0848DF8 -:10045000958DA68DB78DF701818B928BA38BB48B75 -:1004600081E08383822D8F70F7018183148215824E -:1004700016821782108611861286138611E024FEDA -:1004800004C0C7010F94290C182FCE014C960E946E -:100490006480CE0101960E946480812FCC5BDF4F87 -:1004A0000FB6F894DEBF0FBECDBFDF91CF911F9185 -:1004B0000F91FF90EF90DF90CF90BF90AF909F9003 -:1004C0008F907F906F905F904F903F902F90089506 -:1004D000D80113968C911397823009F421CE51964E -:1004E0008D919D910D90BC91A02D803E9F4FAF416D -:1004F000B10508F015CEC8010E94647F882309F475 -:100500000FCE0E94287A882309F40ACED801599682 -:10051000ED91FC915A9714968D909D90AD90BC9062 -:100520001797B2E08B1A9108A108B108858504C01D -:10053000880C991CAA1CBB1C8A95D2F786859785C6 -:10054000A089B189880E991EAA1EBB1E81E08093E6 -:100550004D148092451490924614A0924714B09284 -:100560004814E5E4F2E180E092E0DF019C011D9295 -:1005700021503040E1F7DD24D394D8015996ED9114 -:10058000FC918481D816C0F480914E1490914F1440 -:10059000DC01ED91FC910288F389E02D25E432E144 -:1005A000B501A4014D0D511D611D711D19958823C3 -:1005B00009F4B6CDD394E1CF258580E092E0A0E0A8 -:1005C000B0E004C0880F991FAA1FBB1F2A95D2F75D -:1005D000F8014189528963897489840F951FA61F88 -:1005E000B71F818B928BA38BB48B85E492E1D12CC6 -:1005F000B1CE203161F497012F5E3F4F0E94C87B3E -:10060000882329F084E0D70113968C932BCFD70150 -:1006100013961C9285CD0F931F93CF93DF93CDB785 -:10062000DEB7EB970FB6F894DEBF0FBECDBF8C01DF -:1006300089E894E10E945F808BE1E9E8F4E1DE0162 -:10064000919601900D928A95E1F7BE016F5F7F4F01 -:10065000CE0181960F946C0E1816A4F4CE0101966B -:100660000E94F579882389F3BE016F5F7F4F89E788 -:100670009FE00E94127A69E77FE0C8010F94CF41A2 -:10068000892B19F7CE0181960E946480EB960FB6F4 -:10069000F894DEBF0FBECDBFDF91CF911F910F91B8 -:1006A00008958F929F92AF92BF92CF92DF92EF9276 -:1006B000FF920F931F93CF93DF93DC0170E0FB0158 -:1006C000EE0FFF1FEF5BFC4F20813181615C7C4F9F -:1006D000FB019081D92E80E0E82EF12CB7016D0D41 -:1006E000711D75956795611119C0F9013296659173 -:1006F0007491072E000C880B990B0F94B839DF9179 -:10070000CF911F910F91FF90EF90DF90CF90BF900E -:10071000AF909F908F900895D62EE0CF681711F07C -:10072000D6120CC0492F4150550BFA01EE0FFF1F96 -:10073000EE0FFF1F3296E20FF31FD9CFAB014150EE -:100740005109440F551F440F551FF901E40FF51FC0 -:1007500005911491FA013496E20FF31FC591D491DB -:10076000A017B107C8F2862FCA17DB0708F4B4CF69 -:10077000FA013296E20FF31FE590F490FA013696F3 -:10078000E20FF31FC590D490A01BB10BBD0190E008 -:1007900080E00F94B6394B015C01B6016E197F09F8 -:1007A000072E000C880B990B0F94B8399B01AC01F4 -:1007B000C501B4010F94173A4B015C01C01BD10B6A -:1007C000BE0190E080E00F94B6399B01AC01C501F9 -:1007D000B4010F94023F4B015C01B701FF0C880B81 -:1007E000990B0F94B8399B01AC01C501B4010F946A -:1007F000083E85CF8F929F92AF92BF92CF92DF92A9 -:10080000EF92FF92CF936B017C01C42F20E030E088 -:10081000A9010F94B13987FF07C08DE20E949FCED6 -:10082000F7FAF094F7F8F0942BE037ED43EA5BE346 -:10083000C23021F02FE632E143E05AE3C701B601AE -:100840000F94083E6B017C010F947B3F4B015C01D0 -:100850000F94B6399B01AC01C701B6010F94073E56 -:100860006B017C01C501B4010F94C00D8EE20E94A2 -:100870009FCEC150E8F020E030E040E251E4C701F3 -:10088000B6010F94173A6B017C010F947B3F4B012B -:100890005C010F94C00DC501B4010F94B6399B01E2 -:1008A000AC01C701B6010F94073E6B017C01E1CF9B -:1008B000CF91FF90EF90DF90CF90BF90AF909F903F -:1008C0008F900895EF92FF920F931F93CF93DF9332 -:1008D000C82F7B018A01D2E48F3F09F0D4E580E282 -:1008E0000E949FCE8D2F0E949FCEC7FD04C080E343 -:1008F0008C0F0E949FCE8AE30E949FCEF7016081F9 -:1009000071818281938142E00E94FA8387E693E2BB -:100910000E94ACCEF801608171818281938142E0B6 -:100920000E94FA8362E070E080E090E0DF91CF9176 -:100930001F910F91FF90EF900D94911CEF92FF92F9 -:100940000F931F93CF93DF9300D000D01F921F927D -:10095000CDB7DEB7082F17E1189FC00111249C0105 -:10096000215C394F7901F90160857185072E000CF2 -:10097000880B990B0F94B8396D837E838F8398878A -:10098000F70184819581A681B78189839A83AB839E -:10099000BC83AE014B5F5F4FBE016F5F7F4F80E84E -:1009A0000E9462846091360670913706072E000C13 -:1009B000880B990B0F94B8396D837E838F8398874A -:1009C0008091320690913306A0913406B09135069D -:1009D00089839A83AB83BC83AE014B5F5F4FBE01BB -:1009E0006F5F7F4F8FEF0E94628460914706709126 -:1009F0004806072E000C880B990B0F94B8396D83AD -:100A00007E838F8398878091430690914406A091BE -:100A10004506B091460689839A83AB83BC83AE01B9 -:100A20004B5F5F4FBE016F5F7F4F80E00E9462842B -:100A300060915E0670915F06072E000C880B990B83 -:100A40000F94B8396D837E838F83988780915A067F -:100A500090915B06A0915C06B0915D0689839A83B4 -:100A6000AB83BC83AE014B5F5F4FBE016F5F7F4FB7 -:100A700081E00E946284609138060F3F31F00103EB -:100A8000F0011124E15CF94F628570E082E793E2A6 -:100A90000E9487DA6091380670E08DE693E20E944A -:100AA00087DA60E08AE693E20E94A2D68AE30E9497 -:100AB0009FCE6091490670E090E080E00F942A0E8E -:100AC00061E08AE693E20E94A2D68AE30E949FCE6A -:100AD0006091600670E090E080E00F942A0E289606 -:100AE0000FB6F894DEBF0FBECDBFDF91CF911F913F -:100AF0000F91FF90EF9008950F930FB70F93009110 -:100B00006E000D7F00936E0078940F930BB70F93D8 -:100B10000CB70F921F922F933F934F935F936F9356 -:100B20007F938F939F93AF93BF93EF93FF93112482 -:100B30000E94CB95FF91EF91BF91AF919F918F91C3 -:100B40007F916F915F914F913F912F911F900F90E7 -:100B50000CBF0F910BBF0F910260F89400936E00D1 -:100B60000F910FBF0F911895EF92FF920F931F9364 -:100B7000CF93DF9310926D0660E090E080E00E94DA -:100B8000DCCCCFE3D6E01A8661E090E080E00E9402 -:100B9000DCCC19A22C9802E011E0F8018081807170 -:100BA000C0E0D1E088838EE2E82E86E0F82EF701DF -:100BB000118610860E9422C6F7011286F8018081F4 -:100BC00080728883DF91CF911F910F91FF90EF90FA -:100BD00008958F929F92AF92BF92CF92DF92EF9241 -:100BE000FF920F931F93CF93DF93B0E4A0E06A2F9F -:100BF00070E0AB014B0F511D55954795411119C040 -:100C0000E1EDF8E365917491072E000C880B990BC8 -:100C10000F94B839DF91CF911F910F91FF90EF9012 -:100C2000DF90CF90BF90AF909F908F900895B42F9A -:100C3000E0CFA41711F0B41303C0EDECF9E3E2CF59 -:100C40009A0121503109220F331F220F331FF9015E -:100C5000E153F74CE590F490F901ED52F74CC59152 -:100C6000D4918E159F0518F3A42FC817D90708F43F -:100C7000BECFF901EF52F74C05911491F901EB52F7 -:100C8000F74CC590D4908E199F09BC0190E080E08C -:100C90000F94B6394B015C01B601601B710B072E36 -:100CA000000C880B990B0F94B8399B01AC01C5015E -:100CB000B4010F94173A4B015C01CE19DF09BE0154 -:100CC00090E080E00F94B6399B01AC01C501B401FE -:100CD0000F94023F6B017C01B801110F880B990B37 -:100CE0000F94B8399B01AC01C701B6010F94083EBF -:100CF00091CF80910B06882339F060918316709113 -:100D0000841680918516089560E070E080E0089573 -:100D10002F923F924F925F926F927F928F929F920B -:100D2000AF92BF92CF92DF92EF92FF920F931F93F9 -:100D3000CF93DF93CDB7DEB765970FB6F894DEBFDC -:100D40000FBECDBF8F836B8B20916D062E871092C7 -:100D50006D0637E1839FF0011124E15CF94F848136 -:100D60009581A681B7818F87988BA98BBA8B1092BA -:100D70003A0681E080937402212C312C21011B82E0 -:100D80001C821D821E821A869CE39B87ACE1AC8785 -:100D9000B6E4BD87612C10E000E82FEB2A831982AE -:100DA000AF01485F5F4F59874887CF0104969D8BFD -:100DB0008C8BA885B9856D917C91072E000C880BD2 -:100DC000990B0F94B8396B017C01262D312F402FE0 -:100DD0005A810F94B1398823A9F0EC89FD892081CB -:100DE000318142815381FB89B601C701F1117DC078 -:100DF0000F94B139881F8827881F89836C2C1D2D7B -:100E00000E2DFA820F941E1D6B017C01DC01CB01BB -:100E10002B813C814D815E81821B930BA40BB50B12 -:100E2000B7FD10C0D701C60188519C4FAF4FBF4FCF -:100E30008B839C83AD83BE838F810E949E848AE0D6 -:100E40000E949FCE80E00E94EADD0F941E1D6093F9 -:100E50003B0670933C0680933D0690933E06AC891A -:100E6000BD89AC9011969C90119712968C90129718 -:100E700013967C90B981B1116FC0662D712F802FB0 -:100E80009A810F94743F6B016A2D792D882D972DCF -:100E90000F94743F4B016F85788989899A890F94E3 -:100EA000743FCB01A601B4010E949DCB80917402D6 -:100EB0008823F9F0A885B9856D917C91072E000CE7 -:100EC000880B990B0F94B8399B01AC01EC89FD8913 -:100ED0006081718182819381F981FF23C1F10F9437 -:100EE000684018160CF465CF04C00F94B13987FF21 -:100EF00028C0209174022983222331F010927402B9 -:100F00000F948E100E944B272E8520936D068981A9 -:100F100065960FB6F894DEBF0FBECDBFDF91CF91BF -:100F20001F910F91FF90EF90DF90CF90BF90AF9007 -:100F30009F908F907F906F905F904F903F902F90F9 -:100F400008956C2C1D2D0E2DFA8219825BCF0F9403 -:100F5000B13987FD2ECFCDCF211431044104510486 -:100F600041F0D701C60182199309A409B509B7FD5B -:100F70009DCF2A2D392D482D572D6A857B858C854F -:100F80009D850F94073E20E030E040EC5FE30F9436 -:100F9000B13987FDAECF16012701E0E62E0EEAEE4D -:100FA0003E1E411C511CAA869B868C867D867ECF68 -:100FB00012988D5F21E030E001C0220F8A95EAF798 -:100FC0008091BF07822B8093BF070895CF92DF9255 -:100FD000EF92FF92CF93DF93EC01C880D980EA8033 -:100FE000FB8083EB92E20E94ACCEC701B6010F9466 -:100FF0002A0ECC80DD80EE80FF8083E49CE30E949B -:10100000ACCEC701B6010F942A0EC884D984EA84F5 -:10101000FB848FE39CE30E94ACCEC701B6010F9422 -:101020002A0E8AE0DF91CF91FF90EF90DF90CF9072 -:101030000C949FCE0F930FB70F9300916E000F93F8 -:101040000D7F00936E0000916F000D7F00936F0085 -:101050000F930BB70F930CB70F921F922F933F93E1 -:101060004F935F936F937F938F939F93AF93BF93B0 -:10107000EF93FF9311240E9418A8FF91EF91BF9165 -:10108000AF919F918F917F916F915F914F913F9120 -:101090002F911F900F900CBF0F910BBF0F9102600B -:1010A000F89400936F000F9100936E000F910FBFA3 -:1010B0000F91189500008091E50880FF27C0899A5C -:1010C0008FEF809358078091E50881FF22C08F9AA7 -:1010D0008FEF809359078091E50882FF1DC08091B2 -:1010E0000B0180958270809309018FEF80935A07DE -:1010F00080915C079091E50893FF17C0811113C0A0 -:10110000169A8FEF80935B0700000895899881E01D -:10111000D8CF8F9881E0DDCF80910B0182708093D2 -:10112000090181E0E3CF4398ECCF811103C0169809 -:1011300081E0E8CF439AFCCFAF92BF92CF92DF928B -:10114000EF92FF921F93CF93DF9340EC50E070E05B -:1011500060E08FEA95E10F94CE218FEAA82E85E119 -:10116000B82E11E0F50113AF43E051E860E070E103 -:10117000C5010F940222C0E2D3E0F501D2AFC1AFA6 -:10118000C12CD12CE12C9FE3F92EC586D686E786AB -:10119000F08A60E273E0C5010F940F2164E0C5019D -:1011A0000F942E09C5010F94E61160E8C5010F9454 -:1011B000C72044E25EE06DE078ECC5010F94B221F7 -:1011C000C5010F94DA1168EC70E080E090E00F94B4 -:1011D000911C40EC50E070E060E083E795E10F94F3 -:1011E000CE2123E7A22E25E1B22EF50113AF43E075 -:1011F00051E860E070E1C5010F940222F501D2AF21 -:10120000C1AFC586D686E786F08A60E273E0C50185 -:101210000F940F2164E0C5010F942E09C5010F94AE -:10122000E61160E8C5010F94C72044E25EE06DE07E -:1012300078ECC5010F94B221C5010F94DA1168EC66 -:1012400070E080E090E00F94911C40EC50E070E082 -:1012500060E087E395E10F94CE2137E3A32E35E1DB -:10126000B32EF50113AF43E051E860E070E1C50132 -:101270000F940222F501D2AFC1AFC586D686E786AC -:10128000F08A60E273E0C5010F940F2164E0C501AC -:101290000F942E09C5010F94E61160E8C5010F9463 -:1012A000C72044E25EE06DE078ECC5010F94B22106 -:1012B000C5010F94DA1168EC70E080E090E00F94C3 -:1012C000911C40EC50E070E060E08BEF94E10F94F3 -:1012D000CE214BEFA42E44E1B42EF50113AF43E031 -:1012E00051E860E070E1C5010F940222F501D2AF30 -:1012F000C1AFC586D686E786F08A60E273E0C50195 -:101300000F940F2164E0C5010F942E09C5010F94BD -:10131000E61160E8C5010F94C72044E25EE06DE08D -:1013200078ECC5010F94B221C5010F94DA1168EC75 -:1013300070E080E090E00F94911C40EC50E070E091 -:1013400060E08FEB94E10F94CE215FEBA52E54E18A -:10135000B52EF50113AF43E051E860E070E1C5013F -:101360000F940222F501D2AFC1AFC586D686E786BB -:10137000F08A60E273E0C5010F940F2164E0C501BB -:101380000F942E09C5010F94E61160E8C5010F9472 -:10139000C72044E25EE06DE078ECC5010F94B22115 -:1013A000C5010F94DA1168EC70E080E090E00F94D2 -:1013B000911CDF91CF911F91FF90EF90DF90CF9024 -:1013C000BF90AF900C945A8893E0980F21E030E0E2 -:1013D00002C0220F331F9A95E2F720953095909125 -:1013E000BF0729232093BF07882321F0813021F0F4 -:1013F00081E00895129AFCCF479AFACF80E00E94CC -:10140000E48981E00C94E489882319F0813021F08B -:10141000089580E00C94D88747988091BF07806139 -:101420008093BF070895813089F070F0823081F099 -:1014300021E030E001C0220F8A95EAF78091BF07D2 -:10144000822B8093BF0708955F98F2CF8A98F0CFE0 -:1014500090910801917090930601EACF0F931F932A -:10146000CF93DF93C82F41E06DE979E10E946FD9F6 -:101470008C2F0E948ED985E999E10E94ACCE8DED2A -:1014800098E10E9409DB41E063E879E18C2F0E943A -:101490006FD98C2F0E948ED986E699E10E94ACCE3E -:1014A0008C2F0E9415DA8C2F0F9432128C2F0E94F1 -:1014B00010D68C2F0E943AD68C2F0E94EED58C2FFE -:1014C0000E94B6D58C2F0E9494D58C2F0E94E4D90F -:1014D00041E065EF78E18C2F0E946FD902EF15E0B3 -:1014E000D0E08C2F0E948ED96D2F8CEE98E10E9457 -:1014F00074D6F80160817181072E000C880B990B5E -:101500000F94B839AB01BC0189EE98E10E94A4CFD9 -:10151000F80162817381072E000C880B990B0F94E0 -:10152000B839AB01BC0186EE98E10E94A4CFF80166 -:101530006481758183EE98E10E9404DB0A5F1F4F8E -:10154000D13009F098C06FEF8C2F0E9493D98C2F67 -:101550000E9484D641E063E279E18C2F0E946FD92A -:101560008C2F0E948ED980E199E10E94ACCE6091CF -:10157000E8157091E9158EE499E10E947BDA60919B -:10158000AC157091AD158FE09CE30E947BDA609101 -:101590007015709171158CE09CE30E947BDA8AE0F3 -:1015A0000E949FCE8C2F0E948ED980E199E10E94EB -:1015B000ACCE60913415709135158DE199E10E94A2 -:1015C00004DB8C2F0E948ED980E199E10E94ACCE81 -:1015D0006091F8147091F91487E199E10E9404DB9D -:1015E0008AE00E949FCE41E061E579E18C2F0E9464 -:1015F0006FD9D091EA151091AE1500917215D111E5 -:101600003CC0111141C001113FC0809136158823A3 -:1016100091F0C11102C00E940FD88AE399E10E94A3 -:10162000ACCE80E20E949FCE89E499E10E94ACCECC -:101630008AE00E949FCE8091FA14882391F0C11114 -:1016400002C00E940FD88AE399E10E94ACCE80E2EA -:101650000E949FCE84E499E10E94ACCE8AE00E9471 -:101660009FCE8C2F0E94C7DB8C2FDF91CF911F91D3 -:101670000F910C948ED6D1E034CFCC2349F08AE37D -:1016800099E10E94ACCE0CC08AE399E1C1110AC075 -:101690000E940FD88AE399E10E94ACCEDD2321F0AD -:1016A0008EE499E10E94ACCE112321F08FE09CE3FF -:1016B0000E94ACCE002321F08CE09CE30E94ACCED3 -:1016C0008AE00E949FCEA1CF8F929F92AF92BF924D -:1016D000DF92EF92FF920F931F93CF93DF93CDB7DB -:1016E000DEB7C658D1090FB6F894DEBF0FBECDBF26 -:1016F000C358DF4F188219821A821B82CD57D040FF -:101700008091EF039091F003A091F103B091F20367 -:10171000CF57DF4F88839983AA83BB83C158D040BA -:1017200084E690E0909354078093530710925607F5 -:10173000109255071092570725E537E044E050E036 -:10174000BE016F577F4F83E597E00E9494DA809146 -:101750005307909154070296909354078093530730 -:10176000109256071092550781E0CA57DF4F8883C1 -:10177000C658D040CE018A579F4F0E941F7725E55B -:1017800037E048E450E065E579E083E597E00E94C2 -:1017900094DA80E1E4ECF2E08E010F5F1F4FD80194 -:1017A00001900D928A95E1F725E537E040E150E0A0 -:1017B000B80183E597E00E9494DA8EEF95E00E94ED -:1017C000317786EE98E00E9428778AE796E00E94BB -:1017D00028777E018DE6E80EF11C8FEFD7018C9300 -:1017E000C7010E941F7719821A821B821C82C801BE -:1017F0000E94317719821A821B821C82C8010E94C2 -:101800003177C358DF4F188219821A821B82CD5755 -:10181000D04083E0F70180838983CE0183589F4FB6 -:101820000E943177C7010E941F77C8010E941F776D -:101830005AE0D52EDA94DD2031F0CE0183589F4F47 -:101840000E943177F7CF8CE0D8011D928A95E9F795 -:10185000C8010E942877C358DF4F188219821A8264 -:101860001B82CD57D0404AE0D42EDA94DD2031F0EF -:10187000CE0183589F4F0E943177F7CF83E0CB573B -:10188000DF4F8883C558D040EA968FAFEA97CE01E4 -:101890008B579F4F0E941F77CE0187589F4F0E9402 -:1018A0001F7788E0F701982F11929A95E9F7D801F0 -:1018B0001D928A95E9F725E537E048E050E0B70149 -:1018C00083E597E00E9494DA25E537E048E050E0B0 -:1018D000B80183E597E00E9494DAC358DF4F18827D -:1018E00019821A821B82CD57D0403AE0A32EB12C28 -:1018F000B1E0AB1AB10831F0CE0183589F4F0E947E -:101900003177F6CF19828FEFF7018083C8010E94EB -:101910001677C7010E941F7780E1D8011D928A9532 -:10192000E9F725E537E040E150E0B80183E597E0CD -:101930000E9494DA1982C8010E94167725E537E0E3 -:101940004CE050E062EF75E083E597E00E9494DAA6 -:1019500092E0D92E812C912C20E8A22E2FE3B22EDA -:10196000198A1A8A1B8A1C8A8D869E86AF86B88A37 -:1019700080914A0690914B06A0914C06B0914D067D -:1019800089839A83AB83BC832CEA35EC47E25EE320 -:1019900060914E0670914F068091500690915106CD -:1019A0000F94023F6D837E838F8398872CEA35ECFA -:1019B00047E25EE3609152067091530680915406AF -:1019C000909155060F94173A69877A878B879C8781 -:1019D00025E537E044E150E0B80183E597E00E9457 -:1019E00094DAB1E0DB12C5C184E190E09A83898387 -:1019F00025E537E042E050E0B80183E597E00E943A -:101A000094DA8CE0E4EDF2E0D80101900D928A9531 -:101A1000E1F7C8010E940D778CE0E4EDF2E0D80117 -:101A200001900D928A95E1F7C8010E940D77198205 -:101A3000C8010E941F7780912E028983C8010E94ED -:101A40001F778FEF8983C8010E941F7785E0E0EE42 -:101A5000F2E0D80101900D928A95E1F725E537E093 -:101A600045E050E0B80183E597E00E9494DA1982DE -:101A7000C8010E94167780E2E5EEF2E0D8010190FD -:101A80000D928A95E1F725E537E040E250E0B80194 -:101A900083E597E00E9494DAF7011082C7010E9463 -:101AA000167781EF95E00E94167725E537E048E04C -:101AB00050E069EE75E083E597E00E9494DAC35840 -:101AC000DF4F188219821A821B82CD57D040CE0177 -:101AD00083589F4F0E943177CE0183589F4F0E94B9 -:101AE0003177FE0137968AE0DF011D928A95E9F78A -:101AF0008091E8159091E9159A8389838091AC15BE -:101B00009091AD159C838B83809170159091711588 -:101B10009E838D8380913415909135159A8B898B96 -:101B20008091F8149091F9149C8B8B8B25E537E00C -:101B300044E150E0B80183E597E00E9494DA88E23E -:101B4000E5E0F3E0D80101900D928A95E1F725E5F3 -:101B500037E048E250E0B80183E597E00E9494DA6C -:101B600080E1D82EF8018D2D11928A95E9F725E5AF -:101B700037E040E150E0B80183E597E00E9494DA55 -:101B80001A8219828091EA1581709091AE1590FBAE -:101B900081F99091721590FB82F989838A819091E5 -:101BA000361590FB80F99091FA1490FB81F98A83A5 -:101BB00025E537E042E050E0B80183E597E00E9478 -:101BC00094DAC358DF4F188219821A821B82CD57CC -:101BD000D040CE0183589F4F0E943177CE01835869 -:101BE0009F4F0E943177D8011D92DA94E9F725E5DD -:101BF00037E040E150E0B80183E597E00E9494DAD5 -:101C00008CE6F80111928A95E9F725E537E04CE674 -:101C100050E0B80183E597E00E9494DA87E497E00A -:101C20000E940D7725E537E040E150E069ED75E071 -:101C300083E597E00E9494DA25E537E044E050E040 -:101C400066E876E083E597E00E9494DA8CE0D701BD -:101C50001D928A95E9F7CB57DF4F1882C558D040BF -:101C600080E090E0A0E4B0E4ED968CAF9DAFAEAF25 -:101C7000BFAFED97C7010E942877CE018B579F4FCA -:101C80000E941F77CE0187589F4F0E943177D090D6 -:101C90005707D1104EC000915307109154070456B6 -:101CA00011098091550790915607F7019183808320 -:101CB00084E690E0909354078093530725E537E03E -:101CC00044E050E069E373E083E597E00E9494DA32 -:101CD00025E537E042E050E0B70183E597E00E9458 -:101CE00094DA0E940FD8B80185E998E10E947BDA66 -:101CF000D7018D909C90B12CA12C88E898E10E948E -:101D0000ACCEC501B4010F94C00D85E898E10E94E6 -:101D1000ACCE033B124041F00E940BD88AEA99E115 -:101D20000E94ACCEDD24D394809157078D298093F7 -:101D3000570780915707811105C060E085E798E15A -:101D40000E941D3B9091570781E08927CA57DF4FBA -:101D50000FB6F894DEBF0FBECDBFDF91CF911F91BC -:101D60000F91FF90EF90DF90BF90AF909F908F907A -:101D70000895DD24D394F4CDCF93DF9300D01F9248 -:101D8000CDB7DEB78091D108882389F083E390E056 -:101D90009C838B831A8219829E012F5F3F4F40E103 -:101DA00050E062ED78E0CE0103960E9494DA0F9045 -:101DB0000F900F900F90DF91CF910895CF93DF9305 -:101DC00000D01F921F92CDB7DEB781E08093D1087B -:101DD00080E1E2EDF8E0DF011D928A95E9F70E94CB -:101DE000BC8E86E18D8382E390E09C838B831A8294 -:101DF00019829E012F5F3F4F41E050E0BE016B5FB3 -:101E00007F4FCE0103960E9494DA0F900F900F90AF -:101E10000F900F90DF91CF910895AF92BF92CF9224 -:101E2000DF92EF92FF920F931F93CF93DF93C5E55D -:101E3000D9E00EEB15E085E6A82E89E0B82EC12C7E -:101E4000D12C7601C39469917991899199910F94DC -:101E5000B639288939894A895B890F94173A0F94D2 -:101E60007B3FF80161937193819391938F01C61623 -:101E7000D706E806F90610F46B017C01AC16BD0626 -:101E800011F76FEF7FEFCB01A70196010F94A43DEF -:101E90002093250730932607409327075093280760 -:101EA000DF91CF911F910F91FF90EF90DF90CF9036 -:101EB000BF90AF9008950F931F93CF93DF9309E6E0 -:101EC00019E0CBE2D7E0F801219131914191519194 -:101ED0008F0160E070E080E89FE30F94023F699318 -:101EE000799389939993F7E0CB33DF0761F70F94E8 -:101EF000BA11DF91CF911F910F910C940D8F90919A -:101F0000091680910A16981306C080914C09909189 -:101F10004D09892B21F080E00E94EADDF0CF089581 -:101F2000CF92DF92EF92FF920F931F93CF93DF93A5 -:101F3000CDB7DEB72C970FB6F894DEBF0FBECDBF7E -:101F4000182F6B017A0180913509833090F00E943F -:101F50000BD8C6010E94ACCE8DEC92E20E94ACCEB2 -:101F60001F3F51F589EC92E20E94ACCE8AE00E94BC -:101F70009FCE0E94B485A8958091C007811152C060 -:101F800081E08093C00782E0809335090E94B48588 -:101F900005E1015019F1A895409A69E170E080E0EF -:101FA00090E00F94911C409860E570E080E090E034 -:101FB0000F94911CA895EDCF17FDD8CF87EC92E236 -:101FC0000E94ACCE612F012E000C770B880B990B71 -:101FD0000F942A0E8AE00E949FCEC8CF409A0F9499 -:101FE0003211811111C08CE0EDE2F3E0DE011196B7 -:101FF00001900D928A95E1F7BE016F5F7F4F80E0FF -:102000000E947C2A0E947F8F60EC72E21F3F31F0B9 -:1020100064EC72E2113011F46DEB72E240E0C70142 -:102020000E94E2DC2C960FB6F894DEBF0FBECDBF47 -:10203000DF91CF911F910F91FF90EF90DF90CF90A4 -:1020400008954F925F926F927F929F92AF92BF924C -:10205000CF92DF92EF92FF920F931F93CF93DF9374 -:10206000EC016B015A01922E8FEFE2E02813E22F70 -:1020700085E0E802F0011124E25EF94F84818823B3 -:1020800009F456C01C821D821E821F8218868C8114 -:102090008230A1F0833009F47CC08130C9F52D81F4 -:1020A0003E814F815885F6016081718182819381E3 -:1020B0000F94B13987FD2CC082E08C830F941E1DD4 -:1020C0002B013C01B701FF0C880B990B0F94B83919 -:1020D0009B01AC016D817E818F8198850F94073EB5 -:1020E0009B01AC01F60160817181828193810F9423 -:1020F000684087FD42C09801A8EEB3E00F94F83D18 -:10210000460E571E681E791E488259826A827B825B -:10211000DF91CF911F910F91FF90EF90DF90CF90C3 -:10212000BF90AF909F907F906F905F904F90089579 -:10213000F5014080518062807380A30192016D811E -:102140007E818F8198850F94B139882309F49FCFC0 -:102150004D825E826F8278867724739420E030E02F -:10216000A901F50160817181828193810F9468409A -:1021700018160CF0712C7C828ACF88819981AA81F3 -:10218000BB81481A590A6A0A7B0A77FCC1CF83E0EF -:102190008C8347E453E267E573E2892DDF91CF91A9 -:1021A0001F910F91FF90EF90DF90CF90BF90AF9075 -:1021B0009F907F906F905F904F900C94908F4BEE1C -:1021C00052E268EF72E20C94908FAF92BF92CF927E -:1021D000DF92EF92FF920F931F93CF93DF93A89517 -:1021E00060E080914106909142060E945183609385 -:1021F000430670934406809345069093460661E03B -:1022000080915806909159060E94518360935A0616 -:1022100070935B0680935C0690935D068091300618 -:10222000909131060E94E9856093320670933306DF -:1022300080933406909335068FE3E82E86E0F82EDF -:102240009DE3A92E93E0B92EC4E6D2E010E0F70199 -:10225000C280D380F50101915F0107FF4DC08A81E3 -:102260009B81C816D90608F450C0F7018085918576 -:102270001816190644F407FF4CC0888199818C1503 -:102280009D0508F44FC0F7E1EF0EF11C28961130C0 -:1022900089F52091CF083091D00880913006909137 -:1022A00031068217930718F48FEF0E94DF90809118 -:1022B00036069091370618161906E4F52091620249 -:1022C00030916302809130069091310628173907CA -:1022D00088F548E253E265E373E28FEFDF91CF9137 -:1022E0001F910F91FF90EF90DF90CF90BF90AF9034 -:1022F0000C94908F11E0ABCF002309F4B6CF8A8104 -:102300009B818C159D0508F0B0CF812F0E94DF9036 -:10231000ACCF002309F4B7CF88819981C816D906BC -:1023200008F0B1CF48E253E265E373E2812F0E94E7 -:10233000908FA9CFDF91CF911F910F91FF90EF90D8 -:10234000DF90CF90BF90AF9008952F923F924F9221 -:102350005F926F927F928F929F92AF92BF92CF9235 -:10236000DF92EF92FF920F931F93CF93DF93CDB73E -:10237000DEB7A0970FB6F894DEBF0FBECDBF809139 -:10238000350981111AC0A895A0960FB6F894DEBF42 -:102390000FBECDBFDF91CF911F910F91FF90EF90B6 -:1023A000DF90CF90BF90AF909F908F907F906F9075 -:1023B0005F904F903F902F9008958091FB0781117F -:1023C000E3CF81E08093FB0780912D06811103C04C -:1023D0001092FB07D9CF0E94E59010922D060F9422 -:1023E0001E1D6F83788789879A8723E436E03E83B2 -:1023F0002D8344E652E0598B488B82E196E09B8B1B -:102400008A8BABEEB5E1BD8FAC8FEEE1F6E0FF87D6 -:10241000EE8745EC242E47E0342E1B86FB85F8A37F -:10242000A889B98916966D917C91072E000C880BAE -:10243000990B0F94B8399B01AC01ED81FE8160814D -:102440007181828193810F94684018161CF48B85EA -:102450000E94DF90AE85BF8514968C9114978111F0 -:102460001AC08D919D910D90BC91A02D0097A10552 -:10247000B10589F02F81388549855A85281B390B8C -:102480004A0B5B0BDA01C901B7FD05C0E1E0AE857F -:10249000BF851496EC93AD81BE8114966D917C91AD -:1024A000072E000C880B990B0F94B83969837A8337 -:1024B0008B839C8334E0E32EF12C08E210E02B8523 -:1024C000AE014F5F5F4F6D817E818C8D9D8D0E942F -:1024D0002190AD81BE812D913D914D915C912C8BD0 -:1024E0003D8B4E8B5F8BE889F98964817581072E5E -:1024F000000C880B990B0F94B8399B01AC016C89C7 -:102500007D898E899F890F94684018160CF06EC2E1 -:10251000A889B98916966D917C91072E000C880BBD -:10252000990B0F94B8399B01AC016C897D898E8918 -:102530009F890F94B13987FF59C28091F3078111A8 -:102540003FC0EFE3F6E0F093C607E093C507A7ECC2 -:10255000B7E0ECE01D92EA95E9F71092D3071092EC -:10256000D4071092D5071092D6071092D707109271 -:10257000D8071092D9071092DA07F1E0F093DB0741 -:1025800026E536E03093DD072093DC07AEEDB7E0BB -:10259000ECE01D92EA95E9F71092EA071092EB073A -:1025A0001092EC071092ED071092EE071092EF07D1 -:1025B0001092F0071092F107F093F207F093F307EF -:1025C000D1010D90BC91A02DBD87AC8718966D915F -:1025D0007C9119976115710501F114962D913D912A -:1025E0004D915C911797288F398F4A8F5B8F072EFB -:1025F000000C880B990B0F94B839288D398D4A8DB2 -:102600005B8D0F94073E4B015C0120E030E040E71A -:1026100051EC0F94B13987FF07C021E0F101268BFF -:10262000C12CD12C7601DEC020E030E040E751E43F -:10263000C501B4010F94684018165CF4E1E0D101C3 -:102640005696EC93C12CD12C2FE7E22E23E4F22EE8 -:10265000C9C0D10156968C915697882371F0569631 -:102660001C925697F10116861786108A118A1A96BF -:102670001D921D921D921C921D97EC85FD8547842D -:10268000508861887288D1011E962D913D914D919F -:102690005C915197C501B4010F94083E7B018C01F8 -:1026A00020E030E0A9010F94B13987FD9AC1A30160 -:1026B000920160E070E08FE793E40F94023F6E8F29 -:1026C0007F8F6C019701A8010F94B13987FF03C078 -:1026D000EE8CFF8C8601C701D801F10186879787B0 -:1026E000A08BB18BAC85BD851B962D913D914D91F5 -:1026F0005C911E97C501B4010F94173A4B015C0120 -:10270000F10182829382A482B5829701A801C3015C -:10271000B2010F94173A6B017C01D1011696CD924C -:10272000DD92ED92FC9219971A964D905D906D9006 -:102730007C901D97288D398D4A8D5B8D52966D91B9 -:102740007D918D919C9155970F94073EEC85FD8569 -:1027500023893489458956890F94173AA301920138 -:102760000F94073E20ED3CEC4CE45DE30F94173AE8 -:10277000A30192010F94083E2B013C01D1011A964E -:102780004D925D926D927C921D97288D398D4A8D68 -:102790005B8D52962D933D934D935C935597A70176 -:1027A0009601C501B4010F94083EA30192010F9454 -:1027B000083E20E030E0A9010F94083E6B017C0147 -:1027C00020E030E0A9010F94B13987FD29CF20E046 -:1027D00030E04FE753E4C701B6010F946840181684 -:1027E0000CF430CFC701B6010F94743F759567950F -:1027F000ED81FE816683EA89FB8982819381A481D0 -:10280000B5810097A105B105E9F02F81388549858B -:102810005A85281B390B4A0B5B0BDA01C901B7FD3E -:1028200011C06C897D898E899F890F94743FAA8914 -:10283000BB892D913C91621773070CF4D9C08B852D -:102840000E949ACCED81FE817796FE83ED832889E4 -:102850003989285F3F4F398B288B4A895B894A5FCA -:102860005F4F5B8B4A8B8C8D9D8D09969D8F8C8FD6 -:10287000AE85BF851596BF87AE87B7E12B0E311C9D -:10288000E1E0EB87F8A1F13009F0C8CD20E030E0BD -:102890004CED52E46091320670913306809134061B -:1028A000909135060F94684018161CF48FEF0E9423 -:1028B000DF9080910E0690910F06A0911006B091C6 -:1028C00011060097A105B10501F12F8138854985D1 -:1028D0005A85281B390B4A0B5B0BDA01C901B7FD7E -:1028E00014C0609132067091330680913406909145 -:1028F00035060F94743F20910C0630910D06621737 -:1029000073070CF47DC00E9422C68091C10790918C -:10291000C207A091C307B091C4072F8138854985AC -:102920005A85281B390B4A0B5B0BDA01C901B7FD2D -:102930004FCD8F819885A985BA8588579C4EAF4F1A -:10294000BF4F8093C1079093C207A093C307B09372 -:10295000C40780912C0681111BC08091280690919C -:102960002906A0912A06B0912B060097A105B10572 -:1029700079F02F81388549855A85281B390B4A0BF8 -:102980005B0BDA01C901B7FD03C081E080932C061F -:102990006091360670913706072E000C880B990B54 -:1029A0000F94B83969837A838B839C8382E0E82E05 -:1029B000F12C04E110E02FEFAE014F5F5F4F62E3B7 -:1029C00076E08DEF95E10E94219080912C0688237E -:1029D000F9F0109238068091020180728093000114 -:1029E000F7CCE12CF12C00E010E075CE60E000CFD8 -:1029F0004AE053E269E173E28B850E94908F22CF17 -:102A00004AE053E269E173E28FEF0E94908F7DCF3D -:102A1000C0903206D0903306E0903406F090350630 -:102A200020E030E040EA50E4C701B6010F9468406E -:102A300087FDCFCF20E030E04CED52E4C701B60176 -:102A40000F94B13918162CF2609136067091370642 -:102A5000072E000C880B990B0F94B8399B01AC0121 -:102A6000C701B6010F94B13987FF04C08FE7809387 -:102A70003806AECC80E0FBCF90916F0081E091FDF5 -:102A800002C080E0089590916F009D7F90936F0049 -:102A90000895EFE6F0E08081826080830895CF930F -:102AA000C82F0E943C9594E0C99F90011124F90120 -:102AB000ED55F84F2155384FD9014D915D916D91EC -:102AC0007C91408351836283738391E09093A2074A -:102AD000882319F0CF910C944995CF910895CF9305 -:102AE000DF9380910807649B4DC081608093080745 -:102AF000909103018091080791FD46C08D7F8093DE -:102B00000807809108074B9941C08B7F8093080785 -:102B1000C0919307C0FF10C08091E50880FD0CC0F4 -:102B20008091080780FF08C08091340981608093FC -:102B3000340980E00E944F95C1FF10C08091E508E4 -:102B400081FF0CC08091080781FF08C08091340983 -:102B500082608093340981E00E944F95C2FF18C0C3 -:102B60008091E50882FF14C08091080782FF10C0A1 -:102B70008091340984608093340982E0DF91CF91A1 -:102B80000C944F958E7FB2CF8260B9CF8460BECF58 -:102B9000DF91CF910895809136028F3708F449C0B4 -:102BA0008F57909149069093FF07992309F43FC0EE -:102BB0002C9A209160062093000890910201211127 -:102BC0009095907190930001209138062093FE0714 -:102BD00090910201211190959072909300018F5F66 -:102BE000809336028091FD0791E089278093FD074D -:102BF00081110E94603E9091350221E0290F9730AB -:102C00000CF020E0983008F041C0E92F092E000CAC -:102C1000FF0B8827E15FF9468F4F0D945C413F968B -:102C200087969396A696AB96BE96C3962F962C98AB -:102C3000C0CF9091FF07891708F02C989091000859 -:102C4000891728F090910201907190930001909162 -:102C5000FE07891708F4C3CF90910201BDCF809180 -:102C6000FC07811103C083E08093FC078091FC077F -:102C700081508093FC07882349F0292F07C0809159 -:102C800034028F5F8031ACF480933402209335029C -:102C90008091E30881110E946F9580914C09909179 -:102CA0004D09009729F0019790934D0980934C09A5 -:102CB00008951092340280912D0681111BC08091DD -:102CC0003F06909140069093420680934106809182 -:102CD0005606909157069093590680935806809116 -:102CE0002E0690912F06909331068093300681E056 -:102CF00080932D061092400610923F0610925706C0 -:102D00001092560610922F0610922E06BFCF88E022 -:102D100080937B0085E480937C0080917A008064BE -:102D200080937A00B3CF80917A0086FDA6CF409140 -:102D300078005091790080913F0690914006840F71 -:102D4000951F9093400680933F06A0CF88E0809324 -:102D50007B0086E4E0CF80917A0086FD8ECF4091A3 -:102D600078005091790080912E0690912F06840F63 -:102D7000951F90932F0680932E0688CF88E080932E -:102D80007B0087E4C8CF80917A0086FD76CF4091A2 -:102D90007800509179008091560690915706840FE3 -:102DA000951F909357068093560670CF2F923F92AF -:102DB0004F925F926F927F928F929F92AF92BF924B -:102DC000CF92DF92EF92FF920F931F93CF93DF93F7 -:102DD000CDB7DEB7C058D1090FB6F894DEBF0FBE2D -:102DE000CDBF7C018B01242EAA963FAF2EAFAA97B0 -:102DF0002091690930916A0940916B0950916C09E1 -:102E0000DC016D917D918D919C910F94173A0F94F7 -:102E10007540E8966CAF7DAF8EAF9FAFE89720917D -:102E20006D0930916E0940916F0950917009F70159 -:102E300064817581868197810F94173A0F9475404C -:102E4000EC966CAF7DAF8EAF9FAFEC972091710980 -:102E5000309172094091730950917409D701189605 -:102E60006D917D918D919C911B970F94173A0F94C2 -:102E70007540C458DF4F688379838A839B83CC571E -:102E8000D040209175093091760940917709509191 -:102E90007809F70164857585868597850F94173ABB -:102EA0000F947540A8966CAF7DAF8EAF9FAFA8977B -:102EB0008091D40583FF0EC0A8962CAD3DAD4EADDC -:102EC0005FADA89720932B1630932C1640932D16A8 -:102ED00050932E16D801BC916896BFAF6897F80141 -:102EE000F1812C96FFAF2C97D8011296BC91A09639 -:102EF000BFAFA097F80133808091091690910A1610 -:102F0000891B80958F7019F40E94EADDF5CFF0914E -:102F10000916C058DF4FF883C058D04020910916D9 -:102F20002DAF80914C0990914D09892B11F00C9493 -:102F300071A480911F1690912016A0912116B09136 -:102F40002216E8968CAC9DACAEACBFACE897881A64 -:102F5000990AAA0ABB0A8091231690912416A0917F -:102F60002516B0912616EC962CAD3DAD4EAD5FAD5D -:102F7000EC97281B390B4A0B5B0B29AF3AAF4BAFD1 -:102F80005CAF8091271690912816A0912916B091D8 -:102F90002A16C458DF4F288139814A815B81CC577A -:102FA000D040281B390B4A0B5B0B2DAB3EAB4FAB14 -:102FB00058AF80912B1690912C16A0912D16B091A0 -:102FC0002E16A896CCACDDACEEACFFACA897C81A18 -:102FD000D90AEA0AFB0A09F465C0822D0E940CCDC9 -:102FE0008823B9F0A8968CAD9DADAEADBFADA897C6 -:102FF00080932B1690932C16A0932D16B0932E161B -:103000000E940FD88AE598E10E94ACCEC12CD12C49 -:10301000760194E0299E800111240A5D1D4FC701AD -:10302000B6010F94B839D8012D913D914D915C9125 -:103030000F94173A2B013C0120E030E0A9010F94D6 -:10304000684087FF04C077FA709477F8709420E0A6 -:1030500030E048E453E460917509709176098091FD -:103060007709909178090F94173AA30192010F9470 -:10307000B13987FF17C0A8962CAD3DAD4EAD5FAD01 -:10308000A89720932B1630932C1640932D1650930F -:103090002E160E940FD88BE398E10E94ACCEC12C73 -:1030A000D12C7601D501C4018827B7FD83959927D6 -:1030B000AA27BB27782E29AD3AAD4BAD5CAD57FFA3 -:1030C00002C0689471F88DA99EA9AFA9B8ADB7FFE9 -:1030D00002C0689472F8F7FE02C0689473F894E036 -:1030E000299E800111240A5D1D4FC701B6010F946E -:1030F000B839D8012D913D914D915C910F94173ABB -:103100006B017C0120E030E0A9010F94684087FF4B -:10311000D2C1C701B6019058FDADEF2FF0E0FCAB76 -:10312000EBAB5DAD4DE5549F90011124D901A35641 -:10313000B64FBEAFADAF20E030E040E05FE30F94AC -:10314000083E0F947B3F2B966CAF7DAF8EAF9FAF49 -:103150002B97EDADFEAD1082EA5BFF4F70822DA97B -:103160003EA94FA958AD27962CAF3DAF4EAF5FAFEC -:10317000279757FF0DC050954095309521953F4FAB -:103180004F4F5F4F27962CAF3DAF4EAF5FAF2797A6 -:1031900049AC5AAC6BAC7CAC77FE08C070946094C0 -:1031A00050944094411C511C611C711C23968CAEA0 -:1031B0009DAEAEAEBFAE2397B7FE0DC08827992750 -:1031C000DC0188199909AA09BB0923968CAF9DAF28 -:1031D000AEAFBFAF239723962CAD3DAD4EAD5FADE7 -:1031E0002397ADADBEAD55962D933D934D935C9316 -:1031F0005897FD01418E528E638E748E27962CADAA -:103200003DAD4EAD5FAD27975D962D933D934D93AC -:103210005C939097C501B4010F94B83920912B07A6 -:1032200030912C0740912D0750912E070F94173A9B -:1032300063966CAF7DAF8EAF9FAF639769A37AA3A0 -:103240008BA39CA369AD7AAD8BAD9CAD0F94B839BF -:1032500020912F073091300740913107509132076C -:103260000F94173A67966CAF7DAF8EAF9FAF67979D -:103270006DA37EA38FA398A76DA97EA98FA998ADF2 -:103280000F94B839209133073091340740913507B6 -:10329000509136070F94173A6F966CAF7DAF8EAF93 -:1032A0009FAF6F9769A77AA78BA79CA72091370735 -:1032B000309138074091390750913A07C701B6015C -:1032C0000F94173A69AF7AAF8BAF9CAF6DA77EA70B -:1032D0008FA798AB23962CAD3DAD4EAD5FAD239738 -:1032E00026303105410551050CF0EDC036E043169E -:1032F0005104610471040CF0E6C027968CAD9DADBD -:10330000AEADBFAD27970697A105B1050CF0DBC0A8 -:1033100020E030E0A90169AD7AAD8BAD9CAD0F9492 -:10332000684087FFCBC089AD9AADABADBCADB0589E -:103330002DE54BA95CA9249FF001259FF00D1124D8 -:10334000E356F64F85879687A787B08B8DE5ABA9A7 -:10335000BCA98A9FF0018B9FF00D1124E356F64F14 -:103360002B962CAD3DAD4EAD5FAD2B9721A332A377 -:1033700043A354A327968CAD9DADAEADBFAD2797AB -:1033800084159505A605B70510F4D301C20123964F -:103390002CAD3DAD4EAD5FAD239782179307A407CB -:1033A000B50710F4DA01C9012B962CAD3DAD4EAD39 -:1033B0005FAD2B9782179307A407B50710F4DA01C6 -:1033C000C9012DE54BA95CA9249FF001259FF00DB3 -:1033D0001124E356F64F85A396A3A7A3B0A706979B -:1033E000A105B10510F40C9454A4DF01A95ABF4FF4 -:1033F0008091D2058C9311968091D3058C9321A650 -:1034000089288A288B2819F080E00E94138A8DE58C -:10341000ABA9BCA98A9FF0018B9FF00D1124E35644 -:10342000F64F818D928DA38DB48D892B8A2B8B2B9A -:1034300019F081E00E94138A8DE52BA93CA9829F97 -:10344000F001839FF00D1124E356F64F858D968D84 -:10345000A78DB0A1892B8A2B8B2B19F082E00E94BB -:10346000138A2B968CAD9DADAEADBFAD2B97892B3E -:103470008A2B8B2B11F40C9473A480912907882339 -:1034800019F081508093290780912A07882319F029 -:10349000815080932A07211075C080E00E94D88750 -:1034A00080E28093290780912A0781117AC081E008 -:1034B0000E94E48976C0C701B6012ECE89AD9AADCF -:1034C000ABADBCAD35CFAA96AEADBFADAA97CD9092 -:1034D000DD90ED90FC9020E030E0A901C701B6013D -:1034E0000F94B139882379F08DE52BA93CA9829FEF -:1034F000F001839FF00D1124E356F64FC586D68662 -:10350000E786F08A23CF63962CAD3DAD4EAD5FAD1F -:103510006397CA01B9010F94173A6B017C01679652 -:103520002CAD3DAD4EAD5FAD6797CA01B9010F94AB -:10353000173A9B01AC01C701B6010F94083E6B011D -:103540007C016F962CAD3DAD4EAD5FAD6F97CA015E -:10355000B9010F94173A9B01AC01C701B6010F9452 -:10356000083E0F94B6402DE54BA95CA9249FF001BD -:10357000259FF00D1124E356F64F658776878787E0 -:10358000908BE4CE80912907811102C00E94E489CA -:1035900091E0291288CF81E00E94048A80E2809322 -:1035A0002A07E0909509F0909609009197091091EB -:1035B00098090C947BA42B968CAD9DADAEADBFADA0 -:1035C0002B97892B8A2B8B2B09F404C52091890911 -:1035D00030918A0940918B0950918C09A4966CAD69 -:1035E0007DAD8EAD9FADA4970F94173A0F94E63E34 -:1035F0000F947B3F6B017C018091250790912607FA -:10360000A0912707B0912807EDADFEAD218D328D39 -:10361000438D548D2DAB3EAB4FAB58AF258D368DC2 -:10362000478D50A123962CAF3DAF4EAF5FAF239790 -:1036300021A132A143A154A12F962CAF3DAF4EAF93 -:103640005FAF2F9727962CAD3DAD4EAD5FAD279761 -:1036500082179307A407B50708F4C5C48114910421 -:10366000A104B104D1F06091BE057091BF058091B5 -:10367000C0059091C1056C157D058E059F0568F408 -:103680000F94943DA50194010F94A43D2C153D0584 -:103690004E055F0510F469017A018DA99EA9AFA9B5 -:1036A000B8AD892B8A2B8B2B11F16091C2057091DB -:1036B000C3058091C4059091C5056C157D058E05E7 -:1036C0009F05A8F427962CAD3DAD4EAD5FAD279775 -:1036D0000F94943D2DA93EA94FA958AD0F94A43D38 -:1036E0002C153D054E055F0510F469017A012396FE -:1036F0002CAD3DAD4EAD5FAD2397232B242B252B59 -:1037000021F16091C6057091C7058091C80590911F -:10371000C9056C157D058E059F05B8F427962CAD5F -:103720003DAD4EAD5FAD27970F94943D23962CADE4 -:103730003DAD4EAD5FAD23970F94A43D2C153D05D7 -:103740004E055F0510F469017A012F968CAD9DAD91 -:10375000AEADBFAD2F97892B8A2B8B2B21F16091BA -:10376000CA057091CB058091CC059091CD056C1563 -:103770007D058E059F05B8F427962CAD3DAD4EAD69 -:103780005FAD27970F94943D2F962CAD3DAD4EAD78 -:103790005FAD2F970F94A43D2C153D054E055F0599 -:1037A00010F469017A018DE54BA95CA9849F800121 -:1037B000859F100D11240356164FF801ED5AFF4F47 -:1037C000C082D182E282F382C701B6010F94B6397A -:1037D000A4962CAD3DAD4EAD5FADA4970F94023FC6 -:1037E000D80151966D937D938D939C9354976396D6 -:1037F0002CAD3DAD4EAD5FAD6397298B3A8B4B8BB6 -:103800005C8B67968CAD9DADAEADBFAD67978D8B74 -:103810009E8BAF8BB88F6F962CAD3DAD4EAD5FAD2F -:103820006F97298F3A8F4B8F5C8F89AD9AADABAD77 -:10383000BCAD8D8F9E8FAF8FB8A32B962CAD3DADB9 -:103840004EAD5FAD2B97232B242B252B09F4DAC427 -:103850008E010F5E1F4F5E0131E2A30EB11CC12C21 -:10386000D12C7601D8014D905D906D907D908D01A9 -:1038700020E030E0A901C301B2010F94B1398823DF -:1038800071F0A3019201C301B2010F94173A9B0199 -:10389000AC01C701B6010F94083E6B017C01A01674 -:1038A000B10601F7C701B6010F94B6409B01AC0108 -:1038B00060E070E080E89FE30F94023F6B017C01C1 -:1038C000AC019B0163966CAD7DAD8EAD9FAD6397F2 -:1038D0000F94173A698B7A8B8B8B9C8BA70196017F -:1038E00067966CAD7DAD8EAD9FAD67970F94173A1F -:1038F0006D8B7E8B8F8B988FA70196016F966CAD29 -:103900007DAD8EAD9FAD6F970F94173A698F7A8F0B -:103910008B8F9C8FA701960169AD7AAD8BAD9CAD65 -:103920000F94173A6D8F7E8F8F8F98A3A096BFAD9F -:10393000A097BB2309F4A2C520910B1630910C1659 -:1039400040910D1650910E1623962CAF3DAF4EAF01 -:103950005FAF23972DEB37E346E855E323966CAD35 -:103960007DAD8EAD9FAD23970F94B13987FD86C590 -:103970008090150790901607A0901707B090180731 -:10398000C988DA88EB88FC888091190790911A071A -:10399000A0911B07B0911C078DAB9EABAFABB8AF2E -:1039A0002D893E894F89588D2B962CAF3DAF4EAF58 -:1039B0005FAF2B9780911D0790911E07A0911F0765 -:1039C000B091200763968CAF9DAFAEAFBFAF63974A -:1039D000298D3A8D4B8D5C8D67962CAF3DAF4EAFE8 -:1039E0005FAF67978091210790912207A0912307ED -:1039F000B09124076F968CAF9DAFAEAFBFAF6F97FE -:103A00002D8D3E8D4F8D58A127962CAF3DAF4EAFDB -:103A10005FAF2797C501B4019058A70196010F9495 -:103A2000173A2B013C016DA97EA98FA998AD90583A -:103A30002B962CAD3DAD4EAD5FAD2B970F94173A45 -:103A40009B01AC01C301B2010F94083E2B013C0164 -:103A500063966CAD7DAD8EAD9FAD639790586796C4 -:103A60002CAD3DAD4EAD5FAD67970F94173A9B01FE -:103A7000AC01C301B2010F94083E2B013C016F96CB -:103A80006CAD7DAD8EAD9FAD6F97905827962CADE8 -:103A90003DAD4EAD5FAD27970F94173A9B01AC013A -:103AA000C301B2010F94083E69AF7AAF8BAF9CAFF0 -:103AB0002FEE3FEF4FE75FE30F94684018160CF4CA -:103AC000D6C4A5019401C701B6010F94073E2B018E -:103AD0003C0149825A826B827C822DA93EA94FA962 -:103AE00058AD2B966CAD7DAD8EAD9FAD2B970F94E1 -:103AF000073E2B966CAF7DAF8EAF9FAF2B976D833C -:103B00007E838F83988763962CAD3DAD4EAD5FADC0 -:103B1000639767966CAD7DAD8EAD9FAD67970F9443 -:103B2000073E63966CAF7DAF8EAF9FAF639769879B -:103B30007A878B879C876F962CAD3DAD4EAD5FAD80 -:103B40006F9727966CAD7DAD8EAD9FAD27970F9487 -:103B5000073E67966CAF7DAF8EAF9FAF67976D875F -:103B60007E878F87988BAE014F5F5F4F5EAB4DAB0B -:103B70008E010F5E1F4F1A01C12CD12C7601D1018D -:103B80008D909D90AD90BD901D0120E030E0A90189 -:103B9000C501B4010F94B139882371F0A5019401D6 -:103BA000C501B4010F94173A9B01AC01C701B601DE -:103BB0000F94083E6B017C010215130501F7C70144 -:103BC000B6010F94B6409B01AC0160E070E080E864 -:103BD0009FE30F94023F6B017C01AC019B01C30189 -:103BE000B2010F94173A69837A838B839C83A70170 -:103BF00096012B966CAD7DAD8EAD9FAD2B970F943E -:103C0000173A6D837E838F839887A7019601639609 -:103C10006CAD7DAD8EAD9FAD63970F94173A6987FC -:103C20007A878B879C87A701960167966CAD7DADDF -:103C30008EAD9FAD67970F94173A6D877E878F87FC -:103C4000988BEDADFEAD418852886388748805E598 -:103C500019E0ADA9BEA9CD90DD90ED90FD90BEAB71 -:103C6000ADAB20E030E0A901C701B6010F94B13936 -:103C7000882309F43EC020E030E0A901C701B60165 -:103C80000F94684087FFEBC2A701960150582B960E -:103C90002CAF3DAF4EAF5FAF2B97D8016D917D91AB -:103CA0008D919C910F94B6394B015C01A301920157 -:103CB0002B966CAD7DAD8EAD9FAD2B970F94173AC3 -:103CC000A50194010F94684018169CF4A701960171 -:103CD000C501B4010F94023F2B013C0120E030E00C -:103CE000A9010F94684087FF04C077FA709477F8B1 -:103CF00070940C5F1F4FEDA9FEA92E163F0609F028 -:103D0000A8CFAA96AEADBFADAA971496CD90DD9080 -:103D1000ED90FC90179720E030E0A901C701B601B3 -:103D20000F94B139882309F4A1C2A3019201C701FC -:103D3000B6010F94173A1B018C0123962CAD3DADB3 -:103D40004EAD5FAD2397CA01B9010F94173A6B01CD -:103D50007C018DE5ABA9BCA98A9FF0018B9FF00D7A -:103D60001124E356F64F61817281838194819B0116 -:103D7000AC010F94173A4B015C019B01AC01B601F9 -:103D8000C7010F946840181614F46401750191017D -:103D9000A801B601C7010F946840181614F4610118 -:103DA000780180E1FE017196A5E1B7E001900D92E6 -:103DB0008A95E1F78DE5EBA9FCA98E9F80018F9F85 -:103DC000100D11240356164FC601D701F801818743 -:103DD0009287A387B487618972898389948990586F -:103DE0009B01AC010F94083EADADBEAD1D962D916B -:103DF0003D914D915C9150970F94173A9B01AC0106 -:103E00006BE077ED83E29BE30F94073E6B017C014F -:103E10008BE097EDA3E2BBE3F80185839683A7834C -:103E2000B0876181728183819481ADADBEAD2C91EB -:103E300021602C939B01AC010F94173A9B01AC01BC -:103E4000C701B6010F94684087FD05C0EDADFEAD1A -:103E50008081826080838DE52BA93CA9829FF0013F -:103E6000839FF00D1124E356F64F81819281A38147 -:103E7000B48180930B1690930C16A0930D16B093FB -:103E80000E16E8968CAD9DADAEADBFADE8978093B4 -:103E90001F1690932016A0932116B0932216EC962D -:103EA0002CAD3DAD4EAD5FADEC9720932316309316 -:103EB00024164093251650932616C458DF4F888148 -:103EC0009981AA81BB81CC57D040809327169093CB -:103ED0002816A0932916B0932A16A8962CAD3DADAE -:103EE0004EAD5FADA89720932B1630932C164093C0 -:103EF0002D1650932E169091091680910A1698133C -:103F000003C084E680930616C058DF4F8881C058EE -:103F1000D0408F5F8F708093091680910916909121 -:103F2000081681508F70891709F4D5C310910916AE -:103F30002090081680910916281609F432C31150F2 -:103F40001F70D12CC12C121509F42BC3812E912C7A -:103F50003DE5139FC0011124AC014356564F5CABA5 -:103F60004BABCA010E946A72882309F417C38BA95C -:103F70009CA9892B09F19DE5989DF001999DF00D73 -:103F80001124E356F64FB1840285A384348445801E -:103F9000568067807084A30192016B2D702F8A2D4B -:103FA000932D0F94B139811171C2C114D10421F044 -:103FB000D6018C9180FD6EC211501F70822D209011 -:103FC0000816281609F45FC2181709F4EAC28F5FB1 -:103FD0008F70F5CF2091910930919209409193090A -:103FE00050919409FBCA81149104A104B10409F40D -:103FF0003FC06091BE057091BF058091C005909152 -:10400000C1056C157D058E059F0590F50F94B63999 -:104010006B962CAD3DAD4EAD5FAD6B970F94173ADF -:1040200027966CAF7DAF8EAF9FAF2797C501B401C8 -:104030000F94B6399B01AC0127966CAD7DAD8EAD6A -:104040009FAD27970F94023F4B015C01C701B6015A -:104050000F94B6399B01AC01C501B4010F94B1397D -:1040600087FF06C0C501B4010F947B3F6B017C0143 -:104070002DA93EA94FA958AD232B242B252BC9F1DF -:104080006091C2057091C3058091C4059091C505EA -:104090006C157D058E059F0560F50F94B6396B96FE -:1040A0002CAD3DAD4EAD5FAD6B970F94173A4B0104 -:1040B0005C016DA97EA98FA998AD0F94B6399B01BB -:1040C000AC01C501B4010F94023F4B015C01C70173 -:1040D000B6010F94B6399B01AC01C501B4010F9430 -:1040E000B13987FF06C0C501B4010F947B3F6B0156 -:1040F0007C0123968CAD9DADAEADBFAD2397892BD2 -:104100008A2B8B2BD9F16091C6057091C7058091E0 -:10411000C8059091C9056C157D058E059F0570F544 -:104120000F94B6396B962CAD3DAD4EAD5FAD6B9730 -:104130000F94173A4B015C0123966CAD7DAD8EADAB -:104140009FAD23970F94B6399B01AC01C501B40113 -:104150000F94023F4B015C01C701B6010F94B639C1 -:104160009B01AC01C501B4010F94B13987FF06C0B2 -:10417000C501B4010F947B3F6B017C012F962CADE0 -:104180003DAD4EAD5FAD2F97232B242B252B09F48E -:104190000ACB6091CA057091CB058091CC059091B6 -:1041A000CD056C157D058E059F0508F0FCCA0F94A2 -:1041B000B6396B962CAD3DAD4EAD5FAD6B970F94A0 -:1041C000173A4B015C012F966CAD7DAD8EAD9FAD66 -:1041D0002F970F94B6399B01AC01C501B4010F9420 -:1041E000023F4B015C01C701B6010F94B6399B0138 -:1041F000AC01C501B4010F94B13987FFD4CAC50120 -:10420000B401A4C5A301920163966CAD7DAD8EADE2 -:104210009FAD63970F94173A698B7A8B8B8B9C8B2E -:10422000A301920167966CAD7DAD8EAD9FAD679792 -:104230000F94173A6D8B7E8B8F8B988FA301920111 -:104240006F966CAD7DAD8EAD9FAD6F970F94173AA5 -:10425000698F7A8F8B8F9C8FA30192015DCB2B96F8 -:10426000CCAEDDAEEEAEFFAE2B9717CD2FEE3FEF0F -:104270004FE75FEB69AD7AAD8BAD9CAD0F94B13973 -:1042800087FF08C02FEE3FEF4FE75FEB29AF3AAF54 -:104290004BAF5CAF29AD3AAD4BAD5CAD60E070E0CB -:1042A00080E89FE30F94073E20E030E040E05FE3CA -:1042B0000F94173A0F94B6406B017C012091FE05D4 -:1042C0003091FF054091000650910106C301B201F3 -:1042D0000F94173AA70196010F94173A4B015C010E -:1042E000A701960160E070E080E89FE30F94073E2D -:1042F0009B01AC01C501B4010F94023F1B018C016D -:104300008DE54BA95CA9849FF001859FF00D1124D8 -:10431000E356F64F85859685A785B0898DAB9EAB14 -:10432000AFABB8AF20E030E040E85FE3BC01CD01C7 -:104330000F94B13987FF01CD23EF34E045E35FEB04 -:1043400069AD7AAD8BAD9CAD0F94B13987FFF5CCDB -:1043500020E030E0A90169AD7AAD8BAD9CAD0F9442 -:10436000B139C12CD12C60E8E62E6FEBF62E87FD1B -:1043700006C0C12CD12C50E8E52E5FE3F52EA70135 -:10438000960169AD7AAD8BAD9CAD0F94173A4B0198 -:104390005C0129E539ED40E053E30F94B13987FD25 -:1043A00063C0A501940160E070E080E89FE30F9492 -:1043B000073E20E030E040E057E40F94173A0F94B6 -:1043C0007B3FCB010F9464410197880F991F880FA1 -:1043D000991FFC01E550F84E259135914591549176 -:1043E000FC01E554F84E85919591A591B49189AF62 -:1043F0009AAFABAFBCAFC501B4010F94173A29AD6A -:104400003AAD4BAD5CAD0F94083E4B015C0120E032 -:1044100030E0A901C701B6010F946840181654F4A2 -:10442000A50194016BED7FE089E490E40F94073ED1 -:104430004B015C01A30192016DA97EA98FA998ADE2 -:104440000F94173AA50194010F94023F6B017C0170 -:104450009B01AC01B101C8010F94684018160CF023 -:104460006CCC1601870169CC90E080E0AECF2BE0E8 -:10447000222E37ED332E03E21BE35FCCC12CD12C6F -:10448000E12CF12C8ECCCBA8DCA85DCDC114D104DD -:1044900009F45CC0F601C580D680E780F084BDE5F4 -:1044A000B89DF001B99DF00D1124E356F64F8081BF -:1044B00081FD28C0618972898389948990589B0104 -:1044C000AC010F94083EEBA9FCA9258536854785EC -:1044D00050890F94173A9B01AC01C701B6010F94A4 -:1044E000073E6B018DAF99AF9B01AC016B2D702F17 -:1044F0008A2D932D0F94B13987FD04C0BC2C0D2D4E -:10450000ADAC39AC2B2D302F4A2D532DC301B20148 -:104510000F94B139882309F44FCDFDE5F89DC00112 -:10452000F99D900D11249C012356364F6901D90144 -:104530008C9181608C938BA99CA90E9481708823A7 -:1045400019F1F60180818E7F808336CDAA96AEADBB -:10455000BFADAA971896CD90DD90ED90FC901B977B -:104560002BE037ED43E25BE3C701B6010F946840EF -:1045700018160CF494CF9BE0C92E97EDD92E93E238 -:10458000E92E9BE3F92E8BCF8B2D902FAA2DB32DE7 -:10459000F60185839683A783B0870ECDDCAACBAACC -:1045A0000BCD10910816F12CE12C0DE58091091628 -:1045B000811709F490C0812E912C109FC001112405 -:1045C0009C012356364F3CAB2BABC9010E946A724B -:1045D000882309F47DC0E114F10409F46AC0C7011D -:1045E0000E948170811165C0D7018C9181FD4CC002 -:1045F000089DC001099D900D1124AC014356564FF2 -:104600001A01DA0115964D905D906D907C90189787 -:10461000F701A580B680C780D084A3019201C601AE -:10462000B5010F94B13987FF2FC0D70151966D9115 -:104630007D918D919C91549790589B01AC010F9462 -:10464000083EF70125853685478550890F94173A2E -:104650009B01AC01C601B5010F94073E6B017C01C3 -:10466000A30192010F94B13987FF0EC0D1018C9143 -:1046700081608C938BA99CA90E9481708823F1F0A2 -:10468000F10180818E7F8083089DF001099DF00DEE -:104690001124E356F64F2185328543855485658183 -:1046A0007681878190850F94B139811102C0109372 -:1046B00008161F5F1F70EBA8FCA878CFD1011596D4 -:1046C000CD92DD92ED92FC92189710930816DCCFF4 -:1046D000FCAAEBAAEECFF0900A16E09009160DE5C1 -:1046E000FE1409F480C01FEF1E0D1F70109FC00143 -:1046F00011248356964F0E946A72882309F471C070 -:10470000A12CB12C1BAA1DAE10E000E0FE1409F490 -:1047100071C0BDE5FB9EC0011124FC01E356F64FBC -:104720006F01CF010E946A72882309F45EC0D6012E -:1047300015966D917D918D919C9118970F94B6402F -:104740003B014C010115110509F442C0F6018081BD -:1047500080FF04C0D8018C9181608C93F801808126 -:1047600080FF36C0C8010E94817081112DC0D80120 -:1047700011962D913D914D915C91149760E070E000 -:1047800080E89FE30F94023F1B012C01AC019B01C9 -:10479000B301C4010F94173A69837A838B839C8396 -:1047A00095014BA95DADC201B1010F94173A698B18 -:1047B0007A8B8B8B9C8BAE014F5F5F4FBE016F5E20 -:1047C0007F4FC8010E944C77F80180818E7F8083E3 -:1047D000F394FF2DFF70FF2E53018BAA9DAE86012F -:1047E00095CFE12E7DCFEF2C8BCF35018BA89DACE3 -:1047F0006801EECF0115110509F456C0AA96AEADB9 -:10480000BFADAA9718966D917D918D919C911B9744 -:104810000F94B6406B017C012DEC3CEC4CE45DE365 -:104820000F946840181644F08DECC82E8CECD82EEE -:104830008CE4E82E8DE3F82EF8018081816080837E -:10484000C8010E94817081112BC0D80111962D9151 -:104850003D914D915C91149760E070E080E89FE39A -:104860000F94023F2B013C01A70196010F94173AC8 -:1048700069837A838B839C83A3019201B5018BA901 -:104880009DAD0F94173A698B7A8B8B8B9C8BAE0105 -:104890004F5F5F4FBE016F5E7F4FC8010E944C7734 -:1048A000F80180818E7F80830E94499581E0C05805 -:1048B000DF4F0FB6F894DEBF0FBECDBFDF91CF91B3 -:1048C0001F910F91FF90EF90DF90CF90BF90AF902E -:1048D0009F908F907F906F905F904F903F902F9020 -:1048E000089580E0E4CFE0909909F0909A09009152 -:1048F0009B0910919C099701A80168966FAD689774 -:104900002C967FAD2C97A0968FADA097932D0F94EA -:10491000B13987FD0AC06896EFAC68972C96FFAC5A -:104920002C97A0960FADA097132D8DE5ABA9BCA930 -:104930008A9FF0018B9FF00D1124E356F64F2585D9 -:1049400036854785508960E070E080E89FE30F94EA -:10495000023F2B013C019701A8010F94173A6B010C -:104960007C018091091690910716891B8F70A09683 -:104970008FAFA097A701960160E074E284E799E405 -:104980000F94023F0F9475404B015C01A0968FADD0 -:10499000A09782508630B0F56091650970916609E4 -:1049A0008091670990916809681979098A099B09BA -:1049B00016161706180619062CF5660F771F881F9E -:1049C000991FA096BFADA0972B2F30E050E040E09C -:1049D0000F94C63DCA01B9010F94B8390F94743FC2 -:1049E000860E971EA81EB91EC501B4010F94B839D2 -:1049F0009B01AC0160E074E284E799E40F94023F0C -:104A00006B017C010E943C954091CE055091CF05F1 -:104A10006091D0057091D105480D591D6A1D7B1D0F -:104A20004093CE055093CF056093D0057093D10588 -:104A30009DE52BA93CA9929FF001939FF00D1124B5 -:104A4000EA50F64F80829182A282B38281110E9445 -:104A500049958DE54BA95CA9849F8001859F100D28 -:104A600011240356164FD8011D962D913D914D915D -:104A70005C915097C701B6010F94173AA4966CAF9A -:104A80007DAF8EAF9FAFA497F8016183728383835C -:104A9000948325A136A147A150A527962CAF3DAF01 -:104AA0004EAF5FAF2797CA01B9010F94B6396B9625 -:104AB0006CAF7DAF8EAF9FAF6B979B01AC01C70111 -:104AC000B6010F94173A0F94E63E0F947B3FAE96D3 -:104AD0006CAF7DAF8EAF9FAFAE97F801E95BFF4F34 -:104AE0006083718382839383FE01B1962D96FFAF1D -:104AF000EEAF2D9729E739E0E4963FAF2EAFE4976C -:104B0000AE01435D5F4F5AAB49AB212C312C50E8CD -:104B10005DAB8FE38FAF2D96AEADBFAD2D972D91D1 -:104B20003D914D915D912D96BFAFAEAF2D97C701D1 -:104B3000B6010F94173A4B015C0120E030E0A90167 -:104B40000F94684087FF04C0B7FAB094B7F8B094E8 -:104B5000E496AEADBFADE4972D913D914D915D9141 -:104B6000E496BFAFAEAFE497E2962CAF3DAF4EAF49 -:104B70005FAFE297A5019401E2966CAD7DAD8EAD7D -:104B80009FADE2970F94B13987FF16C0A50194013C -:104B9000E2966CAD7DAD8EAD9FADE2970F94023F76 -:104BA0005B018C0191014DA95FAD0F94B13987FF75 -:104BB00003C015010DAB1FAFE9A9FAA92D962EADC3 -:104BC0003FAD2D97E217F30709F0A5CFA701960196 -:104BD00069AD7AAD8BAD9CAD0F94173A6B017C013A -:104BE00020E030E0A9010F94684087FF04C0F7FA85 -:104BF000F094F7F8F0948090850990908609A09041 -:104C00008709B0908809A7019601C501B4010F94E6 -:104C1000B13987FF12C0A7019601C501B4010F94F5 -:104C2000023F7B018C0191014DA95FAD0F94B13919 -:104C300087FF03C017010DAB1FAF20E030E040E855 -:104C40005FE3B1018DA99FAD0F94B13987FF33C0E8 -:104C50008DE54BA95CA9849F8001859F100D1124CF -:104C60000356164F780157E4E50EF11CAE966CAD75 -:104C70007DAD8EAD9FADAE970F94B63991014DA924 -:104C80005FAD0F94173A0F947B3FD7016D937D93DF -:104C90008D939C93139791014DA95FADA4966CAD34 -:104CA0007DAD8EAD9FADA4970F94173AF801618347 -:104CB0007283838394836B962CAD3DAD4EAD5FAD17 -:104CC0006B97C301B2010F94173AA4966CAF7DAFF6 -:104CD0008EAF9FAFA4978DE52BA93CA9829FF001D1 -:104CE000839FF00D1124E356F64F85889688A78898 -:104CF000B08C81149104A104B10411F00C94DB9ADE -:104D0000818D928DA38DB48D892B8A2B8B2B11F0E5 -:104D10000C94DB9A858D968DA78DB0A1892B8A2B5B -:104D20008B2B11F00C94DB9A20918D0930918E0918 -:104D300040918F0950919009A4966CAD7DAD8EADD8 -:104D40009FADA4970F94173A0F94E63E0F947B3FC4 -:104D50006B017C010C94D39BCF93DF93CDB7DEB76F -:104D600060970FB6F894DEBF0FBECDBFFC0190E197 -:104D7000DE01119601900D929A95E1F780914C0910 -:104D800090914D09892B69F4CE0101960E94D69627 -:104D900060960FB6F894DEBF0FBECDBFDF91CF9106 -:104DA000089580E0F5CFCF93DF93CDB7DEB72C9792 -:104DB0000FB6F894DEBF0FBECDBF19821A821B82D8 -:104DC0001C821D821E821F82188619861A861B86E7 -:104DD0001C869E012F5F3F4F40915109BC0186E721 -:104DE00092E00E94ACA62C960FB6F894DEBF0FBEE0 -:104DF000CDBFDF91CF9108954F925F926F927F92D6 -:104E00008F929F92AF92BF92CF92DF92EF92FF92DA -:104E10000F931F93CF93DF93CDB7DEB72C970FB6C9 -:104E2000F894DEBF0FBECDBF2B013C0129873A8726 -:104E30004B875C8747015801F601E080F1800281D1 -:104E4000138120E030E0A901B701C8010F94B13906 -:104E5000882309F484C05E2D4F2D302F212F852FFC -:104E6000942FA32FB22F89839A83AB83BC8320E036 -:104E700030E0A901B701C8010F94B139811104C014 -:104E8000E12CF12C00E810E4C701D8018D839E834A -:104E9000AF83B887A501940160917E0270917F0273 -:104EA00080918002909181020F94B13987FF0CC0EC -:104EB00080927E0290927F02A0928002B092810244 -:104EC000CE0105960E94D3A64092760250927702B8 -:104ED000609278027092790289859A85AB85BC854B -:104EE00080937A0290937B02A0937C02B0937D0220 -:104EF000CE0101960E94D3A6A501940160917E0285 -:104F000070917F0280918002909181020F9468409D -:104F1000181664F480927E0290927F02A092800222 -:104F2000B0928102CE0105960E94D3A60E947F8F87 -:104F30002C960FB6F894DEBF0FBECDBFDF91CF9198 -:104F40001F910F91FF90EF90DF90CF90BF90AF90A7 -:104F50009F908F907F906F905F904F90089550E05A -:104F600040E035E023E47BCF0E943C951092CE05D3 -:104F70001092CF051092D0051092D10581110C949A -:104F8000499508950F931F938091091690910A16E1 -:104F9000891B8F7009F449C090910616992361F01E -:104FA000833040F48FEF890F29F08093061690E04C -:104FB00080E038C01092061680910A162DE5829F77 -:104FC000C00111248356964FFC01208120FDEFCFB4 -:104FD0004091CE055091CF056091D0057091D105DB -:104FE000E75AFF4F0081118122813381401B510B11 -:104FF000620B730B4093CE055093CF056093D005A1 -:105000007093D10520910A162F5F2F7020930716F9 -:1050100030910A1620910816321304C02091071609 -:10502000209308161F910F9108950E94B4A7BFCF37 -:105030002F923F924F925F926F927F928F929F92A8 -:10504000AF92BF92CF92DF92EF92FF920F931F9396 -:10505000CF93DF93CDB7DEB765970FB6F894DEBF79 -:105060000FBECDBF8FEF9FEF909389008093880094 -:105070000AE00983712C612C789480919C079091AF -:105080009D07A0919E07B0919F07892B8A2B8B2BA0 -:1050900009F0EFC18091A2078823D1F08091A00789 -:1050A0009091A1071092A207892B91F01092A1076D -:1050B0001092A007109293079091091680910A16FA -:1050C000981731F080910A168F5F8F7080930A16BF -:1050D0008091A0079091A107892B09F4CAC1409142 -:1050E00098075091990760919A0770919B0780915A -:1050F000940790919507A0919607B091970700911A -:105100008A0710E030E020E0841B950BA60BB70B5C -:10511000081719072A073B0710F4D901C801E82F1F -:10512000840F951FA61FB71F809398079093990728 -:10513000A0939A07B0939B07F1E0409161075091CB -:105140006207609163077091640780917107909185 -:105150007207A0917307B0917407840F951FA61F63 -:10516000B71F8093710790937207A0937307B09352 -:1051700074071C012D0120943094409450942224F3 -:1051800057FC23943324442455242A82B7FD2FC08E -:1051900000915807002E000C110B220B330B40918D -:1051A000AF075091B0076091B1077091B207400FFF -:1051B000511F621F731F4093AF075093B007609356 -:1051C000B1077093B20740915D0750915E076091FF -:1051D0005F0770916007841B950BA60BB70B80933C -:1051E000710790937207A0937307B093740740916F -:1051F0006507509166076091670770916807809115 -:10520000750790917607A0917707B0917807840F82 -:10521000951FA61FB71F8093750790937607A093DD -:105220007707B09378078C019D0100951095209524 -:105230003095002737FD03951127222733270C8B44 -:10524000B7FD2FC0C09059070C2C000CDD08EE08EC -:10525000FF084091B3075091B4076091B507709172 -:10526000B6074C0D5D1D6E1D7F1D4093B307509317 -:10527000B4076093B5077093B60740915D075091EE -:105280005E0760915F0770916007841B950BA60B0A -:10529000B70B8093750790937607A0937707B09329 -:1052A00078074091690750916A0760916B07709188 -:1052B0006C078091790790917A07A0917B07B09154 -:1052C0007C07840F951FA61FB71F809379079093C3 -:1052D0007A07A0937B07B0937C07AC01BD01409592 -:1052E000509560957095442777FD4395552766271F -:1052F00077274B8BB7FD2FC080905A07082C000CE6 -:105300009908AA08BB08C090B707D090B807E090EA -:10531000B907F090BA07C80CD91CEA1CFB1CC09254 -:10532000B707D092B807E092B907F092BA07C090D9 -:105330005D07D0905E07E0905F07F09060078C19E2 -:105340009D09AE09BF098093790790937A07A093CE -:105350007B07B0937C07C0906D07D0906E07E090FC -:105360006F07F090700780917D0790917E07A09164 -:105370007F07B09180078C0D9D1DAE1DBF1D8093D2 -:105380007D0790937E07A0937F07B0938007B7FDBA -:10539000F2C080905B07082C000C9908AA08BB0893 -:1053A000C090BB07D090BC07E090BD07F090BE074F -:1053B000C80CD91CEA1CFB1CC092BB07D092BC07CE -:1053C000E092BD07F092BE07C0905D07D0905E07E7 -:1053D000E0905F07F09060078C199D09AE09BF0946 -:1053E00080937D0790937E07A0937F07B0938007FB -:1053F000A1E0F11104C080918400909185008A8120 -:105400008111889A9C8991118E9ABB89BB2331F0B6 -:1054100080910B018095887080930901AA2329F05F -:1054200080915C078111A9C0149A809184009091A9 -:105430008500809184009091850021108898011149 -:105440008E98442329F080910B0188708093090184 -:10545000AA2329F080915C07811191C01498EE2352 -:1054600021F08091840090918500E150F0E009F0F6 -:1054700064CE80919C0790919D07A0919E07B0916A -:105480009F07892B8A2B8B2B11F00C941EB1E09176 -:10549000A007F091A107FD8BEC8BEF2B11F40C947E -:1054A00090B18091980790919907A0919A07B09137 -:1054B0009B074091940750919507609196077091D2 -:1054C000970784179507A607B70708F45AC01092E4 -:1054D000A1071092A007109293079091091680914E -:1054E0000A16981711F40C9490B180910A168F5FE8 -:1054F0008F7080930A1630EDC32E37E0D32EE12C47 -:10550000F12C8091A0079091A107892B11F00C94A8 -:1055100016B10E94C2A79093A1078093A007892B80 -:1055200011F40C9416B1A091A007B091A107BD8B06 -:10553000AC8B9C9193FB882780F993FF0E94E770C6 -:10554000882309F412C58C899D8945960E9478703C -:105550001092A1071092A00710929307909109163C -:1055600080910A169817A9F280910A168F5F8F70A2 -:1055700080930A16CECFA0E03CCF419A56CF4198F7 -:105580006ECF40918F075091900760919107709175 -:105590009207481759076A077B0708F40FC2409122 -:1055A0008B0750918C0760918D0770918E07EC8965 -:1055B000FD8986A997A9A0ADB1AD481759076A071B -:1055C0007B0708F0D1C1411551056105710509F04E -:1055D00066C08090070690900806A0900906B090DB -:1055E0000A0683E992E2A1E0FC010591159125915B -:1055F0003491081519052A053B0558F4B694A7946B -:1056000097948794AA0F0496EFEAF2E2E817F90755 -:1056100059F7A0938A07F0E28F169104A104B10410 -:1056200028F480E2882E912CA12CB12C00E2801A63 -:105630009108A108B108811428E09206A104B104E0 -:1056400008F49BC134E0939EC00111248D56914E05 -:10565000FC01329625913491A82DEE27A39F80015D -:10566000A29F010D1E1F06940E1F1E1F112430E065 -:1056700020E0FC01C590D490F12CE12CC01AD10A95 -:10568000E20AF30A4C0D5D1D6E1D7F1D40938B07D2 -:1056900050938C0760938D0770938E0732CF10E084 -:1056A000942F852E862FBD81AE81FF81E8853985B7 -:1056B0002A85FB800C81E0910306E99FA12DFF273D -:1056C00030910406399FA00DF11D10900506199E1A -:1056D000F00DE89DA00DF11D389DF00DE89FF00D37 -:1056E0000A2FBF2F0A9FE12D332722270F9FE00D9E -:1056F000311D211FBA9FE00D311D211FBF9F300DAD -:10570000211D032FB22F0A9FF12C332722270F9F31 -:10571000F00C311D211FBA9FF00C311D211FBF9FBE -:10572000300D211D032FB22FEE2790910706809098 -:1057300008068091090600900E08012A09F484C029 -:1057400030910A08309FE119910B810A810B209159 -:105750000B08209FE0199109810A810BF0900C0839 -:10576000F09E90198108810B3B9FE0199109810AF5 -:10577000810B2B9F90198108810BFB9E801881095A -:105780000A9FF12C332722270F9FF00C311D211F78 -:10579000BA9FF00C311D211FBF9F300D211D032F1B -:1057A000B22F30910608309FE10D911F811E811F9D -:1057B00020910708209FE00D911D811E811FF09010 -:1057C0000808F09E900D811C811F3B9FE00D911DEC -:1057D000811E811F2B9F900D811C811FFB9E800CC1 -:1057E000811D0A9FF12C332722270F9FF00C311DBA -:1057F000211FBA9FF00C311D211FBF9F300D211DAD -:10580000032FB22F30910208309FE119910B810ACA -:10581000810B20910308209FE0199109810A810BD7 -:10582000F0900408F09E90198108810B3B9FE019CD -:105830009109810A810B2B9F90198108810BFB9E96 -:10584000801881090C94A6AC30910A08309FE10DB4 -:10585000911F811E811F20910B08209FE00D911D3B -:10586000811E811FF0900C08F09E900D811C811FFD -:105870003B9FE00D911D811E811F2B9F900D811C70 -:10588000811FFB9E800C811D0A9FF12C332722274C -:105890000F9FF00C311D211FBA9FF00C311D211FED -:1058A000BF9F300D211D032FB22F30910608309F6E -:1058B000E119910B810A810B20910708209FE019C3 -:1058C0009109810A810BF0900808F09E90198108D7 -:1058D000810B3B9FE0199109810A810B2B9F901945 -:1058E0008108810BFB9E801881090A9FF12C3327C8 -:1058F00022270F9FF00C311D211FBA9FF00C311D84 -:10590000211FBF9F300D211D032FB22F30910208A0 -:10591000309FE10D911F811E811F20910308209F60 -:10592000E00D911D811E811FF0900408F09E900DE6 -:10593000811C811F3B9FE00D911D811E811F2B9FAC -:10594000900D811C811FFB9E800C811D11240C83F6 -:10595000FB82BD83AE83FF83E88739872A87982C33 -:10596000892EB12CA82E3DCEAC89BD89D2968D90C2 -:105970009D90AD90BC90D59734CED501C401B6951D -:10598000A795979587958C7F8D56954EFC01C59070 -:10599000D490FC01329625913491B82DB770B29F06 -:1059A000C001B39F900D112403E0969587950A9549 -:1059B000E1F7C81AD90AF12CE12C64CE4091860790 -:1059C0005091870760918807709189074817590798 -:1059D0006A077B0708F031C28090810790908207A8 -:1059E000A0908307B090840780918507EC89FD899A -:1059F00081117CC0EE5BFF4FE080F180028113815A -:105A0000EC89FD89E15BFF4F208131814281538127 -:105A1000EC89FD8962A973A984A995A90E94957052 -:105A2000F1E0F0938507AC89BD89D2964D915D91E7 -:105A30006D917C91D59783E992E2A1E0FC010591FB -:105A4000159125913491041715072607370758F447 -:105A50007695679557954795AA0F0496EFEAF2E277 -:105A6000E817F90759F7A0938A07403251056105F5 -:105A7000710520F440E250E060E070E040525109CE -:105A8000610971094115F8E05F076105710508F4C6 -:105A9000B4C104E0509FC00111248D56914EFC0109 -:105AA000329625913491AA27439FF001429FE10D40 -:105AB000FA1F0694EA1FFA1F1124AF0170E060E09C -:105AC000FC01C590D490F12CE12CC41AD50AE60A49 -:105AD000F70A8C0C9D1CAE1CBF1C80928107909213 -:105AE0008207A0928307B09284070BCD82AD93AD5D -:105AF000A4ADB5AD88169906AA06BB0608F073C119 -:105B000081149104A104B10449F440910706509115 -:105B100008066091090670910A068DCFA0E0FB850A -:105B2000982D492D8A2DEC857D856E85BF855889F8 -:105B300039892A8950910306599F612DBB273091DD -:105B40000406399F600DB11D10900506199EB00D19 -:105B5000549F600DB11D349FB00D589FB00DE62FBE -:105B60007B2FE69F512D33272227EB9F500D311DB0 -:105B70002A1F769F500D311D2A1F7B9F300D211D3E -:105B8000E32F722FE69FF12D33272227EB9FF00D95 -:105B9000311D2A1F769FF00D311D2A1F7B9F300D6E -:105BA000211DE32F722F552790910706409108067B -:105BB0008091090600900E080A2A09F484C03091E9 -:105BC0000A083E9F51199A0B4A0B8A0B20910B0829 -:105BD0002E9F501991094A0B8A0BF0910C08FE9FD9 -:105BE000901941098A0B379F501991094A0B8A0B6A -:105BF000279F901941098A0BF79F40198109E69F59 -:105C0000F12D33272227EB9FF00D311D2A1F769FA0 -:105C1000F00D311D2A1F7B9F300D211DE32F722FA8 -:105C2000309106083E9F510D9A1F4A1F8A1F2091EE -:105C300007082E9F500D911D4A1F8A1FF0910808DA -:105C4000FE9F900D411D8A1F379F500D911D4A1FC9 -:105C50008A1F279F900D411D8A1FF79F400D811DB0 -:105C6000E69FF12D33272227EB9FF00D311D2A1FD0 -:105C7000769FF00D311D2A1F7B9F300D211DE32FD4 -:105C8000722F309102083E9F51199A0B4A0B8A0BD2 -:105C9000209103082E9F501991094A0B8A0BF0910D -:105CA0000408FE9F901941098A0B379F50199109EA -:105CB0004A0B8A0B279F901941098A0BF79F4019BD -:105CC00081090C94E5AE30910A083E9F510D9A1F50 -:105CD0004A1F8A1F20910B082E9F500D911D4A1FAD -:105CE0008A1FF0910C08FE9F900D411D8A1F379F5F -:105CF000500D911D4A1F8A1F279F900D411D8A1F1D -:105D0000F79F400D811DE69FF12D33272227EB9F42 -:105D1000F00D311D2A1F769FF00D311D2A1F7B9F2C -:105D2000300D211DE32F722F309106083E9F51192F -:105D30009A0B4A0B8A0B209107082E9F5019910944 -:105D40004A0B8A0BF0910808FE9F901941098A0BB3 -:105D5000379F501991094A0B8A0B279F90194109C7 -:105D60008A0BF79F40198109E69FF12D33272227DF -:105D7000EB9FF00D311D2A1F769FF00D311D2A1F5C -:105D80007B9F300D211DE32F722F309102083E9F23 -:105D9000510D9A1F4A1F8A1F209103082E9F500DF4 -:105DA000911D4A1F8A1FF0910408FE9F900D411D0E -:105DB0008A1F379F500D911D4A1F8A1F279F900DE4 -:105DC000411D8A1FF79F400D811D1124FB87EC8721 -:105DD0007D876E87BF87588B398B2A8B542F492F2D -:105DE00070E0682F28CE2C893D89215B3F4FD90177 -:105DF0004D915D916D917C911ECEDB01CA01B695EE -:105E0000A795979587958C7F8D56954EFC01C590EB -:105E1000D490FC013296259134914770429FC00185 -:105E2000439F900D1124F3E096958795FA95E1F73D -:105E3000C81AD90AF12CE12C4CCE809130029091F5 -:105E40003102A0913202B0913302B7FF62C02C89B7 -:105E50003D89295B3F4FD901CD90DD90ED90FC90BD -:105E600083E992E221E0FC0145915591659174919D -:105E70004C155D056E057F0558F4F694E794D794AC -:105E8000C794220F0496EFEAF2E2E817F90759F7F0 -:105E900020938A07F0E2CF16D104E104F10428F43C -:105EA00060E2C62ED12CE12CF12C00E2C01AD10800 -:105EB000E108F108C11428E0D206E104F10408F475 -:105EC00031C034E0D39EC00111248D56914EFC01A7 -:105ED0003296259134917C2D6627739FA001729F85 -:105EE000410D561F0694461F561F112470E060E0B6 -:105EF000FC0185919491B0E0A0E0841B950BA60B6A -:105F0000B70B8093300290933102A0933202B0938A -:105F10003302C0903002D0903102E0903202F09013 -:105F20003302EFCAD701C601B695A7959795879515 -:105F30008C7F8D56954EFC0125913491FC01329653 -:105F4000459154918C2D8770C82EC49EC001C59E6A -:105F5000900D112453E0969587955A95E1F7281BEB -:105F6000390BC901B0E0A0E0CCCFEC89FD89C58830 -:105F7000D688E788F08C81E0C114D104E104F104F3 -:105F800009F480E0AC89BD8959960D911D912D9140 -:105F90003C915C97011511052105310509F08260DE -:105FA000EC89FD89458D568D678D70A14115510590 -:105FB0006105710509F08460809393071092810751 -:105FC00010928207109283071092840710928B0719 -:105FD00010928C0710928D0710928E07EC89FD8924 -:105FE00085A196A1A7A1B0A580939407909395074A -:105FF000A0939607B0939707882499245401881A90 -:10600000990AAA0ABB0A8092710790927207A0921D -:106010007307B09274078092750790927607A092EA -:106020007707B09278078092790790927A07A092CA -:106030007B07B0927C0780927D0790927E07A092AA -:106040007F07B092800781A092A0A3A0B4A0880C83 -:10605000991CAA1CBB1CCC0CDD1CEE1CFF1CC092A6 -:106060006107D0926207E0926307F0926407000F25 -:10607000111F221F331F009365071093660720939B -:10608000670730936807440F551F661F771F4093BB -:10609000690750936A0760936B0770936C0780924F -:1060A0006D0790926E07A0926F07B0927007880FED -:1060B000991FAA1FBB1F80935D0790935E07A09353 -:1060C0005F07B0936007109298071092990710929B -:1060D0009A0710929B0782A593A5A4A5B5A58093C6 -:1060E0008F0790939007A0939107B093920786A58E -:1060F00097A5A0A9B1A98093860790938707A0933D -:106100008807B093890781A580935C07EA5BFF4FFE -:1061100090812091E508921304C020912F028217EC -:1061200031F080932F029093E5080E945A88809165 -:10613000E30881110E946F952FEF3FEFA901209393 -:106140003002309331024093320250933302EC8993 -:10615000FD89FE96E080F18002811381AC89BD89C2 -:10616000D2962D913D914D915C91D597A55BBF4FF6 -:10617000BD8BAC8B6D917D918D919C910E949570A2 -:1061800010928507EC89FD8940815181628173817C -:1061900083E992E2A1E0FC010591159125913491EA -:1061A000041715072607370758F47695679557950E -:1061B0004795AA0F04962FEA32E22817390759F7B4 -:1061C000A0938A07403251056105710520F440E231 -:1061D00050E060E070E040525109610971094115D9 -:1061E00038E053076105710508F478C0A4E05A9FB0 -:1061F000C00111248D56914EFC01329625913491A7 -:10620000AA27439FF001429FE10DFA1F0694EA1F5F -:10621000FA1F1124AF0170E060E0FC01C590D4903A -:10622000F12CE12CC41AD50AE60AF70AC0929C07A1 -:10623000D0929D07E0929E07F0929F0780919C0765 -:1062400090919D07A0919E07B0919F07AC01BD0161 -:106250000097E1E0AE07B10520F04FEF5FEF60E09F -:1062600070E0841B950BA60BB70B80939C07909353 -:106270009D07A0939E07B0939F07F8948091840098 -:10628000909185004096F981F150F983FF2309F43C -:1062900045C0640E751E6816790610F40C943CA86F -:1062A0007092890060928800789465960FB6F89491 -:1062B000DEBF0FBECDBFDF91CF911F910F91FF9039 -:1062C000EF90DF90CF90BF90AF909F908F907F9096 -:1062D0006F905F904F903F902F900895DB01CA011F -:1062E000B695A795979587958C7F8D56954EFC0111 -:1062F000C590D490FC013296259134914770429F0D -:10630000C001439F900D112433E0969587953A95EF -:10631000E1F7C81AD90AF12CE12C88CF3C01C0CF93 -:1063200080EDC82E87E0D82EE12CF12C0C9489AAA0 -:10633000FC01208131814281538160917509709106 -:10634000760980917709909178090F94173A0F9404 -:10635000754060932B1670932C1680932D16909396 -:106360002E169091091680910A1698130D9481119A -:106370000E947F8F0E943C9540912B1650912C16C5 -:1063800060912D1670912E164093BB075093BC0759 -:106390006093BD077093BE0781110C9449950895D1 -:1063A0004F925F926F927F928F929F92AF92BF9225 -:1063B000CF92DF92EF92FF92CF93DF93EC01209187 -:1063C00075093091760940917709509178096C856B -:1063D0007D858E859F850F94173A0F9475406B01CC -:1063E0007C0120917109309172094091730950919B -:1063F0007409688579858A859B850F94173A0F946F -:1064000075404B015C0120916D0930916E094091FE -:106410006F09509170096C817D818E819F810F94ED -:10642000173A0F9475402B013C0120916909309176 -:106430006A0940916B0950916C09688179818A8160 -:106440009B810F94173A0F94754060931F167093B9 -:106450002016809321169093221640922316509274 -:106460002416609225167092261680922716909216 -:106470002816A0922916B0922A16C0922B16D092F6 -:106480002C16E0922D16F0922E16909109168091FE -:106490000A16981781F0DF91CF91FF90EF90DF906F -:1064A000CF90BF90AF909F908F907F906F905F90B4 -:1064B0004F900D9481110E947F8F0E943C95C82FB0 -:1064C0008FE196E10E947870CC2381F0DF91CF912B -:1064D000FF90EF90DF90CF90BF90AF909F908F9004 -:1064E0007F906F905F904F900C944995DF91CF9182 -:1064F000FF90EF90DF90CF90BF90AF909F908F90E4 -:106500007F906F905F904F900895CF92DF92EF92BF -:10651000FF92CF93DF93C82F0E943C9594E0C99FD0 -:10652000E0011124FE01E155F84FC080D180E280E6 -:10653000F38081110E944995C55DD84FC701B6010E -:106540000F94B839288139814A815B810F94173AB9 -:10655000DF91CF91FF90EF90DF90CF900895CF9291 -:10656000DF92EF92FF92CF93DF93C82F0E943C956A -:1065700094E0C99FE0011124FE01ED55F84FC08061 -:10658000D180E280F38081110E944995C55DD84F8A -:10659000C701B6010F94B839288139814A815B81DE -:1065A0000F94173ADF91CF91FF90EF90DF90CF904B -:1065B0000895FC017081472F50E0062E02C05595CA -:1065C00047950A94E2F740FF14C04091010850E05B -:1065D000062E02C0559547950A94E2F740FF09C080 -:1065E00021E030E001C0220F6A95EAF720952723C9 -:1065F00020830895CF93DF9324E0829FC00111246C -:10660000EC01C359D04FFC01EA51F74F86559A4F20 -:10661000DC012D913D914D915C9160817181828170 -:1066200093810F94083E688379838A839B83DF91EB -:10663000CF9108958F929F92AF92BF92CF92DF92A7 -:10664000EF92FF92CF93DF9320913702222309F438 -:106650008EC0EC0180910108E82E80FF2CC0809054 -:10666000390290903A02A0903B02B0903C022881FF -:1066700039814A815B81C501B4010F9468401816C5 -:1066800024F488829982AA82BB82809045029090ED -:106690004602A0904702B0904802288139814A8181 -:1066A0005B81C501B4010F94B13987FF04C08882B2 -:1066B0009982AA82BB82E1FE2CC080903D0290901C -:1066C0003E02A0903F02B09040022C813D814E815D -:1066D0005F81C501B4010F946840181624F48C82C0 -:1066E0009D82AE82BF828090490290904A02A09023 -:1066F0004B02B0904C022C813D814E815F81C501DF -:10670000B4010F94B13987FF04C08C829D82AE82A0 -:10671000BF82E2FE2CC0C0904102D0904202E090C5 -:106720004302F0904402288539854A855B85C7017C -:10673000B6010F946840181624F4C886D986EA86F4 -:10674000FB86C0904D02D0904E02E0904F02F09038 -:106750005002288539854A855B85C701B6010F94AB -:10676000B13987FF04C0C886D986EA86FB86DF91E7 -:10677000CF91FF90EF90DF90CF90BF90AF909F9020 -:106780008F900895CF92DF92EF92FF921F93CF9355 -:10679000DF93CDB7DEB760970FB6F894DEBF0FBEBC -:1067A000CDBF8AE896E00E941AB38091D40583FD9C -:1067B00076C02091820230918302409184025091F0 -:1067C0008502609196067091970680919806909147 -:1067D00099060F94B139882309F461C08091510959 -:1067E0000E940CCD182F882331F00E940FD88BE91E -:1067F00094E10E94ACCE20918202309183024091BC -:10680000840250918502609196067091970680915E -:106810009806909199060F94073E6B017C0120E049 -:1068200030E0A9010F94684087FF04C0F7FAF094A4 -:10683000F7F8F094E091510984E0E89FF001112409 -:10684000EA5DFD4F2081318142815381C701B6014C -:106850000F94173A20E030E048E453E40F94684086 -:106860001816DCF40E940FD88CE794E10E94ACCE9D -:106870008091960690919706A0919806B0919906FE -:106880008093820290938302A0938402B093850246 -:1068900086E996E00E9498B102C01111E9CF2AE082 -:1068A00037ED43E25CE360915102709152028091B6 -:1068B0005302909154020F94173A6B017C0160913E -:1068C000200270912102072E000C880B990B0F9467 -:1068D000B8399B01AC01C701B6010F94173A6D8717 -:1068E0007E878F87988B19821A821B821C821D8259 -:1068F0001E821F82188619861A861B861C869E0198 -:106900002F5F3F4F40915109BE01635F7F4F8AE87F -:1069100096E00E94ACA680E1EAE8F6E0A6E7B2E0E5 -:1069200001900D928A95E1F760960FB6F894DEBF5C -:106930000FBECDBFDF91CF911F91FF90EF90DF9001 -:10694000CF900895CF92DF92EF92FF920F931F9313 -:106950006A01E0907E02F0907F0200918002109127 -:106960008102FB012081318142815381FC016081E0 -:106970007181828193810E94FCA61F910F91FF90EB -:10698000EF90DF90CF900895CF92DF92EF92FF9239 -:106990000F931F936B01FC01E080F1800281138152 -:1069A000E6E7F2E02481358146815781608171817B -:1069B000828193810E94FCA61F910F91FF90EF901E -:1069C000DF90CF9008958F929F92AF92BF92CF9217 -:1069D000DF92EF92FF92CF93DF93809051029090DD -:1069E0005202A0905302B0905402FC01C080D180AA -:1069F000E280F38020E030E0A901C701B6010F94E6 -:106A0000B139882341F0C0925102D0925202E092F3 -:106A10005302F0925402C0912002D091210284E6E8 -:106A200090E09093210280932002E091510984E04C -:106A3000E89FF0011124EA5DFD4FC080D180E28023 -:106A4000F38080E090E0A0E8BFE380839183A2839D -:106A5000B3830E94C2B38092510290925202A092DC -:106A60005302B0925402D0932102C0932002E091CD -:106A7000510984E0E89FF0011124EA5DFD4FC082D6 -:106A8000D182E282F382DF91CF91FF90EF90DF908D -:106A9000CF90BF90AF909F908F9008950F931F93CA -:106AA000CF93DF938B01C6E7D2E0E091510924E058 -:106AB000E29FF0011124EA5DFD4F20813181428186 -:106AC0005381FC0160817181828193810F94023F27 -:106AD0002C853D854E855F850F94083E6C877D87AC -:106AE0008E879F87C8010E94D3A6DF91CF911F9107 -:106AF0000F910C947F8F0D94BA114F925F926F9209 -:106B00007F928F929F92AF92BF92CF92DF92EF923D -:106B1000FF920F931F93CF93DF93CDB7DEB72C97E0 -:106B20000FB6F894DEBF0FBECDBF182F062F0E9400 -:106B30007F8F123048F10E940FD884E50E949FCECB -:106B4000612F70E090E080E00F94C00D80E20E9421 -:106B50009FCE86E793E20E94ACCE2C960FB6F894B7 -:106B6000DEBF0FBECDBFDF91CF911F910F91FF9080 -:106B7000EF90DF90CF90BF90AF909F908F907F90DD -:106B80006F905F904F900895011108C080910108A7 -:106B90008770873009F032C10E94446BF090510930 -:106BA0001F1509F422C180E1E6E7F2E0AAE8B6E0A9 -:106BB00001900D928A95E1F7209151023091520295 -:106BC000409153025091540229873A874B875C8742 -:106BD00080E090E0A5E0B3E48093510290935202EC -:106BE000A0935302B0935402412F6F2D80E00E9476 -:106BF0007872412F6F2D81E00E947872412F6F2DA6 -:106C000082E00E947872011146C020918606309180 -:106C10008706409188065091890660917E027091A6 -:106C20007F0280918002909181020F94083E6093D0 -:106C30007E0270937F028093800290938102809005 -:106C40004D0290904E02A0904F02B0905002A501CC -:106C500094010F946840181644F480927E0290923A -:106C60007F02A0928002B092810220E030E040E0FA -:106C70005FE360918109709182098091830990910D -:106C800084090F94173A69837A838B839C83CE019E -:106C900001960E94D3A68CE0189F90011124A901AF -:106CA0004259594F6A018F9DC0011124DC01A2593C -:106CB000B94F7D012D913D914D915C91F60160811F -:106CC0007181828193810F94073E2B013C01D70192 -:106CD00014962D913D914D915C911797F601648129 -:106CE0007581868197810F94073E4B015C01D70126 -:106CF00018962D913D914D915C911B97F601608501 -:106D00007185828593850F94073E6B017C011093FA -:106D10005109A301920160917602709177028091EE -:106D20007802909179020F94083E609376027093F6 -:106D300077028093780290937902A5019401609183 -:106D40007A0270917B0280917C0290917D020F9477 -:106D5000083E60937A0270937B0280937C0290934A -:106D60007D02A701960160917E0270917F02809161 -:106D70008002909181020F94083E60937E0270938E -:106D80007F0280938002909381020E947BB5011163 -:106D900020C0809135098330E0F08AE896E00E94B7 -:106DA0001AB388E0EAE8F6E0DE01119601900D9250 -:106DB0008A95E1F749E759E0BE016B5F7F4FCE014D -:106DC00001960E94A2B461E879E082E996E00E940F -:106DD000C4B429853A854B855C8520935102309354 -:106DE000520240935302509354020E947F8F60914D -:106DF000510988E893E20E947FD6AFCE01E0CECE63 -:106E000021E030E0082E02C0220F331F0A94E2F77F -:106E1000209530959091BF0729232093BF0781309B -:106E200061F020F0823071F081E008955F9A8091E6 -:106E3000E4088E7F8093E408F7CF8A9A8091E40873 -:106E40008D7FF8CF80910801809581708093060135 -:106E50008091E4088B7F8093E40880E090E0A6E1D5 -:106E6000B3E480937E0290937F02A0938002B0935C -:106E700081020E947BB5D8CF80E00E9400B781E0FC -:106E80000E9400B782E00E9400B70C94FE899091A6 -:106E9000091680910A16981308C080914C099091A8 -:106EA0004D09892B11F40C943CB780E00E94EADD77 -:106EB000EECF4F925F926F927F928F929F92AF929E -:106EC000BF92DF92EF92FF920F931F93CF93DF93C6 -:106ED000D82EC82FD0E0FE01E253F44C6491062E68 -:106EE000000C770B880B990B0F94B8392B013C01E0 -:106EF0007E01EE0CFF1CEE0CFF1CF701ED50FB4E6B -:106F00002591359145915491C301B2010F94173ADF -:106F10004B015C01F701E951FB4E6591759185913B -:106F2000949120E030E040EC5FE30F94173AA30126 -:106F300092010F94173AAB01BC0100E010E09801F8 -:106F40008D2D0F94811320E030E0A901C501B4011B -:106F50000F94B139882309F446C0B501A4017058D3 -:106F600000E010E098018D2D0F948113A50194018C -:106F7000C501B4010F94083E4B015C01CC51DB4EBE -:106F8000FE01C491C11107C00E940FD882EC94E1A8 -:106F90000E94ACCECAE0DD2039F0F1E060E070E0A4 -:106FA00080E793E4DF1204C060E070E88BE395E4CF -:106FB00020E030E040E752E40F94023F2B013C0117 -:106FC0006C2F70E090E080E00F94B6399B01AC012B -:106FD000C301B2010F94023F8B019C01B501A401D2 -:106FE0008D2D0F94811381E090E00D2C01C0880F4E -:106FF0000A94EAF79091E408982B9093E408909112 -:107000000108892B80930108F701EA54FB4E859112 -:107010009591A591B491E701CA58DD4F8883998372 -:10702000AA83BB83F701E655FA4F108211821282C0 -:1070300013828D2D0E94FAB20E947BB5F701E657AC -:10704000F94F88819981AA81BB8180839183A28332 -:10705000B383DF91CF911F910F91FF90EF90DF905D -:10706000BF90AF909F908F907F906F905F904F9068 -:1070700008954F925F926F927F928F929F92AF92FC -:10708000BF92CF92DF92EF92FF920E943C95F82E32 -:1070900080910A168093091680930816809307162C -:1070A00084E6809306160E94B4A780ED93E0909347 -:1070B0004D0980934C09F1100E94499581E080931D -:1070C000A2070E947F8F80E00E9485B22B013C01C5 -:1070D0004092090750920A0760920B0770920C07C2 -:1070E00081E00E9485B24B015C0180920D07909275 -:1070F0000E07A0920F07B092100782E00E9485B29F -:107100006B017C01C0921107D0921207E092130725 -:10711000F092140783E00E9485B24092760250926A -:107120007702609278027092790280927A0290924D -:107130007B02A0927C02B0927D02C0927E02D0922D -:107140007F02E0928002F09281026093820270934B -:1071500083028093840290938502FF90EF90DF90EA -:10716000CF90BF90AF909F908F907F906F905F90E7 -:107170004F900C947BB5CF93DF93CDB7DEB72C97B0 -:107180000FB6F894DEBF0FBECDBF0F94B2100E94B1 -:107190003C959CE0EFEAF7E0DE01119601900D923C -:1071A0009A95E1F781110E944995CE0101960E94BE -:1071B000E6872C960FB6F894DEBF0FBECDBFDF91E9 -:1071C000CF9108954F925F926F927F928F929F928C -:1071D000AF92BF92CF92DF92EF92FF92CF93409007 -:1071E00076025090770260907802709079028090D9 -:1071F0007A0290907B02A0907C02B0907D02C090B9 -:107200007E02D0907F02E0908002F09081020E9486 -:107210000D8F0E94E771C0E08C2F0E94FAB240E00F -:1072200060E08C2F0E947872CF5FC330A9F70E9474 -:107230005B8FA30192016091760270917702809139 -:107240007802909179020F94B13981111BC0A50188 -:10725000940160917A0270917B0280917C029091FE -:107260007D020F94B13981110DC020917E023091C1 -:107270007F024091800250918102C701B6010F94B4 -:10728000B13981110E94BBB88FEF80932E02CF914C -:10729000FF90EF90DF90CF90BF90AF909F908F9036 -:1072A0007F906F905F904F900C94BB3F8AE494E185 -:1072B0000E94ACCE8CB164E474E1829581700E942E -:1072C0003A77809103016EE374E1869581700E94A4 -:1072D0003A7789B168E374E183FB882780F90C94DD -:1072E0003A778091E308882331F062E070E080E033 -:1072F00090E00C9421CD0895A5E5B9E090E080E000 -:10730000FC01EC5AF54E45915591659174914D9360 -:107310005D936D937D93FC01EC5BF54E459155912A -:107320006591749150964D935D936D937C935397B3 -:10733000FC01EC5CF54E45915591659174919096E8 -:107340004D935D936D937C93939704968031910553 -:10735000B9F680E29EE4A0E0B0E0809365099093E6 -:107360006609A0936709B093680980E090E0AAE7F6 -:10737000B3E48093890990938A09A0938B09B09311 -:107380008C0980E090E4ACE9B5E480938D0990939A -:107390008E09A0938F09B093900980E090E0AAEF46 -:1073A000B3E48093910990939209A0939309B093C9 -:1073B00094091092950910929609109297091092CB -:1073C00098091092990910929A0910929B091092AB -:1073D0009C098AE097EDA3E2BFE38093FE059093BA -:1073E000FF05A0930006B09301061092EE081092DC -:1073F000EF081092F0081092F1081092EA0810922B -:10740000EB081092EC081092ED081092E60810922A -:10741000E7081092E8081092E90810926E061092A0 -:107420006F061092700610927106109272061092FA -:1074300073061092740610927506109276061092DA -:107440007706109278061092790610927A061092BA -:107450007B0610927C0610927D0610927E0610929A -:107460007F0610928006109281061092820610927A -:10747000830610928406109285061092860610925A -:107480008706109288061092890688EC90E0909307 -:10749000F3058093F20582E390E09093F5058093E5 -:1074A000F4051092F7051092F6058CED90E090939C -:1074B000F9058093F80584E690E09093FB058093AE -:1074C000FA051092FD051092FC0581E79DE3A0EA04 -:1074D000B1E480934A0690934B06A0934C06B09378 -:1074E0004D068AE99EEAACE4BEE380934E06909393 -:1074F0004F06A0935006B093510681E995E6AAEF96 -:10750000B3E48093520690935306A0935406B0932D -:1075100055068FEF80932E021092F10580E090E0E7 -:10752000A0EEBFE38093E9059093EA05A093EB05F5 -:10753000B093EC058093ED059093EE05A093EF05D5 -:10754000B093F0051092E3081092E2080E9471B91E -:107550000E949C8880E090E0A0EAB2E48093D90584 -:107560009093DA05A093DB05B093DC051092DD055E -:107570001092DE051092DF051092E0058093E10580 -:107580009093E205A093E305B093E4051092E5051E -:107590001092E6051092E7051092E8050E94E2B805 -:1075A0000E940FD88BEB98E10C9409DB8091340991 -:1075B000882319F010923409089540E070E060E0EB -:1075C00088E194E10C94E2DC0F931F938091860F85 -:1075D000813019F50F941E1D00913B0710913C0757 -:1075E00020913D0730913E07601B710B820B930B7E -:1075F00028EE33E040E050E00F94A43D60913F0757 -:10760000709140078091410790914207620F731F6C -:10761000841F951F1F910F910895609143077091EA -:1076200044078091450790914607D6CFCF92DF92CD -:10763000EF92FF92CF93C82F8091860F81508230B6 -:1076400008F067C01092860F0F941E1D60934307C9 -:10765000709344078093450790934607C090D505E3 -:10766000D090D605E090D705F090D8050E94E4BAF6 -:10767000AB01BC014093D5055093D6056093D70567 -:107680007093D8058091D6089091D708A091D8081A -:10769000B091D9088C199D09AE09BF09840F951FB7 -:1076A000A61FB71F8093D6089093D708A093D80839 -:1076B000B093D908C1110AC0C1E00E94BC8E8C2FC2 -:1076C000CF91FF90EF90DF90CF9008958091D408F4 -:1076D0009091D50801969093D5088093D4080E9484 -:1076E000E4BAC090DA08D090DB08E090DC08F090B3 -:1076F000DD08C616D706E806F906F0F60E94E4BAD9 -:107700006093DA087093DB088093DC089093DD08BF -:10771000D3CFC0E0D2CF1092860F10923B071092C9 -:107720003C0710923D0710923E07109243071092BB -:107730004407109245071092460710923F07109297 -:10774000400710924107109242070895CF93C091CD -:10775000860F80E0C13069F1C23069F50E94E4BA59 -:1077600060933F07709340078093410790934207CF -:1077700081E08093860F0F941E1D60933B077093EA -:107780003C0780933D0790933E07C23089F080917B -:10779000D2089091D30801969093D3088093D20891 -:1077A0001092D5051092D6051092D7051092D805E3 -:1077B00081E0CF9108950E948BBBDACF20914706DC -:1077C000309148062635310574F420915E063091DB -:1077D0005F06263531053CF4209136063091370698 -:1077E0002630310524F0882349F00C94A6BB66238B -:1077F00029F081E00E9416BB0D948E1008958091AF -:10780000860F813079F482E08093860F0F941E1DDD -:10781000609343077093440780934507909346070E -:1078200081E0089580E00895CF92DF92EF92FF9279 -:10783000FC01C080D180E280F38020E030E0A9012B -:10784000C701B6010F94B13987FF68C0C701B601FF -:10785000905820E030E040E251E40F94173A20E0E5 -:1078600030E040EA50E40F94083E20E030E040E28F -:1078700051E40F94023F0F94743F9B0160E220316A -:10788000F7E23F0730F0C90160E177E20F9434413D -:10789000605D6093A405283E83E0380708F445C086 -:1078A000C90168EE73E00F943441CB016AE070E0E7 -:1078B0000F943441805D8093A50580E22436310524 -:1078C00058F0C90164E670E00F943441CB016AE0DE -:1078D00070E00F943441805D8093A60580E22A30E9 -:1078E000310558F0EAE0F0E0C901BF010F943441DE -:1078F000CB01BF010F943441805D8093A705C9017E -:107900006AE070E00F943441805D8093A80584EABA -:1079100095E0FF90EF90DF90CF90089520E030E069 -:1079200040E251E4C701B60198CF80E2C4CF8F9204 -:107930009F92AF92BF92CF92DF92EF92FF92FC01A3 -:10794000C080D180E280F38020E030E040E251E46A -:10795000C701B6010F94173A20E030E040E251E44D -:107960000F94173A4B015C0120E030E0A901C701F8 -:10797000B6010F94B13920E030E040EA50E487FFCF -:1079800004C020E030E040EA50ECC501B4010F949F -:10799000083E20E030E040E251E40F94023F0F94B3 -:1079A000743F9B018BE237FF05C022273327261B3C -:1079B000370B8DE28093A305C90168EE73E00F9445 -:1079C0004841CB01EAE0F0E0BF010F944841805DFF -:1079D0008093A405C90164E670E00F944841CB018F -:1079E000BF010F944841805D8093A505C901BF0187 -:1079F0000F944841282FCB01BF010F944841805D6F -:107A00008093A6058EE28093A705205D2093A805AC -:107A100083EA95E0FF90EF90DF90CF90BF90AF901A -:107A20009F908F9008959C0197FF26C0EE27FF2717 -:107A3000E81BF90B2D398FEF38070CF05DC08DE294 -:107A40008093A505CF0164E670E00F944841CB0117 -:107A50002AE030E0B9010F944841805D8093A6058B -:107A6000CF01B9010F944841CB01B9010F944841AE -:107A7000805D8093A7052AC0283E83E03807B4F1D3 -:107A8000C90168EE73E00F944841CB01EAE0F0E0F1 -:107A9000BF010F944841805D8093A505C90164E64C -:107AA00070E00F944841CB01BF010F944841805DC5 -:107AB0008093A605C901BF010F944841CB01BF01C6 -:107AC0000F944841805D8093A705F901CF016AE0DA -:107AD00070E00F944841805D8093A80585EA95E0A9 -:107AE00008958DE237FDC5CF80E2C3CFF90180E272 -:107AF000243631050CF0A4CF80E28093A505809355 -:107B0000A605EA30F1056CF38DE237FF80E2809341 -:107B1000A605CF016AE070E00F944841605D609374 -:107B2000A705D4CF9C0197FD2DC080E224363105F6 -:107B30005CF0C90164E670E00F944841CB016AE053 -:107B400070E00F944841805D8093A60580E22A3062 -:107B500031055CF0EAE0F0E0C901BF010F94484153 -:107B6000CB01BF010F944841805D8093A705C901F7 -:107B70006AE070E00F944841805D8093A80586EA32 -:107B800095E008953195219531098DE2DDCF9C0175 -:107B9000283E83E03807D0F1C90168EE73E00F9406 -:107BA0003441CB016AE070E00F943441805D8093F2 -:107BB000A50580E22436310558F0C90164E670E07D -:107BC0000F943441CB016AE070E00F943441805D42 -:107BD0008093A60580E22A30310558F0EAE0F0E013 -:107BE000C901BF010F943441CB01BF010F9434414F -:107BF000805D8093A705C9016AE070E00F9434416D -:107C0000805D8093A80585EA95E0089580E2CFCF56 -:107C1000282F80E2243628F0822F64E60F941A4140 -:107C2000805D8093A60590E22A3040F03AE0822FF2 -:107C3000632F0F941A410F941A41905D9093A705FA -:107C4000822F6AE00F941A41905D9093A80586EA0E -:107C500095E0089524E6829FC001112481589F4F2A -:107C60006FEF70E00F944841262F81E3643609F0EE -:107C700080E28093A50590E22A3040F03AE0822F1E -:107C8000632F0F941A410F941A41905D9093A605AB -:107C9000822F6AE00F941A41905D9093A70585E2C8 -:107CA0008093A80585EA95E00895BC018AE197E2F2 -:107CB0000E94E0DD87E197E20C94ACCECF92DF9298 -:107CC000EF92FF920F931F93CF93DF9300D000D0DA -:107CD0001F92CDB7DEB72091A21724FF92C0F62ED7 -:107CE0008C0181E0681709F46DC0681708F463C05F -:107CF00082E0681709F405C18091A217877F8B7F06 -:107D00008093A2170E94677EA801BE016F5F7F4F1C -:107D100081E00F94BD0C8C01009709F472C0698159 -:107D20007A8121E0AC0180E594E10E946A80882399 -:107D300009F4EEC08091611490916214A0916314D3 -:107D4000B091641480939A1790939B17A0939C17FB -:107D5000B0939D1710929E1710929F171092A01724 -:107D60001092A117B80185E497E20E94E0DDC0906F -:107D70009A17D0909B17E0909C17F0909D178DE379 -:107D800097E20E94ACCEC701B6010F94C00D8AE005 -:107D90000E949FCE8EE297E20E94ACCEC8010E9464 -:107DA0000B838091FC11882311F00CEF11E1C801C5 -:107DB0000F94450E26C0B80182E00F94E72610927A -:107DC00099179ACF0E9473CD811105C0B80181E047 -:107DD0000F94E72691CFE0909917EE2009F10E94C9 -:107DE0000BD861E070E08EE997E20E9487DA8AE0C2 -:107DF0000E949FCE40E070E060E08DE897E20E9434 -:107E0000E2DC27960FB6F894DEBF0FBECDBFDF9140 -:107E1000CF911F910F91FF90EF90DF90CF90089539 -:107E200080EA96E09E838D838FE280939F06FF8297 -:107E3000CE0105969A83898302969C838B838BE17E -:107E4000F82E80919717E81658F4EF9CB001112492 -:107E50006757794ECE0101960E94317FE394F1CFAE -:107E60008F818B3558F460E574E1CE0101960E9454 -:107E7000317F8D819E8101979E838D83ED81FE816F -:107E80001082E091991784E0E89FF0011124E556F3 -:107E9000F94F80919E1790919F17A091A017B091D4 -:107EA000A11780839183A283B3830E940FD8B80166 -:107EB00084E797E20E94E0DD6091991789E6689F68 -:107EC000B00111246156794F89E697E20E94E0DD06 -:107ED000C0909E17D0909F17E090A017F090A11728 -:107EE00083E697E20E94ACCEC701B6010F94C00DA5 -:107EF0008AE00E949FCE809199178F5F8093991797 -:107F0000FBCE0E940FD883E597E20E94ACCEF4CE60 -:107F1000C8010E9455BE75CF0F931F93CF93DF9377 -:107F20001F921F92CDB7DEB72091A21724FF33C056 -:107F30008C01BC0182E00F94E72610929917809182 -:107F4000A217877F8B7F8093A2170E94677EA8016C -:107F5000BE016F5F7F4F80E00F94BD0C8C010097D6 -:107F6000D1F069817A8126E5AC0180E594E10E9437 -:107F70006A808823B9F08091A21781608093A2174C -:107F8000C8010E940B83B8018DEB97E20F94E226A3 -:107F9000C8010F94450E0F900F90DF91CF911F9164 -:107FA0000F910895C8010E9455BEF5CF6F927F9240 -:107FB0008F929F92AF92BF92CF92DF92EF92FF92F9 -:107FC0000F931F93CF93DF93CDB7DEB7C655D1097B -:107FD0000FB6F894DEBF0FBECDBF5C017B016DB65E -:107FE0007EB6BE016F5F7F4FC5010F946C0E1816F1 -:107FF0000CF06BC08C858871803109F081C08DB622 -:108000009EB610E000E0E114F10439F0F7010190B0 -:108010000020E9F78F010E191F09C8010D962DB731 -:108020003EB7281B390B0FB6F8943EBF0FBE2DBFCD -:108030008DB79EB701966C01080F191FE114F1046A -:1080400039F0B7010F94ED418FE2F8013197808349 -:10805000BE016F5F7F4FC8010E94127A19A21CA255 -:1080600021E0A801B501CE0181960E946A80882393 -:10807000E1F08BE1FE01B196DE01DC9601900D92FC -:108080008A95E1F7B601CE01CC960E94D6BFCE010B -:10809000CC960E946480CE0181960E9464800FB6C7 -:1080A000F8949EBE0FBE8DBE9CCF0E940FD8B80123 -:1080B0008AEA96E20F94E226CE0181960E946480BD -:1080C0000FB6F8949EBE0FBE8DBE0FB6F8947EBE5E -:1080D0000FBE6DBECA5ADF4F0FB6F894DEBF0FBE9B -:1080E000CDBFDF91CF911F910F91FF90EF90DF9067 -:1080F000CF90BF90AF909F908F907F906F9008959A -:10810000CE0101960E94F579882309F46ACFE11423 -:10811000F10431F0C7010F94D6268FE20E949FCE62 -:10812000BE016F5F7F4F89E79FE00E94127A0F9434 -:10813000D62680E20E949FCE6D8D7E8D8F8D98A178 -:108140000F94C00D8AE00E949FCE4BCF2F923F929A -:108150004F925F926F927F928F929F92AF92BF9257 -:10816000CF92DF92EF92FF920F931F93CF93DF9303 -:10817000CDB7DEB7C558D1090FB6F894DEBF0FBE34 -:10818000CDBF2DB73EB7CC57DF4F39832883C458B6 -:10819000D04001E025E537E044E050E0BE016758FB -:1081A0007F4F83E597E00E9461CE43E050E0BE013F -:1081B00067587F4F89E393E00F94F441892B09F4CA -:1081C00050C0ED968FADED97882339F08FE3EA9696 -:1081D0008FAFEA97EB961FAEEB970E940FD8BE01C8 -:1081E00067587F4F82E79AE10E94E0DD84E69AE1DA -:1081F0000E94ACCE81E080935707809102068111E6 -:1082000007C080913509833018F080E00E942E8AE3 -:108210009091570781E08927CC57DF4F288139811A -:10822000C458D0400FB6F8943EBF0FBE2DBFCB57F9 -:10823000DF4F0FB6F894DEBF0FBECDBFDF91CF91F9 -:108240001F910F91FF90EF90DF90CF90BF90AF9074 -:108250009F908F907F906F905F904F903F902F9066 -:10826000089501E025E537E042E050E0BE016358A3 -:108270007F4F83E597E00E9461CEE9961CAE1DAE6C -:108280001EAE1FAEE9971092560710925507CE0109 -:1082900081589F4F0E94F176ADB6BEB6C158DF4FF0 -:1082A000C880CF57D040D12C33E0C30ED11CCC0CAA -:1082B000DD1CCC0CDD1C8DB79EB78C199D090FB64B -:1082C000F8949EBF0FBE8DBFEDB7FEB73196CE5767 -:1082D000DF4FF983E883C258D0402DB73EB72C1941 -:1082E0003D090FB6F8943EBF0FBE2DBF8DB79EB7A8 -:1082F00001964C01EDB7FEB7EC19FD090FB6F894E5 -:10830000FEBF0FBEEDBF2DB73EB72F5F3F4F7901C8 -:10831000B601CE57DF4F88819981C258D0400E9464 -:10832000FE760091020681E0082725E537E044E06B -:1083300050E065E679E083E597E00E9461CEB60102 -:10834000C4010E94FE76B601C7010E94FE7600912C -:108350000206011157C0C158DF4F8881CF57D04066 -:1083600090E00296A5E5B9E050E040E030E020E082 -:1083700060E67AE1E0E5CE2EEAE1DE2E8217930791 -:108380000CF4A6C0CE57DF4FE881F981C258D04027 -:10839000E40FF51F40805180628073804D925D92A2 -:1083A0006D927D92821793070CF498C0F401E40F4C -:1083B000F51F208031801281E3812101612E7E2E04 -:1083C00050964D925D926D927C92539782179307CF -:1083D0000CF48DC0F701E40FF51F2080318012816D -:1083E000E3812101612E7E2E90964D925D926D92D9 -:1083F0007C9293972F5F3F4F4C5F5F4F2430310546 -:1084000009F0BCCF89E899E00E94E1768DE899E017 -:108410000E94E17681E999E00E94E17685E999E0A0 -:108420000E94E17689E999E00E94E176CE018B58BD -:108430009F4F0E94E176CE018B589F4F0E94E176BC -:10844000CE018B589F4F0E94E176CE018B589F4FF3 -:108450000E94E1768EEF95E00E94E1760FB6F894E7 -:10846000BEBE0FBEADBE86EE98E00E94D1768AE712 -:1084700096E00E94D176CE0183599F4F0E94A1764B -:10848000CE0101967C010E94E176CE018B589F4F70 -:108490000E94E176CE018B589F4F0E94E176C70182 -:1084A0000E94F176CE0183599F4F0E94F176C980D8 -:1084B000AE968FADAE97C89E6001112491E0C91AA7 -:1084C000D108F8F0CE018B589F4F0E94E176F6CF8D -:1084D000FB01459055906590749060CFF6014590F2 -:1084E0005590659074901201162DE72D66CFE0E44B -:1084F000FAE145905590659074901201162DE72D84 -:1085000070CFC7010E94D1761AE01150CE0129F038 -:108510008B589F4F0E94E176F8CF80589F4F0E9462 -:10852000F176CE018F579F4F0E94F176C7010E94CE -:10853000C176CE0183599F4F0E94C176C058DF4F4C -:10854000C880C058D040CF57DF4F8881C158D04035 -:10855000C89E60011124F1E0CF1AD10830F0CE019D -:108560008B589F4F0E94E176F6CFC7010E94B176EB -:10857000CE0183599F4F0E94A17611E0012725E586 -:1085800037E040E150E0B70183E597E00E9461CE1B -:10859000C7010E94B17600910206012725E537E068 -:1085A0004CE050E062EF75E083E597E00E9461CE19 -:1085B00012E0DD24D394009102060D2525E537E075 -:1085C00044E150E0B70183E597E00E9461CE00915D -:1085D0000206011138C089809A80AB80BC80A50159 -:1085E0009401C501B4010F94FA4081112CC080920E -:1085F0004A0690924B06A0924C06B0924D062CEA89 -:1086000035EC47E25EE36D817E818F8198850F9422 -:10861000173A60934E0670934F06809350069093DE -:1086200051062CEA35EC47E25EE369857A858B8555 -:108630009C850F94023F609352067093530680937B -:10864000540690935506113009F090C1012725E595 -:1086500037E042E050E0B70183E597E00E9461CE49 -:10866000C7010E949176C7010E949176C7010E94BE -:10867000A176C7010E94A17600910206011103C0F4 -:10868000898180932E02C7010E94A17685E0F701BF -:1086900011928A95E9F711E0012725E537E045E0D9 -:1086A00050E0B70183E597E00E9461CEC7010E94C8 -:1086B000B17600910206012725E537E040E250E05F -:1086C000B70183E597E00E9461CECE0183599F4FA9 -:1086D0000E94B17600910206012725E537E041E1CD -:1086E00050E0B70183E597E00E9461CE80910206D9 -:1086F00081110EC089818093F10588E0FE013296D8 -:10870000A9EEB5E001900D928A95E1F70E949C8850 -:108710000091020681E0082725E537E044E150E0BA -:10872000B70183E597E00E9461CE80910206811136 -:108730004BC069817A816115710511F460E273E0C3 -:108740007093E9156093E8158FEA95E10F940F2176 -:108750006B817C816115710511F460E273E07093A7 -:10876000AD156093AC1583E795E10F940F216D81F2 -:108770007E816115710511F460E273E070937115EB -:108780006093701587E395E10F940F2169897A89C9 -:108790006115710511F460E273E070933515609313 -:1087A00034158BEF94E10F940F216B897C8961154F -:1087B000710511F460E273E07093F9146093F8149A -:1087C0008FEB94E10F940F210091020611E0012735 -:1087D00025E537E048E250E0B70183E597E00E94E5 -:1087E00061CE00910206012725E537E040E150E027 -:1087F000B70183E597E00E9461CE00910206012750 -:1088000025E537E042E050E0B70183E597E00E94BC -:1088100061CE80910206811122C08981817080938E -:10882000EA150F9401128981869581708093AE15A7 -:108830000F940912898182FB882780F98093721531 -:108840000F9411128A818170809336150F9419123A -:108850008A81869581708093FA140F942112009179 -:10886000020611E0012725E537E048E050E0B701B6 -:1088700083E597E00E9461CE00910206012725E57D -:1088800037E040E150E0B70183E597E00E9461CE18 -:1088900000910206012725E537E04CE650E0B701DC -:1088A00083E597E00E9461CE19821A821B821C82A6 -:1088B0001D821E821F82188619861A861B861C86B8 -:1088C000C7010E94917600910206012725E537E055 -:1088D00040E150E069ED75E083E597E00E9461CEEC -:1088E00000910206012725E537E044E050E066E804 -:1088F00076E083E597E00E9461CEC7010E94D176C1 -:10890000CE0180589F4F0E94A176CE0183599F4F80 -:108910000E94E176809153079091540787319340EC -:1089200039F10E940BD88AEA99E10E94ACCE1093EB -:1089300057070E940FD860915307709154076456EF -:1089400071098CE29AE10E9487DA63EB72E084E2BB -:108950009AE10E9404DB8091020681114ECC809145 -:10896000570781114ACC0E94E2B847CC11E023CED0 -:10897000109257072091550730915607EF968EAD0C -:108980009FADEF9728173907C9F0109357070E943A -:108990000BD8EF966EAD7FADEF9784E09AE10E9421 -:1089A0007BDA60915507709156078FEF99E10E942D -:1089B0007BDA8FEE99E10E94ACCECDCF809102069A -:1089C0008111C9CF0E940FD889E393E00F94D62676 -:1089D00060915307709154076456710982ED99E1D3 -:1089E0000E9487DAC0905507D0905607F12CE12CF1 -:1089F00085EC99E10E94ACCEC701B6010F94C00D81 -:108A000082EC99E1D8CF84E690E09093540780936C -:108A1000530710925607109255070C94A6C081E098 -:108A2000809302060E9403C51092020681110C94E5 -:108A300003C50E947CB90E94648B0E940FD887EA0C -:108A400098E10E94ACCE80E008950F94D6268DE088 -:108A50000E949FCE8AE00C949FCECF93DF93C0916B -:108A60003606D091370681E0CE31D105E4F020E022 -:108A700030E040E05FE36091320670913306809110 -:108A80003406909135060F94083E0F94743F6C1B8A -:108A90007D0B77FF03C071956195710981E06330AB -:108AA00071050CF080E0DF91CF91089590E080E0B7 -:108AB0000895CF93DF93DB01F9019C919130C1F0D0 -:108AC000943080F094509C938830D1F480819181CF -:108AD000009771F0019791838083480F591FEA0135 -:108AE000188206C08C3539F49C5F9C93943041F415 -:108AF000DF91CF9108958B3339F781E08C93F8CFD4 -:108B000020813181B9016F5F7F4F71836083420F94 -:108B1000531FEA018883808191818F3591056CF71D -:108B2000E7CF0F931F9381E000919E1710919F173D -:108B30002091A0173091A11740919A1750919B173F -:108B400060919C1770919D1704171507260737072A -:108B500008F480E01F910F9108952091A1088330BF -:108B600021F425FD0CC024FD0CC030E0A90102C099 -:108B7000559547958A95E2F7CA018170089581E07D -:108B8000089580E008958091BC0884FD0BC0809119 -:108B9000BE0887FD07C09091BF08937081E019F46B -:108BA00080E0089581E008952FEB280F2A3108F026 -:108BB00047C0E22FF0E08091BC089091BD08A091E1 -:108BC000BE08B091BF0804C0B695A7959795879544 -:108BD0002A95D2F780FD02C081700895EE55F74FB7 -:108BE000E081EE2341F18091530990915409E80FFF -:108BF000F92FF11D808190ED980F9A3030F08E3270 -:108C000051F4818180538A3098F4F0939F08E09367 -:108C10009E0881E008958D3211F08B3249F48181F4 -:108C200090ED980F9A3088F38E3211F48281EACF5A -:108C3000F0E0E0E0EACF10929F0810929E08E9CFA2 -:108C400080E00895CF93DF93C0913606D091370628 -:108C5000209729F160913206709133068091340695 -:108C6000909135060F94743F6E5F7F4F24976C1779 -:108C70007D07ACF470930D0660930C060F941E1DD7 -:108C8000605A75418F4F9F4F60930E0670930F0689 -:108C90008093100690931106DF91CF910895109262 -:108CA0000E0610920F061092100610921106F4CFC5 -:108CB0002F923F924F925F926F927F928F929F92EC -:108CC000AF92BF92CF92DF92EF92FF920F931F93DA -:108CD000CF93DF93D62FC72FFC0180809180A28095 -:108CE000B380C501B40120E831E541E050E00F94C4 -:108CF000A43DC9016DE671E00F9434416B017C0124 -:108D0000C501B40120E13EE040E050E00F94A43DF5 -:108D1000CA01B90128E130E040E050E00F94A43DE1 -:108D2000362E272E062F172F8CE3482E512C612C20 -:108D3000712CC501B401A30192010F94A43DB62E7C -:108D4000A72ECA01B901A30192010F94A43DCB0142 -:108D5000C114D10479F1AF92BF927F936F932F9298 -:108D60003F92FF92EF92DF92CF928EE895E39F932E -:108D70008F93CF93DF930F9448398DB79EB70E969C -:108D80000FB6F8949EBF0FBE8DBF8D2F9C2FDF9125 -:108D9000CF911F910F91FF90EF90DF90CF90BF90F8 -:108DA000AF909F908F907F906F905F904F903F908B -:108DB0002F900895E114F104C9F0AF92BF927F9310 -:108DC0006F932F923F92FF92EF928EE795E39F93DE -:108DD0008F93CF93DF930F944839EDB7FEB73C964E -:108DE0000FB6F894FEBF0FBEEDBFCFCF012BB9F089 -:108DF000AF92BF927F936F932F923F9282E795E35A -:108E00009F938F93CF93DF930F9448398DB79EB77D -:108E10000A960FB6F8949EBF0FBE8DBFB6CF892BB2 -:108E2000A9F0AF92BF927F936F938AE695E39F93E9 -:108E30008F93CF93DF930F944839EDB7FEB73896F1 -:108E40000FB6F894FEBF0FBEEDBF9FCFAF92BF929B -:108E500086E695E39F938F93CF93DF930F944839E2 -:108E60000F900F900F900F900F900F908ECF8091DA -:108E70009E0890919F08009731F04AE050E070E022 -:108E800060E00D94D33760E070E0CB0108958091ED -:108E90009E0890919F08009731F04AE050E070E002 -:108EA00060E00D94A53660E070E0CB0108950E946B -:108EB00047C7CB0108950E9447C797FD0CC00E9489 -:108EC00047C76F3F71058105910509F034F40E9491 -:108ED00047C7862F089580E008958FEF0895809109 -:108EE0009E0890919F08892B41F00E945BC791E0FA -:108EF000811101C090E0892F089591E0FCCFCF92BD -:108F0000DF92EF92FF920F931F93CF93DF93CDB732 -:108F1000DEB72C970FB6F894DEBF0FBECDBFF09032 -:108F20008016E09081162091FA0321111DC042E9BC -:108F300057E36E2D8F2D0F94DD2590E080E0F80E25 -:108F4000F0928016E092811699272C960FB6F8942D -:108F5000DEBF0FBECDBFDF91CF911F910F91FF906C -:108F6000EF90DF90CF900895C0904D16D0904E16A0 -:108F700029E436E13A8329832F2D30E03C832B838B -:108F80002E2D30E03E832D8318861F827A876987D5 -:108F90001C861B8607EA18E29E012F5F3F4F41EABD -:108FA00054E2BC01C6010F945010B60189E496E169 -:108FB0000F9419258F819885C2CFCF92DF92EF92BF -:108FC000FF920F931F93CF93DF93CDB7DEB72C970C -:108FD0000FB6F894DEBF0FBECDBFF0908016E090C4 -:108FE00081162091FA0321111DC042E757E36E2D2F -:108FF0008F2D0F94DD2590E080E0F80EF092801622 -:10900000E092811699272C960FB6F894DEBF0FBE1A -:10901000CDBFDF91CF911F910F91FF90EF90DF9027 -:10902000CF900895C0904D16D0904E1629E436E1A9 -:109030003A8329832F2D30E03C832B832E2D30E083 -:109040003E832D8318861F827A8769871C861B863C -:1090500007EA18E29E012F5F3F4F44EA54E2BC0149 -:10906000C6010F945010B60189E496E10F941925BA -:109070008F819885C2CFCF93609136067091370665 -:10908000072E000C880B990B0F94B839C1E0209182 -:1090900032063091330640913406509135060F94D4 -:1090A000684018160CF0C0E08C2FCF9108958F9275 -:1090B0009F92AF92BF92CF92DF92EF92FF920F9367 -:1090C0001F93CF93DF931092C1081092C0082FE333 -:1090D0002093C4081092C3081092C2081092BC08D2 -:1090E0001092BD081092BE081092BF089C01F901B1 -:1090F00090812F5F3F4F9032D1F39E34C9F481812C -:1091000090ED980F9A3020F08D3211F08B3281F46F -:1091100032969F012F5F3F4F808180538A3008F441 -:109120006BC09F012F5F3F4F8081803209F466C082 -:10913000F0935409E09353098F010F5F1F4FC081D3 -:109140006AE270E0C8010F94E241009731F0FC013F -:10915000319780818032E1F31182CD3421F0C43522 -:1091600011F0C734E1F5F80180810F5F1F4F8032A5 -:10917000D1F380538A3098F5C093C40830E020E0E2 -:109180006AE0AF014F5F5F4F629FC001639F900D28 -:1091900011249C01205331098081280F311D87FD46 -:1091A0003A95FA01808180538A3058F33093C3088E -:1091B0002093C208DF0131968C918032D9F3CD34EF -:1091C00049F52E31310539F0D8F42731310519F040 -:1091D0002C313105F9F4B093C108A093C008DF9198 -:1091E000CF911F910F91FF90EF90DF90CF90BF90A4 -:1091F000AF909F908F900895F9018BCFF90191CF97 -:109200002537310538F02737310528F3203A83E038 -:10921000380709F3D091530940E050E0BA0110E05B -:1092200000E0C12CD12C7601C394FD0131968C91C4 -:10923000882309F47FC08132E1F4CD34D1F42032A7 -:109240003105B9F44093BC085093BD086093BE0843 -:109250007093BF08F093C108E093C00863E270E028 -:10926000CF010F94E241009709F4B9CFFC011082BD -:10927000B6CF81548A3108F058C0DF019D919032F9 -:1092800091F0A0EDA90FAA30E8F09E3271F491811F -:1092900090539A30B8F00115110519F48F0101505F -:1092A000110990E013C0FD01E8CF9D3211F09B320F -:1092B00091F79181A0EDA90FAA3020F09E3259F7C5 -:1092C0009281E6CF9E2F9D1B309759F3A82FB0E0D7 -:1092D0004601570104C0880C991CAA1CBB1C8A9526 -:1092E000D2F7482959296A297B29AE55B74F9C9353 -:1092F00080818154DF018A3108F497CFDF018191A9 -:10930000882309F492CF90ED980F9A30B8F393ED3B -:10931000980F923098F38B3289F3CD010196EC913E -:10932000E03209F082CFDC01F8CF0115110501F719 -:109330008D01DECF1093C1080093C0084093BC0894 -:109340005093BD086093BE087093BF0848CF0F9339 -:109350001F93CF9380919E0890919F080097E9F00A -:10936000FC018F01C1912C2F2F7D81F0C53411F0AC -:10937000C536B9F7F801108270E060E00F94473508 -:10938000F801C083CF911F910F91089570E060E0C4 -:10939000CF911F910F910D94473560E070E0CB01A4 -:1093A000F1CF0E94D4C5882341F081E020919E082E -:1093B00030919F08232B09F480E008954F925F922B -:1093C0006F927F92AF92BF92CF92DF92EF92FF9215 -:1093D0000F931F93CF938CE9A82E82E0B82E9AE8C2 -:1093E000E92E96E0F92E06E712E02DE6C22E2FE0D8 -:1093F000D22EC0E0F50181915F010E94D1C988237E -:1094000009F4A6C00E94A7C92B013C018C2F0E9421 -:10941000ADC5882309F492C0F801208131814281D1 -:109420005381C301B2010F94083EF7016083718339 -:1094300082839383CF5FF4E0EF0EF11C0C5F1F4F2C -:1094400084E0C80ED11CC330A9F685E40E94D1C9BE -:10945000882309F488C00E94A7C96B017C0183E0BE -:109460000E94ADC5882371F0209182023091830261 -:109470004091840250918502C701B6010F94083EC5 -:109480006B017C01C0929606D0929706E0929806F6 -:10949000F092990686E40F94841220E030E0A9014E -:1094A0000F946840181684F40E94A7C920E030E0A9 -:1094B00040E752E40F94023F6093510270935202CE -:1094C00080935302909354028091D40583FD28C069 -:1094D0008091D108882321F120918202309183026A -:1094E0004091840250918502609196067091970692 -:1094F00080919806909199060F94073E2091DE087E -:109500003091DF084091E0085091E1080F94083E47 -:109510006093DE087093DF088093E0089093E10881 -:10952000CF911F910F91FF90EF90DF90CF90BF9060 -:10953000AF907F906F905F904F900895F6012081DB -:10954000318142815381C301B2010F94073E6DCF37 -:10955000F80180819181A281B381F7018083918399 -:10956000A283B38367CF8091820290918302A091FE -:109570008402B09185028093960690939706A093FB -:109580009806B093990686CFCF93DF93EB010E94A4 -:10959000D1C9882321F0DF91CF910C9457C7CE0118 -:1095A000DF91CF910895CF93DF93EB010E94D1C952 -:1095B000882319F00E9447C7EB01CE01DF91CF91BC -:1095C0000895CF93DF93C82FD62F0E94D1C9882347 -:1095D00021F0DF91CF910C946FC78C2F0E94D4C5DE -:1095E000811101C08D2FDF91CF910895FF920F93CC -:1095F0001F93CF93DF93EC019A81A9812881AA233D -:1096000031F08A2F42E0AF3F21F441E001C040E059 -:1096100080E0222351F02F3F59F0882359F0622F28 -:1096200073E028130AC072E001C070E060E005C07A -:1096300071E0FCCF60E0822F72E0992309F44FC003 -:109640009F3FE9F18823E9F1981761F16623D9F189 -:10965000961799F1B0E0092F10E0FD01E01BF10B26 -:10966000F7FF03C0F195E195F109FE2E30E0FD0111 -:10967000E21BF30BF7FF03C0F195E195F1095E2FB3 -:10968000F801E21BF30BF7FF03C0F195E195F10937 -:10969000F51650F4FE16C8F49D01200F311F3695C3 -:1096A0002795822F92E01BC05E1788F0FE1678F097 -:1096B000200F311F36952795622F93E010C091E05F -:1096C0000EC0892FEFCF692FF8CF5E1788F72A0FCA -:1096D0003B1F36952795822F692F93E072E024E097 -:1096E000429FA0011124472B50E1959F9001112426 -:1096F000422B0F94D61988819981482F490F5527FD -:10970000551F8A81840F952F911D21E0833091058B -:109710000CF420E020930B0603974CF0888199818C -:10972000AA818093831690938416A0938516DF9167 -:10973000CF911F910F91FF9008958F929F92AF92BA -:10974000BF92CF92DF92EF92FF92CF93DF9300D040 -:10975000CDB7DEB72FEF8417950731F16A01052EDB -:10976000000CEE08FF084C01092E000CAA08BB08EB -:10977000681779072CF0CB01461757070CF4CA017C -:109780009C01990F440B550B281939094A095B09AB -:10979000AFEFB0E00F94E53DA70196012819390914 -:1097A0004A095B090F94C63D80913A06821759F029 -:1097B00020933A068FEF89831A8220952B83CE015E -:1097C00001960E94F6CA0F900F900F90DF91CF91F3 -:1097D000FF90EF90DF90CF90BF90AF909F908F90D1 -:1097E000089586E896E10C94F6CACF93DF9300D0F3 -:1097F000CDB7DEB719828FEF8A831B82CE01019627 -:109800000E94F6CA0F900F900F90DF91CF910895AC -:1098100083E896E10C94F6CACF93DF9300D0CDB7DE -:10982000DEB780910B06882369F019821A821B82A9 -:10983000CE0101960E94F6CA0F900F900F90DF9113 -:10984000CF9108950E9408CCF7CFCF92DF92EF928C -:10985000FF920F931F93CF9390911A02913009F4C6 -:1098600061C0662351F010927E0810927A0810921F -:109870007B0810927C0810927D08C82F0F941E1D43 -:10988000C0907A08D0907B08E0907C08F0907D082A -:109890009B01AC012C193D094E095F0969017A0150 -:1098A000F7FC40C020917E08C7FD15C04C2F0C2E40 -:1098B000000C550B4C5F5F4FE22F022E000CFF0B8C -:1098C0004E175F077CF144EFC42EDD24D394E12CC6 -:1098D000F12C2C1734F438EEC32E33E0D32EE12CC8 -:1098E000F12CC60ED71EE81EF91EC0927A08D0923F -:1098F0007B08E0927C08F0927D08022F017010E056 -:1099000084E2809FB001819F700D701B112460590B -:109910007C4F82E390E00E948D2B80917E088F5FC8 -:1099200080937E08CF911F910F91FF90EF90DF9071 -:10993000CF9008950F931F93CF93DF93082F10E0DC -:1099400097E1899FF0011124E15CF94FC085D18531 -:10995000209729F164817581868197810F94743FE6 -:109960006E5F7F4F24976C177D07CCF486E0809F55 -:10997000E001819FD00D1124CE5ED94F7983688399 -:109980000F941E1D605E714B8F4F9F4F6A837B83C8 -:109990008C839D83DF91CF911F910F91089586E075 -:1099A000809FF001819FF00D1124EE5EF94F12822D -:1099B000138214821582EECFE62FF0E027E1629F3A -:1099C000D0011124A15CB94FEE0FFF1FE054FD4FF1 -:1099D000208131812F503109821793070CF49C01AB -:1099E00019963C932E931897862F0C949ACCAC0121 -:1099F0008091A00881110EC09091010491110BC0BB -:109A000020916002309161022150310981E04217BA -:109A100053070CF080E0089597E1899FF00111242D -:109A2000E15CF94F20E030E040E05FE36481758164 -:109A3000868197810F94083E0F94743FCB010C945C -:109A4000F7CCCF92DF92EF92FF926B017C0183E320 -:109A5000C816D104E104F10470F082E3C81AD108F9 -:109A6000E108F10862E370E080E090E00F94911C5F -:109A70000E94A591ECCFC701B6010F94911CFF90F5 -:109A8000EF90DF90CF900C94A591809151090E94A6 -:109A9000E48964E670E080E090E00C9421CD809150 -:109AA000860F813069F09091A21792FB882780F988 -:109AB00092FF07C097FB882780F991E089270895D6 -:109AC00081E008958091091690910A16891B8F7084 -:109AD00031F480919A06811104C00C944FCD81E03D -:109AE000089580E008959091A21794FB882780F94B -:109AF00094FF06C081E090915314911101C080E061 -:109B0000089580919A06811110C08091860F82304D -:109B100061F00E9473CD882349F08091A21782FBE7 -:109B2000882780F991E08927089581E00895E2ED82 -:109B3000F5E010821182089581E00895CF93DF93BC -:109B4000EC01E62F660FFF0BE151F84CE491E25077 -:109B5000E13108F0B0C0F0E08827EE54F2438F4FB7 -:109B60000D945C41C3CD5BCE5BCE5BCE5BCEEDCDC9 -:109B7000CFCD11CE0FCEEFCD35CE33CE13CE5BCEC3 -:109B800059CE57CE37CE82E1E5E4F3E0DE01019015 -:109B90000D928A95E1F7CE01DF91CF91089581E092 -:109BA00020EB30E03983288321EB30E03B832A83AC -:109BB0001D821C8223EB30E03F832E8324EB30E0B8 -:109BC000398728871B861A861D861C8692E09E8709 -:109BD0008F8781E0888B198ADECF80E0E1CF81E03A -:109BE0008F5F20E930E03983288321E930E03B832F -:109BF0002A8322E930E03D832C8328E930E03F834B -:109C00002E832AE930E0398728872CE930E03B872A -:109C10002A8726E930E03D872C8793E0D8CF80E083 -:109C2000DFCF80E0DECF81E08F5F20EA30E0398354 -:109C3000288321EA30E03B832A8322EA30E03D8317 -:109C40002C8328EA30E03F832E832AEA30E03987EC -:109C500028872CEA30E03B872A8726EA30E03D87D8 -:109C60002C8794E0B4CF80E0DFCF80E0DECF81E0CE -:109C70008F5F20E231E03983288321E231E03B83AA -:109C80002A8322E231E03D832C8328E231E03F83C6 -:109C90002E832AE231E0398728872CE231E03B87A6 -:109CA0002A8726E231E03D872C8795E090CF80E03F -:109CB000DFCF80E0DECF82E1FE0111928A95E9F7E5 -:109CC0006ACF8F929F92AF92BF92CF92DF92EF9224 -:109CD000FF920F93CF93DF931F92CDB7DEB75C0156 -:109CE0007B0149016B01C40ED51EF5018081918174 -:109CF0000F947E3D8983002311F0F7018083BE011C -:109D00006F5F7F4FC4010F94C40AF5018081918178 -:109D1000019691838083FFEFEF1AFF0AEC14FD0494 -:109D200021F780E00F90DF91CF910F91FF90EF909E -:109D3000DF90CF90BF90AF909F908F9008959091BB -:109D4000C00095FFFCCF8093C600089585E40E9473 -:109D50009FCE81E30C949FCECF93DF93EC01FE0165 -:109D600084912196882319F00E949FCEF8CFDF912D -:109D7000CF9108950F931F93CF938C01C62F89E63F -:109D800092E30E94ACCEC8010E94ACCE8AE30E944E -:109D90009FCE80E38C0F0E949FCE8AE0CF911F91CF -:109DA0000F910C949FCE89E594E30E94ACCE60E0C5 -:109DB00089E494E30E94BACE60E084E394E30E94D5 -:109DC000BACE61E08DE294E30E94BACE61E082E215 -:109DD00094E30E94BACE60E083E194E30E94BACE9D -:109DE00061E083E094E30E94BACE60E08AEF93E3FF -:109DF0000E94BACE61E080EF93E30E94BACE60E0A9 -:109E000086EE93E30E94BACE60E08FED93E30E946A -:109E1000BACE60E087ED93E30E94BACE60E089ECB1 -:109E200093E30E94BACE60E08BEB93E30E94BACE3C -:109E300060E08CEA93E30E94BACE60E08EE993E39F -:109E40000E94BACE60E088E893E30E94BACE60E058 -:109E500087E793E30E94BACE60E082E693E30E9434 -:109E6000BACE60E083E593E30E94BACE61E08CE471 -:109E700093E30E94BACE60E08FE393E30E94BACEF0 -:109E800060E088E393E30E94BACE61E08FE293E35F -:109E90000E94BACE60E08AE193E30E94BACE60E00D -:109EA0008CE093E30E94BACE60E082E093E30E94EC -:109EB000BACE60E08BEE92E30E94BACE60E08EED07 -:109EC00092E30E94BACE61E08BEC92E30E94BACE9C -:109ED00060E08EEB92E30E94BACE61E089EB92E300 -:109EE0000E94BACE60E08CEA92E30E94BACE60E0B3 -:109EF00088E992E30E94BACE60E085E892E30E948E -:109F0000BACE60E08BE89FE00E9456C5682F617072 -:109F10008CE792E30E94BACE60E08EE692E30C9466 -:109F2000BACEE091761081E6E89FF0011124E85264 -:109F3000FF4E8081811107C08AEA9AE30E94ACCE6D -:109F40008AE00C949FCE0895CF92DF92EF92FF9219 -:109F50006A017B010E94ACCE42E0C701B601FF90CE -:109F6000EF90DF90CF900C94FA834F925F926F92B4 -:109F70007F928F929F92AF92BF92CF92DF92EF9299 -:109F8000FF92CF93DF93CDB7DEB72C970FB6F8943F -:109F9000DEBF0FBECDBF83E50E94D4C58823C9F0C4 -:109FA0000E946FC7809337022C960FB6F894DEBFDD -:109FB0000FBECDBFDF91CF91FF90EF90DF90CF909C -:109FC000BF90AF909F908F907F906F905F904F90D9 -:109FD000089562E97DE281E00F94291280913702B1 -:109FE000805D898389E89DE20E94ACCE89810E94D0 -:109FF0009FCE85E89DE20E94ACCE80913702811110 -:10A00000C6C08CE69DE20E94ACCE8AE00E949FCE44 -:10A0100040906D0F50906E0F60906F0F7090700FAA -:10A020002091390230913A0240913B0250913C021A -:10A03000C301B2010F94083E69837A838B839C83AA -:10A040008090710F9090720FA090730FB090740F6A -:10A0500020913D0230913E0240913F0250914002DA -:10A06000C501B4010F94083E6D837E838F8398876A -:10A07000C090750FD090760FE090770FF090780F2A -:10A08000209141023091420240914302509144029A -:10A09000C701B6010F94083E69877A878B879C8732 -:10A0A000209145023091460240914702509148026A -:10A0B000C301B2010F94083E2B013C0120914902DB -:10A0C00030914A0240914B0250914C02C501B401BB -:10A0D0000F94083E4B015C0120914D0230914E02DD -:10A0E00040914F0250915002C701B6010F94083EB3 -:10A0F0006B017C018DE79DE20E94ACCE49815A81C3 -:10A100006B817C818EE499E10E94A4CF4D815E81B8 -:10A110006F8178858FE09CE30E94A4CF49855A85A2 -:10A120006B857C858CE09CE30E94A4CF8BE79DE24D -:10A130000E94ACCE83E79DE20E94ACCEB301A201A7 -:10A140008EE499E10E94A4CFB501A4018FE09CE3C5 -:10A150000E94A4CFB701A6018CE09CE30E94A4CF8B -:10A160008AE02C960FB6F894DEBF0FBECDBFDF910C -:10A17000CF91FF90EF90DF90CF90BF90AF909F90E6 -:10A180008F907F906F905F904F900C949FCE80E760 -:10A190009DE239CF0E94A4CF8AE00C949FCE2F92EB -:10A1A0003F924F925F926F927F928F929F92AF9267 -:10A1B000BF92CF92DF92EF92FF920F931F93CF93B4 -:10A1C000DF93CDB7DEB7CE55D1090FB6F894DEBF19 -:10A1D0000FBECDBF70E060E085E40E94C4CA082FC6 -:10A1E0008EA3823008F042C083E40E94D1C981115D -:10A1F0005FC025E02BAB83E50E94D1C9882309F419 -:10A200005BC00E9457C79A8B898B60E085E50E94EE -:10A21000E1CA2F968FAF2F9760E085E697E30E9403 -:10A220001D3B0F941E1D6B8B7C8B8D8B9E8BE02EAC -:10A23000002E000CFF08F701A3E0EE0FFF1FAA9508 -:10A24000E1F7EC59FD4F868197810E9789889A88AE -:10A2500088169906B4F188E597E30E94ACCE89E3AD -:10A2600097E30E94ACCE0F948E1008C08AEE95E35F -:10A270000E94ACCE82ED95E30E94ACCEC25ADF4F75 -:10A280000FB6F894DEBF0FBECDBFDF91CF911F9107 -:10A290000F91FF90EF90DF90CF90BF90AF909F9085 -:10A2A0008F907F906F905F904F903F902F90089588 -:10A2B0000E9457C78BAB9FCF48EC50E05A8B498B1D -:10A2C000A4CF2B893C894D895E89205E314B4F4F4D -:10A2D0005F4F27962CAF3DAF4EAF5FAF27978CE215 -:10A2E00097E30E94ACCE84E297E30E94ACCE0E943A -:10A2F000B48587E18E9D90018F9D300D1124A901B9 -:10A30000415C594F5A019FE7DA011A969C93089FC6 -:10A3100080011124F801E15CF94F4F01248135815E -:10A320004681578163962CAF3DAF4EAF5FAF6397C9 -:10A3300010923A060E9479862B966DAF7EAF8FAF52 -:10A340002B9760E089E197E30E941D3B81E08093B9 -:10A3500074022B893C894D895E892FA338A749A7B0 -:10A360005AA72AAF3BAF4CAF5DAF1FA618AA19AAD8 -:10A370001AAA1BA61CA61DA61EA61F821886198631 -:10A380001A868FE790E0A0E0B0E08F8B988FA98FBE -:10A39000BA8F1D8690E49C8FACE1AD8FB6E4BE8F82 -:10A3A0001F8E18A219A21AA2FFE7CF2ED12CE12CE2 -:10A3B000F12C1EAE23961CAE1DAE1EAE1FAE239713 -:10A3C0001EAA1FAA18AE19AEE1E0EB8F1C861B86F1 -:10A3D00010E000E0212C312C94012C5F3F4F3DAB6D -:10A3E0002CABA501465F5F4F2D965FAF4EAF2D970B -:10A3F00089899A894E964C01990FAA08BB086796DD -:10A400008CAE9DAEAEAEBFAE679789899A894E97E6 -:10A410004C01990FAA08BB086B968CAE9DAEAEAEF0 -:10A42000BFAE6B9789899A8906974C01990FAA0844 -:10A43000BB086F968CAE9DAEAEAEBFAE6F978091EF -:10A440007402882309F421C20F941E1D2B013C01C4 -:10A4500090902D0628969FAE2897992009F4FEC16A -:10A460000E94E59010922D06ACA9BDA91C911196F1 -:10A470000C91119712962C90129713963C902F8D59 -:10A4800038A149A15AA1612F702FC1010F946840D2 -:10A49000181624F41F8F08A329A23AA22D853C8DFB -:10A4A0004D8D5E8D612F702FC1010F94B13987FFE3 -:10A4B00004C01D870C8F2D8E3E8E612F702FC10121 -:10A4C0000F94743F4B0163966CAD7DAD8EAD9FAD27 -:10A4D00063970F94743FCB0149895A89B4010E9454 -:10A4E0009DCBE989FA894F01FF0FAA08BB08FB8DB4 -:10A4F000FF2309F449C0C501B4010F94B8396BA317 -:10A500007CA38DA32E969FAF2E979B01AC01612F4C -:10A51000702FC1010F94684018160CF09FC1B30151 -:10A52000A2018FA198A5A9A5BAA5481B590B6A0B32 -:10A530007B0BDB01CA0188589341A109B109B7FD22 -:10A540008DC18F89988DA98DBA8D8C199D09AE0901 -:10A55000BF09B595A795979587952D96EEADFFAD5B -:10A560002D9780834EAB5FAB68AF79AFFBA1FF8FB8 -:10A570002CA128A33DA139A32E964FAD2E974AA317 -:10A580004B8A5C8A6D8A7E8AC501B4010F94B83902 -:10A590006B8F7BA38CA39DA39B01AC01612F702FBC -:10A5A000C1010F94B13987FD02C01B8E57C1D30181 -:10A5B000C2018B889C88AD88BE8888199909AA0930 -:10A5C000BB09AC01BD01485853416109710977FDD0 -:10A5D000ECCFAB84BC84AB2809F4FEC08EA89FA846 -:10A5E000A8ACB9AC880E991EAA1EBB1E2EA93FA905 -:10A5F00048AD59AD281B390B4A0B5B0BC701B6019F -:10A600000F94943DA50194010F94C63DCF88D88C3A -:10A61000E98CFA8CC20ED31EE41EF51E24E1C2168C -:10A62000D104E104F1040CF445C13CEEC316D1049D -:10A63000E104F1040CF038C140E8C416D104E1048F -:10A64000F1040CF445C1CF8AD88EE98EFA8E8EEFD4 -:10A6500090E0A0E0B0E09C01AD012C193D094E094D -:10A660005F0969017A0181E197E30E94ACCE6F89AD -:10A67000788D898D9A8D0F942A0E8CE097E30E9435 -:10A68000ACCEC701B6010F942A0E4D855C8D6D8D41 -:10A690007E8D85E097E30E94A4CF4F8D58A169A1DC -:10A6A0007AA18EEF96E30E94A4CFAB85BC85139769 -:10A6B0000CF492C0C701B6010F94B83920E030E025 -:10A6C00040E850E40F94173A6F83788789879A8718 -:10A6D0002D853C8D4D8D5E8D6F8D78A189A19AA1C0 -:10A6E0000F94073E2BED3FE049E450E40F94173AF6 -:10A6F00020E030E040E05FE30F94173A9B01AC01AB -:10A700006F81788589859A850F94023F6D877E8752 -:10A710008F87988BC501B4010F94B8392FE632E1C9 -:10A7200043E85AE30F94173A4B015C012AE939E9EF -:10A7300049E15FE36D857E858F8598890F94173A8F -:10A740006F83788789879A879B01AC010F94083EB5 -:10A75000A50194010F94023F6BA77CA78DA79EA72C -:10A760002F81388549855A85C501B4010F94173A60 -:10A7700020E030E040E05EE30F94173A6FA778AB3B -:10A7800089AB9AAB4D855E856F85788988EF96E3B6 -:10A790000E94A4CFB501A40182EF96E30E94CAD023 -:10A7A00083EE96E30E94ACCE4F81588569857A8509 -:10A7B0008DED96E30E94A4CF4BA55CA56DA57EA56B -:10A7C00087ED96E30E94A4CF4FA558A969A97AA95D -:10A7D00081ED96E30E94CAD08F89988DA98DBA8D9C -:10A7E0008C0D9D1DAE1DBF1DB595A79597958795A1 -:10A7F0002D96EEADFFAD2D9780838BA8882D082C6C -:10A80000000C990B9F938F929C849F92AB84AF9284 -:10A810008DEB96E39F938F9388EC96E39F938F93B2 -:10A820001F920E94FA3A2B853C852F5F3F4F3C8751 -:10A830002B870FB6F894DEBF0FBECDBF8B8C8D86F5 -:10A840009BA09C8EACA0AD8EBDA0BE8E4FA258A684 -:10A8500069A67AA628968FAC28978B8E67966CADE2 -:10A860007DAD8EAD9FAD67970F94B839212F302FF6 -:10A87000A1010F94B13987FF30C080EB96E30E94AD -:10A88000ACCE81E996E30E94ACCE109274020E9495 -:10A89000B4852B968DAC9EACAFAC2B978C829D82F1 -:10A8A000AE82CE0104963AC14BEEC42ED12CE12CDF -:10A8B000F12CC9CE84E190E0A0E0B0E08F8B988FBE -:10A8C000A98FBA8F34E1C32ED12CE12CF12CCBCE41 -:10A8D000CF8AD88EE98EFA8EC6CED301C2018AAC59 -:10A8E0009BACACACBDAC88199909AA09BB09B7FDF2 -:10A8F0004DC08EA10E949E848AE00E949FCEA3013B -:10A9000092012053384F4F4F5F4F2AAF3BAF4CAFB0 -:10A910005DAF8EAC811072C023962CAD3DAD4EADB7 -:10A920005FAD2397612F702FC1010F9468401816F7 -:10A930000CF04EC020E030E040E050E4612F702F7A -:10A94000C1010F94083E23966CAF7DAF8EAF9FAFD1 -:10A950002397A3019201205E314B4F4F5F4F279603 -:10A960002CAF3DAF4EAF5FAF27976F966CAD7DAD0F -:10A970008EAD9FAD6F970F94B839212F302FA10165 -:10A980000F94B139881F8827881F8EAF8B899C89C7 -:10A99000AD89BE898FA098A4A9A4BAA488169906E7 -:10A9A000AA06BB0610F4D501C401481A590A6A0A5E -:10A9B0007B0A21E842162FE4520622E16206710466 -:10A9C00098F184E896E30E94ACCE82E796E35BCFF1 -:10A9D000D301C20127968CAC9DACAEACBFAC27971F -:10A9E00088199909AA09BB094AE053E269E173E2AF -:10A9F000B7FDCCCF8EA10E94908FC8CF6B966CAD67 -:10AA00007DAD8EAD9FAD6B970F94B8399B01AC01B6 -:10AA1000612F702FC1010F94B13987FFB7CF47E481 -:10AA200053E267E573E2E6CF8BA8882D880C990B7B -:10AA3000AB84BC848A159B050CF073C09501233050 -:10AA400031050CF46EC085E696E30E94ACCE84E13D -:10AA500096E30E94ACCE87EF95E30E94ACCE4F8187 -:10AA6000588569857A8580E196E30E94CAD087EF90 -:10AA700095E30E94ACCE4BA55CA56DA57EA58CE0B0 -:10AA800096E30E94CAD087EF95E30E94ACCE4FA513 -:10AA900058A969A97AA988E096E30E94CAD02F969E -:10AAA0008FAC2F97882081F18F809884A984BA84F5 -:10AAB00080924A0690924B06A0924C06B0924D06A8 -:10AAC0002CEA35EC47E25EE36BA57CA58DA59EA53F -:10AAD0000F94173A60934E0670934F06809350067A -:10AAE000909351062CEA35EC47E25EE36FA578A916 -:10AAF00089A99AA90F94023F609352067093530656 -:10AB000080935406909355062B968DAC9EACAFACBB -:10AB10002B9789829A82AB82CE0101960E94F6CA57 -:10AB2000A2CB0E94446B8BCCCF93DF936DE572E395 -:10AB30000F942912C6EED8E0488159816A817B8141 -:10AB400084E592E30E94A4CF4C815D816E817F8178 -:10AB50008FE09CE30E94A4CF488559856A857B8558 -:10AB60008CE09CE3DF91CF910C94CAD060ED7CE245 -:10AB70000F942912609165097091660980916709A7 -:10AB8000909168090F94B639AB01BC0187EC9CE247 -:10AB90000E94A4CF40919509509196096091970920 -:10ABA0007091980984EC9CE20E94A4CF409199098D -:10ABB00050919A0960919B0970919C0981EC9CE2EB -:10ABC0000E94A4CF4091FE055091FF0560910006C0 -:10ABD000709101068EEB9CE20C94CAD0CF93DF9368 -:10ABE00064E77CE20F942912C5E5D9E04CA95DA980 -:10ABF0006EA97FA98BE69CE20E94A4CF48AD59AD17 -:10AC00006AAD7BAD88E69CE20E94A4CF4CAD5DAD01 -:10AC10006EAD7FAD81EC9CE2DF91CF910C94CAD0F8 -:10AC2000CF93DF9360E57CE20F942912C5E5D9E06C -:10AC30004CA15DA16EA17FA187E49CE20E94A4CFFC -:10AC400048A559A56AA57BA58FE09CE30E94A4CFE7 -:10AC50004CA55DA56EA57FA58CE09CE30E94A4CFCA -:10AC600048A959A96AA97BA989E09CE3DF91CF9102 -:10AC70000C94CAD0CF93DF936BE27CE20F9429123D -:10AC8000C5E5D9E0688179818A819B810F94B639C5 -:10AC9000AB01BC0182E29CE20E94A4CF6C817D8169 -:10ACA0008E819F810F94B639AB01BC018FE09CE38C -:10ACB0000E94A4CF688579858A859B850F94B639D3 -:10ACC000AB01BC018CE09CE30E94A4CF6C857D8528 -:10ACD0008E859F850F94B639AB01BC0189E09CE35A -:10ACE000DF91CF910C94CAD0CF93C62F0E94ACCEE7 -:10ACF0006C2F70E090E080E0CF910D94C00D0E9429 -:10AD000074D68AE00C949FCE69E375E30F94291200 -:10AD100060912E0280E395E30C947FD66CE27DE295 -:10AD20000F94291285E29DE20E94ACCE40918606E6 -:10AD30005091870660918806709189068CE09CE3AB -:10AD40000C94CAD0CF93C62F0E94ACCE6C2FCC0FE0 -:10AD5000770B880B990BCF910D942A0EEF92FF92EF -:10AD60000F931F93CF93DF9361E87FEF8FE40E94EF -:10AD7000C4CAD82F813879F18FEF8D0F8F3058F1F9 -:10AD800080E79FE20E94ACCE11E061E87FEF80E5B2 -:10AD90000E94C4CAC82F813849F083E08C0F8031EB -:10ADA00028F086E59FE20E94ACCE11E061E87FEFDB -:10ADB00083E50E94C4CA813881F09FEF980F9830D4 -:10ADC00060F08EE39FE2DF91CF911F910F91FF9092 -:10ADD000EF900C94ACCE10E0D8CF111115C1D13842 -:10ADE00009F4D3E0C13809F4CFEF182F813809F402 -:10ADF00011E08CE9E82E82E0F82E00E081E0F70116 -:10AE000091917F0191544091BC085091BD0860918F -:10AE1000BE087091BF0804C0769567955795479511 -:10AE20009A95D2F740FF19C06D2F023009F4C3C0C4 -:10AE3000033009F4CDC0013009F4B0C08FEA95E1C8 -:10AE40000F94EA216C2F8FEA95E10F94F020612F87 -:10AE50008FEA95E10F94DF2080E00F5F043079F6F0 -:10AE6000882309F4D1C088E50E949FCE8FEA95E13E -:10AE70000F94E521682F8DE99EE20E9474D68FEA37 -:10AE800095E10F94E720682F84E99EE20E94A2D604 -:10AE90008FEA95E10F94D620682F8AE89EE20E94FF -:10AEA0007FD689E50E949FCE83E795E10F94E52147 -:10AEB000682F81EC9EE20E9474D683E795E10F949F -:10AEC000E720682F88EB9EE20E94A2D683E795E1F7 -:10AED0000F94D620682F8EEA9EE20E947FD68AE5E4 -:10AEE0000E949FCE87E395E10F94E521682F85EEC0 -:10AEF0009EE20E9474D687E395E10F94E720682FC5 -:10AF00008CED9EE20E94A2D687E395E10F94D620B5 -:10AF1000682F82ED9EE20E947FD685E40E949FCE3C -:10AF20008BEF94E10F94E521682F89E09FE20E9466 -:10AF300074D68BEF94E10F94E720682F80E09FE2B6 -:10AF40000E94A2D68BEF94E10F94D620682F86EF53 -:10AF50009EE20E947FD60E94A6CE8FEB94E10F94D2 -:10AF6000E521682F8DE29FE20E9474D68FEB94E179 -:10AF70000F94E720682F84E29FE20E94A2D68FEB15 -:10AF800094E10F94D620682F8AE19FE2DF91CF9160 -:10AF90001F910F91FF90EF900C947FD683E795E17E -:10AFA0000F94EA216C2F83E795E10F94F020612F35 -:10AFB00083E795E14FCF87E395E10F94EA216C2F6A -:10AFC00087E395E10F94F020612F87E395E142CF6D -:10AFD0008BEF94E10F94EA216C2F8BEF94E10F94A7 -:10AFE000F020612F8BEF94E10F94DF206D2F8FEB1A -:10AFF00094E10F94EA216C2F8FEB94E10F94F020F1 -:10B00000612F8FEB94E126CFDF91CF911F910F91AC -:10B01000FF90EF90089585E79AE20C94ACCE8FE60E -:10B020009AE20C94ACCECF9384E50E94D1C9C09132 -:10B0300051098823D9F00E945BC7C82F8230B4F031 -:10B040000E940FD88DE40E949FCE6091C20870913B -:10B05000C30890E080E00F94C00D6C2F8CE89FE255 -:10B060000E94A2D68AE00E949FCECFEF8C2FCF9174 -:10B0700008954F925F926F927F928F929F92AF92BC -:10B08000BF92CF92DF92FF920F931F93CF93DF93E4 -:10B090009091D40593FD13C1D82F0E9413D8C82FC7 -:10B0A00087FD0DC189E40E94D1C9882309F47CC0C1 -:10B0B0000E945BC790E01816190614F481E090E036 -:10B0C00026E0289FF001299FF00D1124EE50FA4F41 -:10B0D00080819181F12C6C2F0E94DCCC61E08D2F5E -:10B0E0000E94DEBB0C2F0C2E000C110B37E1C302AB -:10B0F000C0011124FC01E15CF94F6F01608571858D -:10B10000072E000C880B990B0F94B8394B015C018A -:10B11000F6014480558066807780A30192010F94E8 -:10B120006840181614F0F11039C00F5C1F4FD11190 -:10B13000BAC0A3019201C501B4010F94684018166A -:10B140000CF084C0DD24D39489E197E39F938F931F -:10B150001F930F938DEA95E39F938F931F920E9405 -:10B16000FA3A2DB73EB7295F3F4F0FB6F8943EBF6E -:10B170000FBE2DBFDD2041F0C09339068DE490E76E -:10B18000909318128093171211E017C082E50E9465 -:10B19000D1C9882389F00E9457C79DCF1F2D0DC0AC -:10B1A00060E070E0CB0126C083E50E94D1C9F82E93 -:10B1B0008111F1CFD111EACF10E083E50E94D1C90E -:10B1C000882331F00E9457C7909319028093180288 -:10B1D00082E40E94D1C9882331F00E9457C790931E -:10B1E00017028093160286E40E94D4C58823C1F218 -:10B1F0000E94A7C9609312027093130280931402F5 -:10B200009093150201E020E030E0A9010F94B139DC -:10B21000811101C000E000936D06DD2309F44FC0E9 -:10B22000112309F44CC06F2D8C2FDF91CF911F910A -:10B230000F91FF90DF90CF90BF90AF909F908F9035 -:10B240007F906F905F904F900C94888682EA95E390 -:10B250009F938F931F930F938DEA95E39F938F9303 -:10B260001F920E94FA3A2DB73EB7295F3F4F0FB6A3 -:10B27000F8943EBF0FBE2DBF7FCF89E197E39F9328 -:10B280008F931F930F938DEA95E39F938F931F9254 -:10B290000E94FA3A8DB79EB707960FB6F8949EBFF4 -:10B2A0000FBE8DBF71CFA3019201C501B4010F94F0 -:10B2B0006840181614F3D12C82EA95E347CFDF914A -:10B2C000CF911F910F91FF90DF90CF90BF90AF90E3 -:10B2D0009F908F907F906F905F904F9008950F9305 -:10B2E0001F93CF93811116C0C42F8B010E940FD8DA -:10B2F00089E89FE20E94ACCEC8010E94ACCECC236C -:10B3000049F08AE30E949FCE8AE0CF911F910F916E -:10B310000C949FCECF911F910F910895811102C07F -:10B320000C940FD808951F93CF93DF93D82F162F27 -:10B3300041E061E67DE20E946FD9C0E01C1711F088 -:10B340001F3FD1F58D2F0E948ED940914A06509112 -:10B350004B0660914C0670914D0688E59DE20E9477 -:10B36000A4CF2CEA35EC47E25EE360914E06709183 -:10B370004F0680915006909151060F94023FAB0109 -:10B38000BC0185E59DE20E94A4CF2CEA35EC47E2A2 -:10B390005EE360915206709153068091540690913D -:10B3A00055060F94173AAB01BC0182E59DE20E945D -:10B3B000A4CF8AE00E949FCEC13021F4DF91CF91CB -:10B3C0001F910895C1E0BACFCF93DF93C82F63E4F4 -:10B3D0007DE20F9429128C2F0E948ED961E08AE3BE -:10B3E0009DE20E9474D6CEE6D6E04C855D856E85E2 -:10B3F0007F858EE499E10E94A4CF488959896A89A2 -:10B400007B898FE09CE30E94A4CF8CE09CE30E94A8 -:10B41000ACCE6C897D898E899F8943E00E94FA8336 -:10B420008AE0DF91CF910C949FCECF93DF93C82F0A -:10B43000811113C040E060E17CE280E00E946FD99E -:10B440008091F105811104C083E09CE20E94ACCEA2 -:10B450008AE00E949FCE0E940FD8D091F1058AEF1A -:10B460009BE20E94ACCE6D2F70E090E080E00F94E4 -:10B470002A0E8AE00E949FCE8C2F0E948ED960E017 -:10B4800081EF9BE20E94A2D64091E9055091EA0526 -:10B490006091EB057091EC058EEE9BE20E94CAD0A4 -:10B4A0008C2F0E948ED961E081EF9BE20E94A2D690 -:10B4B0004091ED055091EE056091EF057091F0051A -:10B4C0008EEE9BE2DF91CF910C94CAD0CF93C82F20 -:10B4D0004091510982E0C11184E060E00E94092E90 -:10B4E0000E940FD88DE89AE2CC2311F085EA9AE207 -:10B4F000CF910C94ACCECF93DF93EB010E94ACCEF6 -:10B50000BE0190E080E0DF91CF910D94C00DCF930C -:10B51000DF93EB010E94ACCEBE01DD0F880B990BCF -:10B52000DF91CF910D942A0E5F926F927F928F924E -:10B530009F92AF92BF92CF92DF92EF92FF920F93C2 -:10B540001F93CF93DF931F92CDB7DEB77C013901F4 -:10B550008B015B01A40EB51ED12CC12CA016B10627 -:10B5600009F450C0F70180809180F80151908F015B -:10B570005982C4010F947E3D5816B9F1652DC4015E -:10B580000F94863DFFEFCF1ADF0AC6018F77992708 -:10B59000892B21F162E070E080E090E00F94911C33 -:10B5A000C4010F947E3D99818917F9F00E940FD84C -:10B5B00085EF97E20E94ACCE81E00F90DF91CF91B2 -:10B5C0001F910F91FF90EF90DF90CF90BF90AF90C1 -:10B5D0009F908F907F906F905F90089562E070E0F1 -:10B5E00080E090E00E9421CDDBCFBE016F5F7F4FF6 -:10B5F000C3010F94C40AF701808191810196918360 -:10B600008083ACCF80E0D9CF0E947BDA8AE00C94B3 -:10B610009FCE0E94ACCE8AE00C949FCEEF92FF9218 -:10B620001F93CF93DF9383E50E94D4C5882309F449 -:10B6300045C06EEF7FEF84E50E94C4CA182F8230A8 -:10B6400008F01EEF0E946FC7D82F8CE9E82E82E029 -:10B65000F82EC0E0F70181917F010E94D4C58823B4 -:10B6600051F0C23089F0C330A1F0C13041F0D09325 -:10B67000EA150F940112CF5FC43061F719C0D0935F -:10B68000AE150F940912F7CFD09372150F941112C3 -:10B69000F2CF11163CF4113059F4D093FA140F94F0 -:10B6A0002112E9CFD09336150F9419121111F5CF4D -:10B6B000DF91CF911F91FF90EF90089588E50E9450 -:10B6C0009FCE8FED9DE20E94ACCE8FEA95E10F9464 -:10B6D000C221882309F44CC087EC9DE20E9409DB5B -:10B6E00089E50E949FCE86E09EE20E94ACCE83E771 -:10B6F00095E10F94C2218823F1F18EEE9DE20E9424 -:10B7000009DB8AE50E949FCE8DE29EE20E94ACCECC -:10B7100087E395E10F94C221882381F185E19EE2C0 -:10B720000E9409DB85E40E949FCE84E59EE20E9490 -:10B73000ACCE8BEF94E10F94C221882311F18CE3FE -:10B740009EE20E9409DB0E94A6CE8BE79EE20E9449 -:10B75000ACCE8FEB94E10F94C2218823A9F083E64D -:10B760009EE2DF91CF911F91FF90EF900C9409DB47 -:10B7700083ED9DE2B3CF8AEF9DE2C1CF81E29EE2ED -:10B78000CFCF88E49EE2DDCF8FE69EE2EACF0F9333 -:10B790001F93CF93DF93082F41E062EB7DE20E947D -:10B7A0006FD9C9EDD5E010E0802F0E948ED9612FAE -:10B7B00089EA9DE20E94A2D64C815D816E817F81E3 -:10B7C00086EA9DE20E94A4CF488159816A817B81EB -:10B7D00083EA9DE20E94A4CF80EA9DE20E94ACCE63 -:10B7E0008DED98E10E9409DB2896113029F4DF9154 -:10B7F000CF911F910F91089511E0D6CFFF920F9333 -:10B800001F93CF93DF93F62E042F122F882329F155 -:10B810008CE09BE20E94ACCE88E50E949FCE8CEF2C -:10B820009AE20E94ACCE8FEA95E10F94F820D82FCF -:10B83000882361F080EF9AE20E94ACCE88EE9AE213 -:10B84000D13031F084EE9AE2D23011F08DEE9AE2EE -:10B850000E9409DBC1E0D11101C0C0E0FF2039F135 -:10B860008DE39BE20E94ACCE89E50E949FCE8DE2E3 -:10B870009BE20E94ACCE83E795E10F94F820D82F8D -:10B88000882361F081E29BE20E94ACCE89E19BE2D9 -:10B89000D13031F085E19BE2D23011F08EE19BE2B4 -:10B8A0000E9409DB81E0D11101C080E0C80F0023B4 -:10B8B00039F18EE69BE20E94ACCE8AE50E949FCED3 -:10B8C0008EE59BE20E94ACCE87E395E10F94F820D1 -:10B8D000D82F882361F082E59BE20E94ACCE8AE4F7 -:10B8E0009BE2D13031F086E49BE2D23011F08FE45C -:10B8F0009BE20E9409DB81E0D11101C080E0C80F0A -:10B90000112309F44DC08FE99BE20E94ACCE85E47F -:10B910000E949FCE8FE89BE20E94ACCE8BEF94E119 -:10B920000F94F820D82F882361F083E89BE20E94CF -:10B93000ACCE8BE79BE2D13031F087E79BE2D2308F -:10B9400011F080E89BE20E9409DB81E0D11101C087 -:10B9500080E0C80F80ED9BE20E94ACCE0E94A6CE94 -:10B9600080EC9BE20E94ACCE8FEB94E10F94F82028 -:10B97000D82F882361F084EB9BE20E94ACCE8CEA46 -:10B980009BE2D13031F088EA9BE2D23011F081EBBA -:10B990009BE20E9409DB81E0D11101C080E0C80F69 -:10B9A000CC2351F060E089ED9BE2DF91CF911F91B4 -:10B9B0000F91FF900C941D3BDF91CF911F910F9140 -:10B9C000FF900895CF93DF9300D0CDB7DEB78C0101 -:10B9D0007B01D42E0E94B4850115110509F481C0A4 -:10B9E0000E940FD8C8010E9409DBE114F10421F480 -:10B9F0009EE6E92E9AE2F92E0E945940FF92EF92BC -:10BA00001F930F938EE39AE29F938F9381E08F931E -:10BA10000E94FA3A0E945E2D8FEF89831A821B8260 -:10BA2000CE0101960E94F6CA10914A1616951695F7 -:10BA300085E496E10E94126B012F000FF02EF10EAB -:10BA40000FB6F894DEBF0FBECDBF83E00E94AA3FC1 -:10BA5000109280161093811689E192E10E94AD4206 -:10BA60004FE25AE2602F80E00E94C46442E25AE250 -:10BA70006F2D80E00E94C46489E496E10F94E7246E -:10BA80008111E3CF0E940BD88EE49AE20E94ACCEE3 -:10BA900089EE93E0019739F000C00000EEE5F9E08F -:10BAA0003197F0F7F7CFF89489EE93E0019739F0EA -:10BAB00000C00000E6EEF3E03197F0F7F7CF0E9408 -:10BAC000B485DD2031F00E943CB7909905C0A8955F -:10BAD000FCCF0E94FE89F9CF909B02C0A895FCCFB5 -:10BAE000FFCFE114F10421F48EE6E82E8AE2F82E6D -:10BAF00005E41AE281CF80918C0F90918D0F2FEF8A -:10BB00003FEF981751F0E92FF0E0E457F04F228112 -:10BB100030E09F5F9F7790938D0FC90108951F922A -:10BB20000F920FB60F9211240F900FBE0F901F901F -:10BB300018951F920F920FB60F9211240BB60F9209 -:10BB40002F938F939F93EF93FF939091C600209133 -:10BB50008D0FE0918C0F81E08E0F8F77281729F0E1 -:10BB6000F0E0E457F04F9283E82FE0938C0FFF91C1 -:10BB7000EF919F918F912F910F900BBE0F900FBE61 -:10BB80000F901F9018958EBD0DB407FEFDCF089540 -:10BB90008FEF8EBD0DB407FEFDCF8EB50895909149 -:10BBA00064009B7F90936400982F906A96959CBD4B -:10BBB00080FD03C091E0863009F490E09DBD0895BA -:10BBC000CF93DF93EB010E94ACCECE01DF91CF91FA -:10BBD0000D94D6262F923F924F925F926F927F9252 -:10BBE0008F929F92AF92BF92CF92DF92EF92FF928D -:10BBF0000F931F93CF93DF9300D000D01F921F921B -:10BC0000CDB7DEB7B82E80917510843008F0E7C14B -:10BC100061E6D62E80917510843008F025C18091A0 -:10BC20008C0F90918D0F891B8F7709F41DC10E9495 -:10BC30007BDD97FF0BC00E940BD88BE399E20E943B -:10BC4000ACCE80918C0F80938D0FE4CF8A3019F0A9 -:10BC50008D3009F000C110927410809112109091F3 -:10BC60001310FC01E25FFF4E1682892B19F40E942B -:10BC7000A591D0CF109213101092121004E110E190 -:10BC8000F8018191803209F446C08E3409F09DC0DC -:10BC900066E379E2C8010F942E397C01892B41F0CB -:10BCA0006EE470E0C80104960F94E241009709F435 -:10BCB000C8014AE050E070E060E001960F94A536BC -:10BCC0002B013C0180910E1090910F10A09110104B -:10BCD000B09111100196A11DB11D481659066A06B2 -:10BCE0007B0629F060E083E099E2EF2851F16AE2F7 -:10BCF00070E0C8010F9411429C01009729F1982F20 -:10BD0000901BF12C992349F09150F801E90FF11D96 -:10BD10008081F826F7CF8F01B3CF4AE050E070E082 -:10BD200060E0C90101960F94A5362F2D30E050E058 -:10BD300040E0621773078407950751F060E084EED6 -:10BD400098E20F945B0F66CF60E08AEB98E2F9CF40 -:10BD500040920E1050920F106092101070921110BD -:10BD6000809135098130E1F467E470E0C8010F94F7 -:10BD7000E2410097A9F04AE050E070E060E00196EF -:10BD80000F94A536643071058105910548F489E169 -:10BD900098E20E94ACCE60E08FE098E20E941D3BEA -:10BDA000F80180818D3489F58381823309F446C09E -:10BDB000883309F1803349F58181843331F58281FB -:10BDC000813319F50E9439B820C08091A21780FFF5 -:10BDD000C7CF67ED7AE3C8010F942E39009739F089 -:10BDE000DC0113968C9180538A3008F0B9CF60E063 -:10BDF00080E998E2A6CF8281803339F48181813352 -:10BE000021F41092740210924F09809114108B3318 -:10BE100009F400CF80917510843008F0FBCE80913A -:10BE200077108D9DC001112464E170E188589F4E08 -:10BE30000F94ED4180E00F941C0FECCE8281813392 -:10BE400021F78181813309F741E070E060E084EF00 -:10BE500090E30E94E2DC22E130E144E150E164E75A -:10BE600070E10E9459C5D6CE8091A21783FDB7C05C -:10BE700082FFB5C087FDB3C01A82198231E6F32E66 -:10BE800044E0E42E59E6D52E80917510843008F0F8 -:10BE9000A6C00E9491C58111A2C041E050E0BE0140 -:10BEA0006D5F7F4F80E594E10E94167D0B8110E06D -:10BEB000019711F00FEF1FEF8091581490915914D2 -:10BEC000A0915A14B0915B1480939E1790939F1782 -:10BED000A093A017B093A1170E9491C50F3F100720 -:10BEE00049F4811107C00E940BD883E599E20E94B2 -:10BEF000ACCECACF40917710242F30E00A3061F0E9 -:10BF00000D3051F0882309F45CC089819A81009733 -:10BF100019F001969A8389831092620889819A8127 -:10BF2000F29EF001F39EF00D1124EB58FF4EE80F46 -:10BF3000F91F1382892BA9F50E94A5910E9491C532 -:10BF4000882309F4A1CF80E594E10E945E7E809170 -:10BF50009917882361F18150809399178D9DC001B5 -:10BF6000112462E08156994F0E945EBEE0919917BC -:10BF700024E0E29FF0011124E556F94F4081518100 -:10BF80006281738140939E1750939F176093A0170F -:10BF90007093A11780E594E10E94827C0E949279BF -:10BFA00073CF1A82198281E00F941C0FC7CF0E94B1 -:10BFB000677E8091A21788608093A217E09235096E -:10BFC00063CF4F9DA001112448585F4E9E012F5F03 -:10BFD0003F4F62E678E0802F0E9459C555CF0F94FD -:10BFE0001E1D6B017C01B11004C080919A0688234C -:10BFF00051F0C0923B06D0923C06E0923D06F09292 -:10C000003E06BB24B39480919A0890919B08A0911E -:10C010009C08B0919D080097A105B10551F1409190 -:10C020003B0650913C0660913D0670913E06840FA0 -:10C03000951FA61FB71FA7019601281B390B4A0B96 -:10C040005B0BDA01C901B7FD14C00E940BD881EB6C -:10C0500099E20E94ACCE609153097091540986E830 -:10C0600099E20F94E22640E070E060E090E080E02A -:10C07000F0CE9091091680910A16981741F0C0925F -:10C080003B06D0923C06E0923D06F0923E0640917F -:10C090005A0250915B0260915C0270915D02452BE7 -:10C0A000462B472B21F0981701F110926D088091D3 -:10C0B0006B0890916C08909946C0019690936C081B -:10C0C00080936B0880916B0890916C088E3E924033 -:10C0D0000CF43FC00E940BD883E799E20E94ACCEDB -:10C0E00082E699E20E94ACCEBECFB110DECF0F94B3 -:10C0F0001E1D00913B0610913C0620913D0630919B -:10C100003E0680905A0290905B02A0905C02B09034 -:10C110005D02080D191D2A1D3B1D601B710B820B52 -:10C12000930B97FDC2CF80916D088111C0CF81E044 -:10C1300080936D0880E00E9400B781E00E9400B704 -:10C140000E94FE89B4CF181619060CF0BBCF0197D8 -:10C15000B5CF8091670890916808A0916908B09167 -:10C160006A0846015701881A990AAA0ABB0AD5012A -:10C17000C401B7FD72C19091091680910A165091C1 -:10C1800056024091570298131EC08091D20558174D -:10C19000C1F08093560281E02091D305421779F1D6 -:10C1A000209357020F941E1D6091560270E084E0A8 -:10C1B0000F94E9186091570270E089E00F94E91834 -:10C1C00020C080E0E9CFE0910A162E2F30E08DE507 -:10C1D000E89FF0011124EC50F64F8081581769F068 -:10C1E0008093560281E09DE5929FF001939FF00DB0 -:10C1F0001124EB50F64F2081D1CF80E0F4CF811194 -:10C20000D1CF80916D06882309F41AC1809051091D -:10C2100088868090180290901902A88427E1A29E37 -:10C22000F0011124E15CF94FC401029720853185AA -:10C23000281739070CF404C110910A16712C00E07C -:10C240001C82612C80910916811709F45FC0812F2F -:10C2500090E02DE5B22EB89EF001B99EF00D1124AC -:10C26000E356F64F458956896789708D452B462BD5 -:10C27000472B81F4418D528D638D748D452B462B58 -:10C28000472B41F4458D568D678D70A1452B462B6C -:10C29000472BC9F14DE5489F9001499F300D11246E -:10C2A000C9018356964F5C01DC0191966D917D9199 -:10C2B0008D919C9194970F94B6391B012C01F50137 -:10C2C00065A176A187A190A50F94B6399B01AC0119 -:10C2D000C201B1010F94023FD50111962D913D91FC -:10C2E0004D915C9114970F94173A2B015C01272D07 -:10C2F000302F4C81562D0F946840181624F4742C5E -:10C30000052DAC826B2C1F5F1F709CCFB401990C64 -:10C31000880B990B0F94B839562EA72EB82E192FCB -:10C320002091120230911302409114025091150293 -:10C33000672D702F8C81962D0F94173A252D3A2D4D -:10C340004B2D512F0F94083E362E472E782E092F55 -:10C350008090160290901702262F372F482F592FC2 -:10C36000652D7A2D8B2D912F0F9468401816D4F0DF -:10C37000B401990C880B990B0F94B839562EA72E3F -:10C38000B82E192F262F372F482F592F632D742D94 -:10C39000872D902F0F946840181624F0532CA42C4E -:10C3A000B72C102F209163083091640840916508E4 -:10C3B000509166082C833D834E835F83252D3A2D53 -:10C3C0004B2D512F6C817D818E819F810F94684010 -:10C3D000181604F520E037ED43EA5CE3652D7A2D6D -:10C3E0008B2D912F0F94173A4B015C0128E431EE0D -:10C3F0004AE75FE36C817D818E819F810F94173ABC -:10C400009B01AC01C501B4010F94083E562EA72E26 -:10C41000B82E192F852D9A2DAB2DB12F809363083F -:10C4200090936408A0936508B0936608652D7A2DF3 -:10C430008B2D912F0F94743FCB0168850E94DCCC2B -:10C4400034E6C30ED11CE11CF11CC0926708D092E7 -:10C450006808E0926908F0926A080E94A5918091AC -:10C460003509882309F42BC190910901892F809502 -:10C470008170109158021817D1F12091A2172064F1 -:10C480002093A2178093580290FD0FC064EF71E0D3 -:10C4900080E090E00E9421CD0E948F7E8091A217C3 -:10C4A00084FD46C1112319F102C00E94777E12302B -:10C4B00008F41EC100E00E94DE3F83E08093750215 -:10C4C0000F941E1D6C597F4F8F4F9F4F6093FB033E -:10C4D0007093FC038093FD039093FE03002339F0D7 -:10C4E000123029F481E0809398170F9413270F944A -:10C4F0001E1D6B017C01109159021123F1F08091F6 -:10C5000050098823D1F040917608509177086091C6 -:10C5100078087091790846015701841A950AA60A8D -:10C52000B70AB501A40177FD1AC0833009F4FBC036 -:10C530000CF0EAC081300CF0EFC0212F30E0A8EE03 -:10C54000B3E00F94F83DC60ED71EE81EF91EC09248 -:10C550007608D0927708E0927808F0927908809176 -:10C56000860F813009F073C00F941E1D6B017C0192 -:10C570008091720890917308A0917408B091750829 -:10C58000A7019601281B390B4A0B5B0BDA01C90185 -:10C59000B7FD3AC0D701C601805F984DAF4FBF4F7E -:10C5A0008093720890937308A0937408B0937508F1 -:10C5B0008090D5059090D605A090D705B090D8056D -:10C5C0000E94E4BAAB01BC014093D5055093D60557 -:10C5D0006093D7057093D8058091D6089091D708BD -:10C5E000A091D808B091D90888199909AA09BB095E -:10C5F000840F951FA61FB71F8093D6089093D70866 -:10C60000A093D808B093D90880916E0890916F08D4 -:10C61000A0917008B091710846015701881A990AD3 -:10C62000AA0ABB0AD501C401B7FD11C020E8C20E99 -:10C630002EEED21E26E3E21EF11CC0926E08D092AE -:10C640006F08E0927008F09271080E94BC8E0E9400 -:10C65000312B0E94446B80919908882381F10F94BB -:10C660001E1D6B017C018091950890919608A09108 -:10C670009708B091980846015701881A990AAA0AA2 -:10C68000BB0AD501C401B7FD1AC02091990830E05A -:10C69000A8EEB3E00F94F83DC60ED71EE81EF91EB3 -:10C6A000C0929508D0929608E0929708F092980868 -:10C6B000809151090E949E848AE00E949FCE289614 -:10C6C0000FB6F894DEBF0FBECDBFDF91CF911F91A3 -:10C6D0000F91FF90EF90DF90CF90BF90AF909F9021 -:10C6E0008F907F906F905F904F903F902F90089524 -:10C6F00060E085E09AE20E941D3B80914009811133 -:10C70000D9CE0E945E2DD6CE843009F016CF0E947D -:10C710000FD884EC99E204C00E940FD883EF99E20D -:10C720000E94ACCE0ACF0E940FD88CED99E2F8CFD0 -:10C73000123028F460E083E19AE20E941D3B01E0A0 -:10C74000BACE2F923F924F925F926F927F928F92CA -:10C750009F92AF92BF92CF92DF92EF92FF920F9390 -:10C760001F93CF93DF93CDB7DEB76B970FB6F894D7 -:10C77000DEBF0FBECDBF9091D40593FD47C1182FEA -:10C7800089E40E94D1C9882309F46DC10E945BC766 -:10C7900090E01816190614F481E090E026E0289F36 -:10C7A000F001299FF00D1124EE50FA4F8281938100 -:10C7B0001F828436910514F084E690E0909337064A -:10C7C000809336060E9422C60E943BC860E0882300 -:10C7D00009F40DC183EC95E30E941D3B01E0612F3C -:10C7E0006027812F0E94DEBB112309F435C1C09060 -:10C7F0003206D0903306E0903406F0903506CC8AAD -:10C80000DD8AEE8AFF8A8FE780933A0600937402EE -:10C81000412C512C3201188619861A861B86188ADB -:10C820002CE3298B3CE13A8B46E44B8B212C1C8278 -:10C8300050E85D838FEB8E83312C609136067091CA -:10C840003706072E000C880B990B0F94B8397B0123 -:10C850008C01222D3C814D815E810F94B13988235A -:10C86000B9F0209132063091330640913406509150 -:10C870003506CF80B701C801C110BCC00F94B139D3 -:10C88000382E331C3324331C2E2CFC820D831E8344 -:10C890000F941E1D4B015C01DC01CB01C884D984BF -:10C8A000EA84FB848C199D09AE09BF09B7FD11C04C -:10C8B000A501940128513C4F4F4F5F4F288739877E -:10C8C0004A875B87809151090E949E848AE00E947A -:10C8D0009FCE80E00E94EADD0F941E1D60933B0610 -:10C8E00070933C0680933D0690933E06109132066D -:10C8F00000913306D0903406C09035063110C3C085 -:10C90000622D7C818D819E810F94743F4B01612F3C -:10C91000702F8D2D9C2D0F94743F6C877D878E8793 -:10C920009F870C851D856C897D898E899F890F94D1 -:10C93000743F9B018616970609F487C06401092C91 -:10C94000000CEE08FF08C88ED98EEA8EFB8E6B01B4 -:10C95000072E000CEE08FF08061717072CF09401AD -:10C96000081519050CF49801032E000C440B550B07 -:10C970002C193D094E095F09AFEFB0E00F94E53D7A -:10C98000288D398D4A8D5B8D2C193D094E095F0923 -:10C990000F94C63D80913A06821759F020933A06CB -:10C9A00029831A82DD24DA94DB82CE0101960E946B -:10C9B000F6CA80917402882309F1332009F447C034 -:10C9C0006091360670913706072E000C880B990B84 -:10C9D0000F94B839209132063091330640913406D5 -:10C9E000509135060F94B13987FD27CF07C084EBEE -:10C9F00095E3F2CE0F94B13987FF21C08091740284 -:10CA0000882321F0109274020F948E106B960FB64B -:10CA1000F894DEBF0FBECDBFDF91CF911F910F9174 -:10CA2000FF90EF90DF90CF90BF90AF909F908F904E -:10CA30007F906F905F904F903F902F9008952E2C95 -:10CA4000FC820D831E83312C23CF2FEFA3CF0E94B6 -:10CA50003BC88111F2CED2CF8DE295EC90931812A3 -:10CA600080931712D3CF83E50E94D1C98F838111A0 -:10CA700007C0112359F282E50E94D1C9882331F2FF -:10CA80000E9457C796CE411451046104710441F0CD -:10CA9000D501C40184199509A609B709B7FD89CF45 -:10CAA000212F302F4D2D5C2D688979898A899B89AA -:10CAB0000F94073E20E030E040E85FE30F94B13987 -:10CAC00087FD9CCF2401350120E6420E2AEE521E3E -:10CAD000611C711C188B098BDA8ACB8A6ACF1F9371 -:10CAE000CF93DF93D82F162F8091D40583FD15C0E7 -:10CAF000C091510987E1C89FF0011124E15CF94F11 -:10CB0000808591850E94F7CC882339F06C2F809125 -:10CB10006002909161020E94DCCC40915109612F2A -:10CB20008BE00E94092EDD2341F061E080915109E4 -:10CB3000DF91CF911F910C9488868091A00891E09D -:10CB400089278093740217E1809174028823F9F099 -:10CB5000C09151091C9FE0011124C15CD94F20E014 -:10CB600030E040E05FE36C817D818E819F810F9496 -:10CB7000083E0F94743F28853985621B730B77FF3D -:10CB800003C07195619571096230710544F410928A -:10CB900074028091D40583FF06C081E019C080E053 -:10CBA0000E94EADDD1CFE091510987E1E89FF001D1 -:10CBB0001124E15CF94F808591850E94F7CC882390 -:10CBC00061F30E940FD88CE79AE20E94ACCE80E01D -:10CBD000DF91CF911F9108956F927F928F929F92D4 -:10CBE000AF92BF92CF92DF92EF92FF920F931F937B -:10CBF000CF93DF9300D000D01F921F92CDB7DEB746 -:10CC00005C014B013A01F22E68011091220610924C -:10CC10001E0610921F0610922006109221061092F6 -:10CC2000220680E00E949ACC00912706012B1092E8 -:10CC300023061092240610922506109226061092C2 -:10CC4000270681E00E949ACC6091510987E1689F94 -:10CC5000F0011124E15CF94F808591858C159D05CB -:10CC60001CF4C6010E94DCCCE12C2F2DA301B401E1 -:10CC7000C5010F948D121C141D0454F460915109C8 -:10CC8000C6010E94DCCC60E0809151090E94888638 -:10CC90004091510960E088E00E94092E60E081E047 -:10CCA0000E946FE580E090E0A0E7B2E489839A8378 -:10CCB000AB83BC8380E090E0A0E0B0EC8D839E83EA -:10CCC000AF83B887BE016F5F7F4FCE0105960E948C -:10CCD0004EB50F941711811168C080918202909116 -:10CCE0008302A0918402B091850240917E0250910E -:10CCF0007F02609180027091810280908308909001 -:10CD00008408A0908508B090860800917F08109153 -:10CD10008008209181083091820800938A06109340 -:10CD20008B0620938C0630938D0680928E0690920F -:10CD30008F06A0929006B09291064093920650936F -:10CD4000930660939406709395068093960690934D -:10CD50009706A0939806B093990680E090E0A8EC1F -:10CD6000B2E489839A83AB83BC83CE0101960E948F -:10CD7000E3B48091870890918808A0918908B091C8 -:10CD80008A088093920690939306A0939406B0939A -:10CD9000950680E090E0A0EAB0E489839A83AB83B3 -:10CDA000BC83CE0101960E94E3B4812C912C80E7D4 -:10CDB000A82E82E4B82E89829A82AB82BC8280E05F -:10CDC00090E0A0E0B0E48D839E83AF83B887BE017E -:10CDD0006F5F7F4FCE0105960E944EB520E030E098 -:10CDE000A90160918B0870918C0880918D089091B9 -:10CDF0008E080F94B13987FF0BC089829A82AB826B -:10CE0000BC82BE016F5F7F4F8BE898E00E944EB5F9 -:10CE100080918B0890918C08A0918D08B0918E081C -:10CE20008093820290938302A0938402B093850240 -:10CE30008093960690939706A0939806B0939906D0 -:10CE400086E996E00E9498B1809151098093000490 -:10CE50000E945E2D80919A06815080939A0680915F -:10CE6000860F823011F40E94A6BB80919A06882317 -:10CE700029F0815080939A060E9492790F948E1027 -:10CE80000E945E2D28960FB6F894DEBF0FBECDBF70 -:10CE9000DF91CF911F910F91FF90EF90DF90CF9096 -:10CEA000BF90AF909F908F907F906F9008954F921A -:10CEB0005F926F927F92AF92BF92CF92DF92EF928A -:10CEC000FF921F93CF93DF9300D000D01F921F9249 -:10CED000CDB7DEB75C01E62EF42E642F80E00E9411 -:10CEE0006FE5182F81111DC0EE2031F0809151099E -:10CEF000809300040E945E2D812F28960FB6F8942F -:10CF0000DEBF0FBECDBFDF91CF911F91FF90EF909D -:10CF1000DF90CF90BF90AF907F906F905F904F90D9 -:10CF20000895EE2031F0409151096F2D83E00E9469 -:10CF3000092E80E090E0A0E7B2E48D839E83AF836A -:10CF4000B88780E090E0A0E5B1EC89839A83AB8359 -:10CF5000BC83BE016B5F7F4FCE0101960E944EB530 -:10CF600068E873E180E090E00E9421CDC12CD12CD3 -:10CF700088ECE82E81E4F82ECD82DE82EF82F886FE -:10CF800080E090E0A8EAB1E489839A83AB83BC8314 -:10CF9000BE016B5F7F4FCE0101960E944EB540905F -:10CFA0008D0950908E0960908F0970909009C09201 -:10CFB0008D09D0928E09E0928F09F092900980E05D -:10CFC00090E0A0E2B1E48D839E83AF83B887F50142 -:10CFD00080819181A281B38189839A83AB83BC8351 -:10CFE000BE016B5F7F4FCE0101960E944EB540920D -:10CFF0008D0950928E0960928F09709290090E945B -:10D0000045CD7ACFAF92BF92CF92DF92EF92FF924F -:10D010000F931F93CF93DF9300D01F92CDB7DEB74E -:10D020007C015B01D42E890181E080939A06809176 -:10D03000A21782FF08C087FD06C08B7F8093A217CE -:10D0400082E080939A060E94FFBB80E1E6E7F2E06F -:10D05000AFE7B8E001900D928A95E1F70F941711B0 -:10D06000C82E0E947F8F20E030E0A901F701608187 -:10D070007181828193810F94B1398823A1F08091CD -:10D0800051090E940CCD81110EC080E090E0A0E714 -:10D09000B2E489839A83AB83BC83BE016F5F7F4F09 -:10D0A000C7010E944EB5C11004C0B50180E00E94C6 -:10D0B0007C2A20E030E0A901F80160817181828141 -:10D0C00093810F94B139882329F042E06D2DC80176 -:10D0D0000E9457E70E9445CD81E00F900F900F907E -:10D0E0000F90DF91CF911F910F91FF90EF90DF9004 -:10D0F000CF90BF90AF900895CF92DF92EF92FF92C2 -:10D10000CF93DF936B017C01D42FC091500983E052 -:10D110008093500981E080934F09C114D104E10448 -:10D12000F10431F00F941E1DC60ED71EE81EF91E25 -:10D1300080914F09882389F0C114D104E104F104DE -:10D1400021F48D2F0E94EADDF3CF0F941E1D6C1980 -:10D150007D098E099F0997FDF4CF10924F098091A8 -:10D16000FF0382FF07C062E370E080E090E00E946E -:10D1700021CDF5CFC0935009DF91CF91FF90EF9073 -:10D18000DF90CF9008951F93CF93DF93D82FC62FB2 -:10D190000E9466DA61E08C2F0E9425CC0F941E1D40 -:10D1A000685370458F4F9F4F60931E0670931F0604 -:10D1B0008093200690932106109222060F941E1D44 -:10D1C000685370458F4F9F4F6093230670932406DA -:10D1D00080932506909326061092270610915009F9 -:10D1E00083E08093500981E080934F0980914F093B -:10D1F000882309F46BC060E08C2F0E9425CC8091BD -:10D200002206811105C080912706882309F45AC09F -:10D210004091510960E08AE00E94092E0E940FD8D7 -:10D2200087EC9AE20E94ACCE41E060E070E0CB0176 -:10D230000E947CE810921E0610921F061092200693 -:10D24000109221061092220680E00E949ACC109241 -:10D25000230610922406109225061092260610929C -:10D26000270681E00E949ACC60E080E00E946FE592 -:10D270008D2F0E9466DA0F941E1D685370458F4FE4 -:10D280009F4F60931E0670931F0680932006909315 -:10D290002106109222060F941E1D685370458F4F71 -:10D2A0009F4F6093230670932406809325069093E6 -:10D2B00026061092270681E080934F0961E08C2FAB -:10D2C0000E9425CC81E00E94EADD90CF10935009A6 -:10D2D000DF91CF911F910895AF92BF92CF92DF92CD -:10D2E000EF92FF920F931F93CF93DF93CDB7DEB7EB -:10D2F000A0970FB6F894DEBF0FBECDBF0E9413D823 -:10D30000182F87FD30C1482F61E081E00E94092E6F -:10D31000B0905109812F012E000C990BB8161906F7 -:10D3200021F060E0812F0E947DB585E40E94D1C983 -:10D33000C12CD12CE12C90E4F92E882379F00E94A5 -:10D34000A7C96B017C0120E030E0A9010F9468407F -:10D3500087FF04C0F7FAF094F7F8F094F7FAF09426 -:10D36000F7F8F094C98EDA8EEB8EFC8E8CE0E7E550 -:10D37000F3E0DE01119601900D928A95E1F788E5C0 -:10D380000E94D1C9882339F088E50F9484126983FB -:10D390007A838B839C8389E50E94D1C9882339F0E5 -:10D3A00089E50F9484126D837E838F8398878AE545 -:10D3B0000E94D1C9882339F08AE50F9484126987C5 -:10D3C0007A878B879C8700915109E02EF12C8CE0A5 -:10D3D000089F800111240259194FF80120813181E1 -:10D3E0004281538169817A818B819C810F94083EAF -:10D3F00069837A838B839C83F801248135814681FC -:10D4000057816D817E818F8198850F94083E6D8351 -:10D410007E838F839887F8012085318542855385E7 -:10D4200069857A858B859C850F94083E69877A8704 -:10D430008B879C87F70183E0EE0FFF1F8A95E1F74A -:10D44000E752FA4FC080D180E280F38085E50E94E8 -:10D45000D1C9882321F00E94A7C96B017C0120E07B -:10D4600030E0A901C701B6010F94684087FF04C0EE -:10D47000F7FAF094F7F8F094F7FAF094F7F8F094DC -:10D48000CD8EDE8EEF8EF8A26AE070E082E40E941C -:10D49000C4CAA82E80919A0681115DC09E01235EA8 -:10D4A0003F4F41E0BE016F5F7F4FCE0149960E9422 -:10D4B00002E8882309F44FC06A2D81E00E94C3E886 -:10D4C00070E060E082E50E94C4CA8C0180E090E0D8 -:10D4D000A8E4B2E48D8B9E8BAF8BB88FE09151099D -:10D4E00088E0E89FF0011124E752FA4FC480D5800C -:10D4F000E680F7808CE40E94D1C9882321F00E9445 -:10D50000A7C96B017C0120E030E0A901C701B60189 -:10D510000F94684087FF04C0F7FAF094F7F8F0948E -:10D52000C98ADA8AEB8AFC8A80E090E0A0EAB2E459 -:10D530008D879E87AF87B88B80919A06882359F094 -:10D540002A2DAE014B5E5F4FBE016F5E7F4FCE0155 -:10D550000D960E94ECE5809151098B1521F060E059 -:10D560008B2D0E947DB5A0960FB6F894DEBF0FBE3E -:10D57000CDBFDF91CF911F910F91FF90EF90DF9082 -:10D58000CF90BF90AF900895CF92DF92EF92FF922D -:10D590000F931F93CF93DF93CDB7DEB76C970FB682 -:10D5A000F894DEBF0FBECDBF8CE40E94D1C98823A2 -:10D5B00009F4F1C00E94A7C96B017C0120E030E0B2 -:10D5C000A9010F94684087FF04C0F7FAF094F7F8B8 -:10D5D000F094F7FAF094F7F8F094C98EDA8EEB8EA7 -:10D5E000FC8E8CE0E7E5F3E0DE01119601900D92F0 -:10D5F0008A95E1F788E50E94D1C9882389F088E5FA -:10D600000F94841220916D0F30916E0F40916F0F27 -:10D610005091700F0F94073E69837A838B839C83AC -:10D6200089E50E94D1C9882389F089E50F94841285 -:10D630002091710F3091720F4091730F5091740FC0 -:10D640000F94073E6D837E838F8398878AE50E94BF -:10D65000D1C9882339F08AE50F94841269877A87C3 -:10D660008B879C87F09051098CE0F89E80011124F3 -:10D670000259194FF801208131814281538169811A -:10D680007A818B819C810F94083E69837A838B8396 -:10D690009C83F80124813581468157816D817E818B -:10D6A0008F8198850F94083E6D837E838F83988742 -:10D6B000F801208531854285538569857A858B857A -:10D6C0009C850F94083E69877A878B879C87809119 -:10D6D000A21782FB112710F982FF05C087FB1127D3 -:10D6E00010F981E018274F2D61E080E00E94092E9B -:10D6F00060E080E50E94E1CA082F1D861E861F8615 -:10D70000188A80919A06811137C09E01235F3F4F8E -:10D71000402FBE016F5F7F4FCE0149960E9402E805 -:10D72000882351F1112311F0002331F160E080E0F2 -:10D730000E94C3E8898D9A8DAB8DBC8DB0588D8BBE -:10D740009E8BAF8BB88F198A1A8A1B8A1C8A1D86FA -:10D750001E861F86188A80919A06882369F010E039 -:10D7600000E020E0AE014B5E5F4FBE016F5E7F4F79 -:10D77000CE010D960E94ECE56C960FB6F894DEBFD4 -:10D780000FBECDBFDF91CF911F910F91FF90EF9012 -:10D79000DF90CF900895C12CD12CE12C80E4F82E9D -:10D7A00018CF2F923F924F925F926F927F928F92FB -:10D7B0009F92AF92BF92CF92DF92EF92FF920F9320 -:10D7C0001F93CF93DF93CDB7DEB7CD58D1090FB6F6 -:10D7D000F894DEBF0FBECDBFC357DF4F8883CD584F -:10D7E000D040C0905009E196CFAEE19721E0209360 -:10D7F00050098091C4088D3409F4E1C4843511F4D2 -:10D800000D94CA00873409F041C10091C2081091FB -:10D81000C3080531110509F401C308F03AC1043009 -:10D82000110508F02FC1809135090230110508F467 -:10D83000EFC2833008F4F2C233243394023011056E -:10D8400009F0312C0E94DEC982E50E94D1C98823EB -:10D8500009F4FDC20E94A7C96B017C0120E030E001 -:10D86000A9010F94B139882309F405C140907602CB -:10D8700050907702609078027090790220917A023D -:10D8800030917B0240917C0250917D0228AF39AFEC -:10D890004AAF5BAF80908A0690908B06A0908C0672 -:10D8A000B0908D0680918E0690918F06A091900683 -:10D8B000B09191068CAF9DAFAEAFBFAFA501940103 -:10D8C000C301B2010F94B13981110DC02CAD3DAD32 -:10D8D0004EAD5FAD68AD79AD8AAD9BAD0F94B139FA -:10D8E000882309F4C8C0A3019201C501B4010F94B3 -:10D8F000073E20E030E040E05FE30F94173A6CAB66 -:10D900007DAB8EAB9FAB28AD39AD4AAD5BAD6CAD99 -:10D910007DAD8EAD9FAD0F94073E20E030E040E03E -:10D920005FE30F94173A68AF79AF8AAF9BAF20E0FF -:10D9300030E0A901C701B6010F94B139881F8827CB -:10D94000881F381609F47AC220E030E040E85FEB27 -:10D950002CAF3DAF4EAF5FAF2CA93DA94EA95FA93B -:10D96000CA01B9010F94173A4B015C0128AD39ADDA -:10D970004AAD5BADCA01B9010F94173A9B01AC01E6 -:10D98000C501B4010F94083E0F94B6404B015C01F1 -:10D99000AC019B01C701B6010F94073E2B013C016E -:10D9A000A5019401C701B6010F94083E9B01AC018B -:10D9B000C301B2010F94173A6B017C0120E030E003 -:10D9C000A9010F946840412C512C320187FD06C0FB -:10D9D000C701B6010F94B6402B013C0168AD79AD8B -:10D9E0008AAD9BAD9058A50194010F94023F2CADD8 -:10D9F0003DAD4EAD5FAD0F94173AA30192010F9468 -:10DA0000173A2CA93DA94EA95FA90F94083E6B01B6 -:10DA10007C01A50194016CA97DA98EA99FA90F94F1 -:10DA2000023F2CAD3DAD4EAD5FAD0F94173AA30153 -:10DA300092010F94173A28AD39AD4AAD5BAD0F9402 -:10DA4000083E6CAB7DAB8EAB9FAB20E030E0A90114 -:10DA5000C701B6010F94B13981110D941F0120E067 -:10DA600030E0A9016CA97DA98EA99FA90F94B139B5 -:10DA700081110D941F010E940BD88FE99FE20E9433 -:10DA8000ACCECCC10430110509F431C30F94761229 -:10DA9000C5C10A35110509F481C308F048C10B312D -:10DAA000110509F45EC30C31110581F70F941711AC -:10DAB000811111C08091BC089091BD08A091BE0851 -:10DAC000B091BF08FEE0B695A79597958795FA9512 -:10DAD000D1F780FDA3C10E947F8F109238020F946E -:10DAE0001E1D60933B0670933C0680933D06909309 -:10DAF0003E06D090510961E080E00E947DB58091A2 -:10DB0000510290915202A0915302B091540280931D -:10DB1000910890939208A0939308B09394088091F1 -:10DB20002002909121029093900880938F0884E6C0 -:10DB300090E0909321028093200281E08093E3089B -:10DB40000E9471B98091BC089091BD08A091BE0857 -:10DB5000B091BF08A7FBFF24F0F80B2F0170B1FBB9 -:10DB6000882780F9F01203C08F1509F412C3182F0B -:10DB700082E50E94D1C9882311F40D94EB000E9424 -:10DB8000A7C93B014C0120E030E0A9010F94B13955 -:10DB90008823D9F1A0907E02B0907F02C0908002CD -:10DBA000E090810295014C2D5E2DB301C4010F94CC -:10DBB000B13987FD03C05301C82CE92C80E090E007 -:10DBC000A0E8B0E48C8F9D8FAE8FBF8F20E030E057 -:10DBD00046E153E4B5018C2D9E2D0F94B13987FD9C -:10DBE00006C0A12CB12C56E1C52E63E4E62EC5017A -:10DBF000AC2DBE2D89839A83AB83BC83BE01645E4A -:10DC00007F4FCE0101960E94C4B4FF2009F45DC08D -:10DC1000002309F457C010927602109277021092F6 -:10DC200078021092790210927A0210927B0210927E -:10DC30007C0210927D020E947BB58EED9BE6ADE8E2 -:10DC4000B2E488A799A7AAA7BBA7EBEEF4E1659178 -:10DC500075918591949120E030E040EC5FE30F9462 -:10DC6000173A905869837A838B839C83E7EEF4E1BB -:10DC7000659175918591949120E030E040EC5FE3EF -:10DC80000F94173A6C8F7D8F8E8F9F8FAE01485DFA -:10DC90005F4FBE016F5F7F4FCE014C960E94A2B4D2 -:10DCA0000E94D6BA109276021092770210927802F1 -:10DCB0001092790210927A0210927B0210927C02EA -:10DCC00010927D0280E00E9459B7002319F081E094 -:10DCD0000E9459B7112319F082E00E9459B70E949F -:10DCE0007BB58091E2088093E30880919108909140 -:10DCF0009208A0919308B091940880935102909358 -:10DD00005202A0935302B093540280918F089091D5 -:10DD10009008909321028093200261E08D2D0E9453 -:10DD20007DB583E0809375020E94BBB877C00B3548 -:10DD3000110509F436C20C35110509F0A7CE4CE9DE -:10DD4000C42E42E0D42EF12CE12C00E010E0D601EC -:10DD50008D916D010E94D1C9382E882309F448C0E5 -:10DD60000E94A7C94B015C01133059F0F701E35938 -:10DD7000F04F20813181428153810F94073E4B0146 -:10DD80005C01F701EA58FD4F2081318142815381C6 -:10DD9000C501B4010F94073E2B013C012DEB37E385 -:10DDA00046E855EB0F94684087FD0AC02DEB37E33A -:10DDB00046E855E3C301B2010F94B1391816C4F413 -:10DDC000133009F4F2C1F701E655FA4F5F01A301E0 -:10DDD000920160817181828193810F94083ED50107 -:10DDE0006D937D938D939C931397812F0E94FAB22C -:10DDF0001F5FB4E0EB0EF11C143009F0A8CF002334 -:10DE000021F082E892E00E9498B10E94BBB806C05F -:10DE1000833020F00E94DEC90E94C2B3C357DF4F97 -:10DE2000C880CD58D040C11002C00E9491CFE19669 -:10DE3000DFACE197D09250090C944AF780E090E073 -:10DE4000A0E8BFE38CAF9DAFAEAFBFAF85CD89E497 -:10DE50000E94D1C9C12CD12C7601882321F00E94C7 -:10DE6000A7C96B017C018AE40E94D1C9882311F4FF -:10DE70000D9410010E94A7C9E4CD28962CAD3DADAC -:10DE80004EAD5FAD289768AD79AD8AAD9BAD0F946F -:10DE9000173A6B017C012C962CAD3DAD4EAD5FADBC -:10DEA0002C976CAD7DAD8EAD9FAD0F94173A9B0155 -:10DEB000AC01C701B6010F94083E6B017C012C96A2 -:10DEC0002CAD3DAD4EAD5FAD2C9768AD79AD8AAD53 -:10DED0009BAD0F94173A4B015C0128962CAD3DADDC -:10DEE0004EAD5FAD28976CAD7DAD8EAD9FAD0F94FF -:10DEF000173A9B01AC01C501B4010F94073EA7017D -:10DF000096010F94873E6B017C0120E030E0A9016F -:10DF10000F94B139882311F40D94B60520E030E058 -:10DF2000A901C701B6010F94B13987FF2CC082E067 -:10DF300090E083298130910549F1029791F120E029 -:10DF400030E0A901C701B6010F94684026013701EE -:10DF500087FF04C077FA709477F870942BED3FE058 -:10DF600049EC50E4C301B2010F94023F20E030E0DD -:10DF700040E952E40F94173A0F94E63E0F947B3F2A -:10DF80008B010D94040290E080E0D3CF2BED3FE0B5 -:10DF900049EC50E4C701B6010F94073E6B017C01C8 -:10DFA000CECF2BED3FE049EC50E4C701B6010F9412 -:10DFB000083EF4CF08E410E0BBED4B2EBFE05B2E33 -:10DFC000B9EC6B2EB0E47B2E730162010D94040258 -:10DFD0002DEC3CEC4CEC5DE3C201B1010F94B13986 -:10DFE00087FF28C02DEC3CEC4CEC5DE321966FAD37 -:10DFF000219725967FAD259729968FAD2997659610 -:10E000009FAD65970F94023F0F94AA3F2B013C01EF -:10E0100020E030E040E85FE30F94B13987FF06C0AD -:10E02000412C512CA0E86A2EAFE37A2EC301B20135 -:10E030000D94D102B301C8010D94D1026796CEAC04 -:10E04000DFAC6797B60190E080E00F94B6396F9629 -:10E050002CAD3DAD4EAD5FAD6F970F94173A4B01B0 -:10E060005C010F94FD3E6B017C01C501B4010F946E -:10E07000A8404B015C01A701960168AD79AD8AAD5E -:10E080009BAD0F94173A2B013C01A50194016CA99B -:10E090007DA98EA99FA90F94173A9B01AC01C301DA -:10E0A000B2010F94083E2B013C01A501940168AD1B -:10E0B00079AD8AAD9BAD0F94173A4B015C01A70176 -:10E0C00096016CA97DA98EA99FA90F94173A9B016F -:10E0D000AC01C501B4010F94073E6CAF7DAF8EAFAC -:10E0E0009FAF29E1A0962FAFA0970D94BA0480E5C9 -:10E0F0000E94D1C9C12CD12C7601882321F00E9425 -:10E1000037C76B017C0183E50E94D1C9882361F088 -:10E110000E94A7C920E030E04AE754E40F94173A80 -:10E120000F947B3F6B017C010E947F8F80911912BD -:10E13000811105C060E085EB9FE20E941D3B0F94BA -:10E140001E1DC60ED71EE81EF91E0F941E1D6C194B -:10E150007D098E099F0997FF61CE80E00E94EADD6C -:10E16000F4CF0F943211811159CE8CE0E3E6F3E045 -:10E17000DE01119601900D928A95E1F770E060E062 -:10E1800080E50E94D3CABE016F5F7F4F0E947C2A48 -:10E1900045CEFF24F39401E011E0EACC1092A108EF -:10E1A0003DCE8FE08093A10839CE8092820290927A -:10E1B0008302A0928402B0928502032D19CE809131 -:10E1C000C2089091C3088837910511F40C9480F926 -:10E1D00008F097C18E34910509F4B5C508F0FDC06B -:10E1E0008931910509F4ABC408F094C084319105DC -:10E1F00009F44DC408F05EC08131910509F4F7C3FC -:10E2000098F5029708F042CC80E50E94D1C9C12C54 -:10E21000D12C7601882321F00E9437C76B017C0145 -:10E2200083E50E94D1C9882361F00E94A7C920E03C -:10E2300030E04AE754E40F94173A0F947B3F6B01A8 -:10E240007C010E947F8F8091C0089091C108009747 -:10E2500009F4C7C30F94450E40E0C701B6010E9400 -:10E260007CE80F948E10DACD429709F00FCC83E54D -:10E270000E94D1C9882309F401C70F941E1D609321 -:10E280003B0670933C0680933D0690933E060E94A9 -:10E29000A7C920E030E04AE754E40F94173A0F94FE -:10E2A0007B3F60935A0270935B0280935C02909371 -:10E2B0005D02B4CD8631910509F41BC408F416C47F -:10E2C0008731910509F41EC4489709F0DFCB80918E -:10E2D0009A06882309F428C480E090E0A8E4B2E418 -:10E2E00088A799A7AAA7BBA71C8E1D8E1E8E1F8E5E -:10E2F00019821A821B821C8210E000E020E0AE012D -:10E30000485D5F4FBE01645E7F4FCE0101960E9463 -:10E31000ECE584CD8E31910509F490C498F48B31ED -:10E32000910509F42AC408F40DC48C31910509F44F -:10E330007EC44D9709F0AACB8091A2178E7F80935F -:10E34000A2176CCD8B34910509F4F7C4D0F58F3149 -:10E35000910509F4D7C4809709F098CB8091A21752 -:10E3600082FF03C087FF0E947F8F8091A21784FFE6 -:10E3700055CD60E080E50E94E1CA182F682F80919A -:10E38000C0089091C1080E945EBE83E50E94D1C979 -:10E39000882381F00E9447C7AB01BC0140939E17C0 -:10E3A00050939F176093A0177093A11780E594E195 -:10E3B0000E94827C0E949279111130CD0E94A6BBEE -:10E3C0002DCD8C34910509F4BBC48D34910509F031 -:10E3D0005DCB81E00E9416BB21CD8C36910509F4FE -:10E3E00016C608F059C08535910509F485C638F57B -:10E3F0008235910509F432C6C8F48135910509F0DA -:10E4000045CB0E9447B70E9497CD0E94B48581E01A -:10E410000E9416BB68EE73E080E090E00E9421CD80 -:10E4200060E089E091E30E941D3BF8CC83359105C3 -:10E4300009F41CC68435910509F419CF27CB893618 -:10E44000910509F413C560F48C35910509F479C67A -:10E450008836910509F01ACB80E00E9439D8DECCCD -:10E460008A36910509F430C58B36910509F00ECB3B -:10E470001091510980E50E94D1C9811172C5812F87 -:10E4800090E01816190614F481E090E0E82FF0E00F -:10E49000EE52FA4F1082C2CC8137910509F4BDC506 -:10E4A000A8F48E36910509F463C508F4DAC48F36F2 -:10E4B000910509F470C58037910509F0E7CA41E07C -:10E4C00070E060E084EF90E30E94E2DC8537910524 -:10E4D00009F4CBC658F48237910509F4BEC68337D8 -:10E4E000910509F0D3CA0E94D3CE98CC8637910506 -:10E4F00009F4CBC68737910509F0C8CA0E9456B9FE -:10E500008DCC8D32E1E09E0711F40C94C9FC08F02B -:10E51000F4C08B3C910511F40C94E5FA08F064C04A -:10E520008139910509F4FCC698F48A37910511F4F4 -:10E530000C94DCFF08F4ECC68D37910509F4FFC29A -:10E540008C38910509F0A2CA80E00E94A1E366CC54 -:10E550008E3B910509F47DC568F58639910509F46E -:10E5600058C78B39910509F091CA83E50E94D1C93A -:10E57000882309F453CC0E945BC7182F8C3308F012 -:10E580008CE3809399080F941E1D6B017C01212F51 -:10E5900030E0A8EEB3E00F94F83DC60ED71EE81E9B -:10E5A000F91EC0929508D0929608E0929708F092D2 -:10E5B000980834CC883C910509F465C7893C9105DD -:10E5C00009F064CA8091BC0884FDD4C78091BE085C -:10E5D000887809F0CFC78091BF08837009F0CAC757 -:10E5E00081E00E943AD61ACC893D910511F40C9431 -:10E5F0000EFCA0F48D3C910511F40C946EFB10F40C -:10E600000C9419FB8E3C910511F40C94DBFB833DBB -:10E61000910509F03BCA0E94B5CF00CC8D3D910514 -:10E6200011F40C9471FC08F04AC08A3D910511F474 -:10E630000C9422FC8C3D910509F028CA82E40E94CA -:10E64000D4C5882341F080912002909121029093BB -:10E650005F0280935E0282E50E94D4C5882341F068 -:10E6600080915E0290915F0290932102809320023C -:10E6700083E50E94D1C9882331F00E9457C7909347 -:10E680002102809320028091BC089091BD08A09146 -:10E69000BE08B091BF08892B8A2B8B2B09F0BECB0B -:10E6A000609120027091210286E691E30E9487DA50 -:10E6B00085E20E949FCE8AE00E949FCEAFCB8A3F28 -:10E6C000910511F40C9427FD8C32914009F0DEC9BC -:10E6D00064E071E083E50E94D3CA8C0168EE73E0C8 -:10E6E00080E50E94D3CA8938B3E19B0710F088E81F -:10E6F00093E1B8010E948D2B91CB8C3032E09307CF -:10E7000011F40C9448FE08F04CC08C3A51E0950787 -:10E7100011F40C947AFDB0F48F32B1E09B0711F440 -:10E720000C9472FD10F40C942CFD8039F1E09F07DD -:10E7300011F40C9476FD8A39914009F0A7C90E9422 -:10E7400039B86CCB863F31E0930711F40C943AFE54 -:10E7500068F4843F51E0950711F40C9436FE853F30 -:10E76000914009F093C90E940FC558CB873FB1E093 -:10E770009B0711F40C943EFE883F914009F086C936 -:10E7800081E0809302060E9403C51092020688234E -:10E7900009F444CB0E940FD88FEE91E30E94ACCED7 -:10E7A0003DCB8E3BF2E09F0711F40C9405FF08F07F -:10E7B000F8C0883532E0930711F40C945EFE38F40B -:10E7C0008933924009F062C90E940EDB27CB8B355A -:10E7D000A2E09A0711F40C9462FE8D3B924009F07E -:10E7E00055C90E9413D8082F87FD18CB8AE50E94CF -:10E7F000D1C9882311F40C94EFFE8AE50F9484129A -:10E80000762E872E982EC92E402F63E085E00E9439 -:10E81000092E10915109A02E002E000CBB081A15CC -:10E820001B0421F060E0802F0E947DB520917E02C4 -:10E8300030917F02409180025091810260E070E04F -:10E8400086E193E40F94073ED62EE72EF82E092F8B -:10E85000272D382D492D5C2D0F94684018161CF477 -:10E86000D72C74010C2D8D2D9E2DAF2DB02F88AB84 -:10E8700099ABAAABBBAB20E030E0A9016D2D7E2D9A -:10E880008F2D902F0F94B139882321F0CE01C0969F -:10E890000F94862780E090E0A8E4B2E48CA79DA7BF -:10E8A000AEA7BFA780E090E0A0EAB2E488A799A74E -:10E8B000AAA7BBA78CE40E94D1C9882311F40C94A9 -:10E8C000F7FE0E94A7C96B017C0120E030E0A9019E -:10E8D000C701B6010F94684087FF04C0F7FAF094AF -:10E8E000F7F8F094CC8EDD8EEE8EFF8E87E18A9D58 -:10E8F000F0018B9DF00D1124E15CF94FE084F1846F -:10E9000034E0E316F104BCF020E030E040E05FE3E7 -:10E9100064817581868197810F94083E0F94743FBE -:10E920006E197F0977FF03C071956195710901E048 -:10E93000643071050CF400E053E0E52E2AE0AE01EE -:10E94000445D5F4FBE01645E7F4FCE0188960F9499 -:10E950008D1268A979A98AA99BA96B017C01F7FA94 -:10E96000F094F7F8F094C982DA82EB82FC8220E01E -:10E9700030E0A9010F94B139882321F0CE0101962E -:10E980000F94862780915109181721F060E0812F9C -:10E990000E947DB580915109809300040E945E2DF4 -:10E9A0003DCA803AE3E09E0709F49FC168F48A38C3 -:10E9B00023E0920711F40D942B008739934009F05E -:10E9C00065C80E94AED62ACA873E43E0940711F478 -:10E9D0000D94BA00893E934009F058C80F9434064C -:10E9E0001DCA60E08EEB9FE20E941D3B35CC0E9469 -:10E9F000C3C58823B9F185E40E94D4C5882361F09A -:10EA000080919E0890919F08892B39F10E9457C7E9 -:10EA1000823010F40E94048A3CE9E32E32E0F32EA7 -:10EA200010E0D7012D917D0121548091BC08909177 -:10EA3000BD08A091BE08B091BF0804C0B695A795C7 -:10EA4000979587952A95D2F780FF03C0812F0E9462 -:10EA5000138A1F5F133029F7E1C980E00E94D8872D -:10EA600081E0D8CF60E081ED9FE20E941D3B80E015 -:10EA70000E94138A81E00E94138A82E00E94138A16 -:10EA800080E00E94D88781E00E94048AC7C98091F3 -:10EA9000A21784FF24C089EE9FE20E94ACCE809131 -:10EAA000A21784FF17C084EA94E10E945F808BE183 -:10EAB000E4EAF4E1DE01119601900D928A95E1F706 -:10EAC00070E060E0CE0101960E94D6BFCE010196B3 -:10EAD0000E9464808AED9FE20E94ACCE9FC90E9492 -:10EAE0000FD88AEF9FE20E94ACCE98C90E948F7E19 -:10EAF00095C98091A21782FF02C087FF8FC90E942B -:10EB0000777E8CC98091C0089091C108FC01219149 -:10EB1000222331F02032D9F7DF0111971C92F7CF71 -:10EB200060E00E945EBE7AC90E9473CD882321F006 -:10EB30000E9492790E94A6BB0F948E106FC90E940A -:10EB4000C4EA6CC98091A21784FF68C983E50E945A -:10EB5000D1C9882309F462C90E9447C7AB01BC012F -:10EB600040939E1750939F176093A0177093A1171F -:10EB700080E594E10E94827C51C98091BC0890910B -:10EB8000BD08A091BE08B091BF0822E0B695A79538 -:10EB9000979587952A95D1F780FF1CC08EE090E36A -:10EBA0000E94ACCE80915314882379F0BE016F5F30 -:10EBB0007F4F80E594E10E94F77ECE0101960F948D -:10EBC000D6268AE00E949FCE29C984E090E30E9465 -:10EBD000ACCEF7CF8091A21782FF24C0C0909E17C1 -:10EBE000D0909F17E090A017F090A1178DE190E3CF -:10EBF0000E94ACCEC701B6010F94C00D8FE20E94F7 -:10EC00009FCE60919A1770919B1780919C1790915D -:10EC10009D170F94C00D8DE00E949FCE8AE00E9448 -:10EC20009FCEFCC88FE290E30E94ACCEF7C88091E3 -:10EC3000C0089091C1080E948CBFF0C88091A217B3 -:10EC400084FFECC80F945F128091A21784FFE6C87E -:10EC50004091C0085091C108BE01645E7F4F80E0C2 -:10EC60000F94BD0C8C01009709F4D8C86C8D7D8D74 -:10EC700019821C8222E0AC01CE0101960E946A80BA -:10EC8000811115C0F12CCE0101960E946480B8015B -:10EC9000FF2011F18BE590E30F94E22610929E176E -:10ECA00010929F171092A0171092A117B7C8CE010B -:10ECB00001960F94290C882329F361E0CE01019677 -:10ECC0000E940F7E0097F1F225EEFC0120831C824A -:10ECD0000E94287AF82ED7CF83E490E30E94E0DDEB -:10ECE00080E490E30E94ACCE99C82091C008309196 -:10ECF000C1089091A21792609093A217C9010E9437 -:10ED00008CBF8CC80E94E4BA6C8F7D8F8E8F9F8FD2 -:10ED1000BE016F5F7F4FCE014C960E9458C6CE0158 -:10ED200001960F94450E0E940FD8BE016F5F7F4F72 -:10ED300089E690E30F94E22671C80E94A6BB6EC8D4 -:10ED40000E94FFBB6BC870E060E083E50E94C4CA0C -:10ED50008E34910529F40E94DE8E0F948E105EC8C9 -:10ED600084ED90E30E94ACCE6091D2087091D308FC -:10ED70008BEC90E30E947BDA6091D4087091D50807 -:10ED80008EEB90E30E947BDA6091D2087091D308F9 -:10ED90008091D4089091D508681B790B8091860FDB -:10EDA000815021E030E0823010F030E020E0621B42 -:10EDB000730B83EB90E30E9404DB8BEA90E30E94E9 -:10EDC000ACCE8091D6089091D708A091D808B09188 -:10EDD000D9088C8F9D8FAE8FBF8FBE016F5F7F4F25 -:10EDE000CE014C960E9458C6BE016F5F7F4F8EE9E0 -:10EDF00090E30E94E0DD8091DA089091DB08A09119 -:10EE0000DC08B091DD088C8F9D8FAE8FBF8FBE0167 -:10EE10006F5F7F4FCE014C960E9458C6BE016F5F58 -:10EE20007F4F8EE890E30E94E0DD20E030E04AE78B -:10EE300054E46091DE087091DF088091E0089091C1 -:10EE4000E1080F94023FAB01BC0186E790E30E940A -:10EE5000A4CF8DE60E949FCE8AE00E949FCE0C94A4 -:10EE60000EEF81E00E9439D80C940EEF0E9413D867 -:10EE7000182F87FD0AC08CED90E30E94ACCE812F45 -:10EE80000E949E848AE00E949FCEE196CFACE197DB -:10EE9000C0925009C357DF4F0FB6F894DEBF0FBEC4 -:10EEA000CDBFDF91CF911F910F91FF90EF90DF9039 -:10EEB000CF90BF90AF909F908F907F906F905F901A -:10EEC0004F903F902F9008951091510980E50E9436 -:10EED000D1C981113EC0812F90E01816190614F493 -:10EEE00081E090E0182F8091BC08EE24EA94F12C88 -:10EEF00080FF08C0E0915109F0E0EE52FA4F6081C6 -:10EF0000E62EF12C89E40E94D1C9882311F40D94D6 -:10EF1000F9000E945BC790E01816190614F481E00E -:10EF200090E026E0289FF001299FF00D1124EE507B -:10EF3000FA4FE480F580E12FF0E0EE52FA4FB7018E -:10EF40006F3F710519F010F06FEF70E060830C9463 -:10EF50000EEF0E945BC7182F823010F00C940EEF5A -:10EF6000C2CF0E945BC7823010F00C940EEF8ECAA5 -:10EF70008EE40E94D1C9882311F40C940EEF0E94F4 -:10EF800047C760930E1070930F10809310109093EA -:10EF900011100C940EEF83E50E94D1C9882321F053 -:10EFA0000E945BC78093D4050E940FD88DEE90E33A -:10EFB0000E94ACCE8091D405882331F110E000E0AE -:10EFC00020E08091D40590E0002E02C095958795B1 -:10EFD0000A94E2F780FF12C0FF24F394F20E22237A -:10EFE00019F08CE20E949FCEF801EE0FFF1FED5149 -:10EFF000FF4C859194910E94ACCE2F2D0F5F1F4F37 -:10F0000005301105F1F6DDCD8FED90E3E0CD1092E6 -:10F010004F09109274020C940EEF83E50E94D1C93F -:10F02000882369F00E945BC78D3320F480935902D6 -:10F030000C940EEF8CE3809359020C940EEF0E9417 -:10F040000FD86091590282E091E30E947FD60C9420 -:10F050000EEF81E00E94A1E30C940EEF8091A108D5 -:10F060008F7D80618093A1080C940EEF8091A108A0 -:10F070008F7E80628093A1080C940EEF0E94C3C51E -:10F080008823B1F10E947F8F85E40E94D4C5882334 -:10F0900051F080919E0890919F08892B31F10E9438 -:10F0A00057C70E94E489BCE9EB2EB2E0FB2E10E0CA -:10F0B000D7012D917D0121548091BC089091BD080C -:10F0C000A091BE08B091BF0804C0B695A7959795CA -:10F0D00087952A95D2F780FF03C0812F0E9400B741 -:10F0E0001F5F133029F70C940EEF0E94FE89DBCFCF -:10F0F0000E9447B70C940EEF83E50E94D4C5882385 -:10F1000011F40C940EEF0F941E1D60933B06709348 -:10F110003C0680933D0690933E060E94A7C920E0DE -:10F1200030E04AE754E40F94173A0F947B3F609322 -:10F130009A0870939B0880939C0890939D080C9468 -:10F140000EEF0E9413D887FF02C00C940EEF80913F -:10F15000BC0884FD09C08091BE0887FD05C0809170 -:10F16000BF08837009F474C0FCE9CF2EF2E0DF2EF3 -:10F17000A5E5EA2EA9E0FA2E10E0F60181916F01D3 -:10F180000E94D1C9882359F0133099F00E94A7C971 -:10F19000D70154966D937D938D939C9357971F5FE2 -:10F1A000B4E0EB0EF11C143041F70E945B8F0C941D -:10F1B0000EEF0E94A7C94B015C0120E030E040EA5D -:10F1C00051E40F94B13987FF3AC0A50194016091D1 -:10F1D00075097091760980917709909178090F945B -:10F1E000023F2B013C01AC019B01609185097091AC -:10F1F000860980918709909188090F94173A609346 -:10F200008509709386098093870990938809609196 -:10F21000CA057091CB058091CC059091CD050F94D6 -:10F22000B639A30192010F94173A0F947B3F609374 -:10F23000CA057093CB058093CC059093CD05809241 -:10F24000750990927609A0927709B0927809A7CFB4 -:10F2500081E00F9432120C940EEF0F94B2108FE1F4 -:10F2600096E10E94E6870C940EEF8091C008909181 -:10F27000C108009709F460CCFC012081222309F425 -:10F280005BCC0F94450E0C940EEF0091C0081091CA -:10F29000C10894E0F12C40E0915009F1D8018C9123 -:10F2A000282F2B7F2134A1F411962C912133B9F40E -:10F2B000813419F1853409F441E098012E5F3F4F04 -:10F2C00089012F5F3F4FD8018C918032C9F3E4CF81 -:10F2D000803529F4F801818180538A3070F341111F -:10F2E0000E940FD8FF2021F082E291E30E94ACCE71 -:10F2F000C8010E9425C50C940EEFFF24F394DDCFC6 -:10F300002093E3082093E2080E9471B90C940EEF59 -:10F310001092E3081092E2080E9471B90C940EEF6B -:10F3200070E060E083E50E94C4CA823040F00E9431 -:10F330000BD885E291E30E94ACCE0C940EEF8C01C9 -:10F34000112788E40E94D1C98823C1F00E9457C7C1 -:10F350008A3A91050CF44BC00E9457C7863F91052D -:10F360000CF048C00E9457C726E0209FF001219F63 -:10F37000F00D1124EE50FA4F9183808382E40E94B5 -:10F38000D1C98823A9F00E9457C70597B4F10E94FC -:10F3900057C785369105A4F50E9457C726E0209FE0 -:10F3A000F001219FF00D1124EE50FA4F93838283D8 -:10F3B00086E40E94D1C9882311F40C940EEF0E94B8 -:10F3C00057C797FD20C00E9457C78F3F910509F08E -:10F3D000ECF40E9457C726E0209FF001219FF00D1A -:10F3E0001124EE50FA4F958384830C940EEF8AEA31 -:10F3F00090E0BACF85EF90E0B7CF85E090E0CECF38 -:10F4000084E690E0CBCF90E080E0E5CF8FEF90E016 -:10F41000E2CF82E40E94D4C510E0882351F08091AD -:10F420009E0890919F081FEF892B19F00E945BC7DF -:10F43000182F85E50E94D4C500E0882351F0809103 -:10F440009E0890919F080FEF892B19F00E945BC7CF -:10F45000082F82E50E94D4C5882389F080919E08F8 -:10F4600090919F08892B69F00E945BC789830A836A -:10F470001B83CE0101960E94F6CA0C940EEF80E029 -:10F48000F5CF8FEFF3CF8091BC0883FD09C0809149 -:10F49000BE088C7029F481E00E9415DA0C940EEFFE -:10F4A0000E9413D8182F87FF02C00C940EEFF09023 -:10F4B000F10584E40E94D1C9082F882309F456C0BD -:10F4C0000E94A7C96B017C0120E030E0A9010F94E4 -:10F4D000B139882309F44CC0B4E01B02F0011124B7 -:10F4E000E751FA4FC082D182E282F38220E030E01D -:10F4F000A9016091E9057091EA058091EB05909171 -:10F50000EC050F94B13981110CC080E090E0A0EEC1 -:10F51000BFE38093E9059093EA05A093EB05B093D0 -:10F52000EC0520E030E0A9016091ED057091EE0559 -:10F530008091EF059091F0050F94B13981110CC0C5 -:10F5400080E090E0A0EEBFE38093ED059093EE05A0 -:10F55000A093EF05B093F005602F83E50E94E1CA08 -:10F560008093F1050E94E7710C940EEF0F2DF4CFFC -:10F5700080E0F6CF0E9413D887FF02C00C940EEFF4 -:10F580000CE912E075E5E72E79E0F72EE0EACE2EE1 -:10F59000E2E0DE2EF80181918F010E94D1C988231B -:10F5A00061F00E94A7C90F947B3FD7016D937D93B3 -:10F5B0008D939C9313970E940D8FB4E0EB0EF11C7A -:10F5C000C016D10639F70C940EEF8091BC0884FD6B -:10F5D0000DC08091BE08887849F48091BF0883707F -:10F5E00029F481E00E9410D60C940EEF0E9413D8EB -:10F5F00087FF02C00C940EEF6CE9E62E62E0F62E57 -:10F6000010E000E0F70181917F010E94D1C98823B9 -:10F6100049F00E94A7C9F801EB5AF64F64A375A3FD -:10F6200086A397A30C5F1F4F0031110559F70C9467 -:10F630000EEF8091BD0887FD09C08091BE088E70D5 -:10F6400029F481E00E94EED50C940EEF83E50E9430 -:10F65000D1C9882391F00E94A7C96093890970934A -:10F660008A0980938B0990938C0960939109709318 -:10F670009209809393099093940980E50E94D1C9DF -:10F68000882351F00E94A7C96093890970938A0961 -:10F6900080938B0990938C0982E50E94D1C98823BD -:10F6A00051F00E94A7C960938D0970938E098093D1 -:10F6B0008F099093900984E50E94D1C9882311F4A1 -:10F6C0000C940EEF0E94A7C9609391097093920960 -:10F6D00080939309909394090C940EEF8091BC0849 -:10F6E00081FD0DC08091BD0881FD09C08091BE08DB -:10F6F0008C7029F481E00E94B6D50C940EEF82E460 -:10F700000E94D1C9882351F00E9437C760936509D0 -:10F7100070936609809367099093680983E50E9456 -:10F72000D1C9882351F00E94A7C9609395097093AD -:10F730009609809397099093980984E50E94D1C90E -:10F74000882351F00E94A7C96093990970939A0980 -:10F7500080939B0990939C098AE40E94D1C98823D5 -:10F7600011F40C940EEF0E94A7C96B017C012AE0F2 -:10F7700037ED43E25CE30F94684087FD14C02AE94B -:10F7800039E949E95EE3C701B6010F94B1391816AA -:10F7900054F0C092FE05D092FF05E0920006F09270 -:10F7A00001060C940EEF0E940BD887E491E30E94AF -:10F7B000ACCE0C940EEF8091BC089091BD08A09146 -:10F7C000BE08B091BF084CE9C42E42E0D42E56EEDC -:10F7D000E52E58E0F52E10E0892B8A2B8B2B29F48F -:10F7E00081E00E9494D50C940EEFD6018D916D01AD -:10F7F0000E94D1C9882351F00E94A7C9F7016083F4 -:10F80000718382839383812F0E94FAB21F5FF4E099 -:10F81000EF0EF11C133049F70C9405EF8AE50E94B6 -:10F82000D1C9882351F00E94A7C9609386067093BE -:10F830008706809388069093890681E00E948ED681 -:10F840000C940EEF8091BC089091BD08A091BE0869 -:10F85000B091BF08892B8A2B8B2B29F481E00E9461 -:10F86000E4D90C940EEF0E9413D8182F87FF02C022 -:10F870000C940EEF88E50E94D1C9882361F00E94A4 -:10F88000A7C92CE01202F0011124E259F94F60835C -:10F8900071838283938389E50E94D1C9882361F0B3 -:10F8A0000E94A7C93CE01302F0011124E259F94F6C -:10F8B00064837583868397838AE50E94D1C98823F0 -:10F8C00011F40C940EEF0E94A7C94CE01402F00151 -:10F8D0001124E259F94F60877187828793870C94CE -:10F8E0000EEF0E9413D8082F87FF02C00C940EEF72 -:10F8F00083E50E94D1C9002E000C110B7801EE0C9B -:10F90000FF1C882361F10E9457C7F701EE5DFD4F90 -:10F9100091838083000F111F000F111FD801AA5D72 -:10F92000BD4F7D01BC01990F880B990B0F94B8391D -:10F930002AE037ED43E25CE30F94173A0A541A4F7A -:10F94000F80120813181428153810F94173AD70108 -:10F950006D937D938D939C9313970C940EEF0E945F -:10F960000FD885E40E949FCE80E3800F0E949FCE37 -:10F97000F701EE5DFD4F608171818AE691E30E949F -:10F9800087DA85E20E949FCE8AE00E949FCE0C9487 -:10F990000EEF85E40E94D1C9882381F00E945BC7E5 -:10F9A0009091BC0893FD0CC09091BD08917841F4F2 -:10F9B000682F81E00E9493D90C940EEF8FEFF0CF67 -:10F9C0008230ECF580E50E94D1C9882351F00E9475 -:10F9D000A7C960934A0670934B0680934C06909398 -:10F9E0004D0689E40E94D1C9882381F00E94A7C9ED -:10F9F0002CEA35EC47E25EE30F94173A60934E062B -:10FA000070934F06809350069093510684E40E94B1 -:10FA1000D1C9882311F40C940EEF0E94A7C92CEAD7 -:10FA200035EC47E25EE30F94023F60935206709319 -:10FA3000530680935406909355060C940EEF0E9443 -:10FA40000BD882E791E30E94ACCE0C940EEF81E0DC -:10FA50000E9484D60C940EEF83E50E94D4C5182F23 -:10FA6000882369F00E9457C79C019093610280939C -:10FA7000600291E0232B09F090E09093A00880E5CC -:10FA80000E94D4C5882361F0209160023091610208 -:10FA9000232B11F00E946FC78093A0080C940EEFE7 -:10FAA00011110C940EEF0E940FD880EA91E30E948E -:10FAB000ACCE8091A008882391F088E891E30E9461 -:10FAC000ACCE60916002709161028FE891E30E9478 -:10FAD00087DA8BE891E30E94ACCE0C940EEF84E8B9 -:10FAE00091E3EDCF0E94CFD00C940EEF0E947F8F58 -:10FAF0000C940EEF0F94321181110C940EEFB6EBB3 -:10FB0000CB2EB4E1DB2EE6E7F2E0FDABECAB9E01E1 -:10FB10002F5F3F4F19018901F12CE12CF60165910E -:10FB2000759185919491ACA9BDA98D909D90AD9052 -:10FB3000BD90BDABACABA50194010F94073E2B016A -:10FB40003C01F801408251826282738220E030E001 -:10FB500040EA51EC0F94684087FD0AC020E030E095 -:10FB600040EA51E4C301B2010F94B139181684F48C -:10FB7000F701E253F44CE4911E1654F4B7FAB09432 -:10FB8000B7F8B094D8018D929D92AD92BC92139724 -:10FB9000F80180809180A280B38020E030E040EACC -:10FBA00051ECC501B4010F94684087FD4AC020E0C4 -:10FBB00030E040EA51E4C501B4010F94B1391816A0 -:10FBC0000CF43FC0FFEFEF1AFF0A24E0C20ED11C75 -:10FBD0000C5F1F4F33E0E316F10409F09FCFA6EE50 -:10FBE000EA2EA8E0FA2E10E0F10181919191A19105 -:10FBF000B1911F01F70181939193A193B1937F017B -:10FC0000812F0E94FAB21F5F133071F70E94BBB8B8 -:10FC100060E083EB91E30E941D3B63E972E084E6C0 -:10FC200090E00E948D2B70E060E08AE090E00E94FE -:10FC30008D2B6AEB72E084E690E00E948D2B0C9491 -:10FC40000EEF0E940BD881ED91E30E94ACCE61E0F3 -:10FC500083EC91E30E941D3B0E945E2D68E270E000 -:10FC600080E991E00E948D2B0C940EEF0E94648B32 -:10FC70000C940EEF0E947CB90C940EEF61E083E5CA -:10FC80000E94E1CA91E089270E942E8A0C940EEF0F -:10FC90001091A21712FF0AC017FD08C00E9473CD71 -:10FCA00080FB17F91093A2170C940EEF14FD02C0FD -:10FCB0000C940EEF0F945F120C940EEF0E946CE9FF -:10FCC0000C940EEF8091BD0883FD09C08091BE08A1 -:10FCD000887129F481E00E94C7DB0C940EEF0E942A -:10FCE00013D8082F87FF02C00C940EEF85E50E9401 -:10FCF000D1C9882359F10E94A7C94B015C01E02EAC -:10FD0000002E000CFF0820E030E0A9010F946840AD -:10FD100087FF04C0B7FAB094B7F8B09420E030E0A1 -:10FD200048E453E4C501B4010F9468409701F3E03F -:10FD3000220F331FFA95E1F727523A4F1816D4F1E4 -:10FD4000D9018D929D92AD92BC9213978CE40E9442 -:10FD5000D1C9882311F40C940EEF0E94A7C96B013E -:10FD60007C01002E000C110B20E030E0A9010F9463 -:10FD7000684087FF04C0F7FAF094F7F8F09420E0A9 -:10FD800030E048E453E4C701B6010F94684098019D -:10FD9000E3E0220F331FEA95E1F727523A4F181696 -:10FDA0009CF0D9011496CD92DD92ED92FC921797BA -:10FDB0000C940EEF80E090E0A8E4B3E4F9018083B6 -:10FDC0009183A283B383C2CF80E090E0A8E4B3E440 -:10FDD000F90184839583A683B7830C940EEF712C6D -:10FDE000812C60EA962E71E4C72E0C9404F4E09105 -:10FDF000510928E0E29FF0011124E752FA4FC48034 -:10FE0000D580E680F7800C9465F40E9413D8082F03 -:10FE100087FF02C00C940EEF8AE50E94D1C9812CA5 -:10FE2000912C40EAA42E41E4B42E882329F08AE5DF -:10FE30000F9484124B015C01402F64E083E00E9428 -:10FE4000092E10915109E02E002E000CFF081E15FE -:10FE50001F0421F060E0802F0E947DB520E030E09B -:10FE6000A901C501B4010F94684018167CF580E023 -:10FE700090E0A0EAB0E489839A83AB83BC832091AD -:10FE80007E0230917F024091800250918102C50133 -:10FE9000B4010F94083E2B013C0120E030E046E124 -:10FEA00053E40F94B13987FD06C0412C512C36E143 -:10FEB000632E33E4732E4C8E5D8E6E8E7F8EBE016C -:10FEC0006F5F7F4FCE014C960E94C4B485E50E94BF -:10FED000D4C5882309F463C00E94A7C96B017C01C3 -:10FEE00020E030E0A901C701B6010F94684087FF08 -:10FEF00004C0F7FAF094F7F8F094F7FAF094F7F8F2 -:10FF0000F094C982DA82EB82FC8244E061E0CE01A7 -:10FF100001960E9457E720E030E0A901C501B40135 -:10FF20000F94684018165CF580E090E0A0EAB0E419 -:10FF300089839A83AB83BC83A501940160917E027F -:10FF400070917F0280918002909181020F94073E10 -:10FF50006B017C0120E030E0A9010F946840181685 -:10FF60001CF0C12CD12C7601CC8EDD8EEE8EFF8E56 -:10FF7000BE016F5F7F4FCE014C960E94C4B480914A -:10FF80005109181721F060E0812F0E947DB5809102 -:10FF90005109809300040E945E2D0C940EEFF7012E -:10FFA00023E0EE0FFF1F2A95E1F7E752FA4FC080DA -:10FFB000D180E280F38094CF19821A821B821C8246 -:10FFC0004091BC085091BD086091BE087091BF0877 -:10FFD000ECE9F2E0DE01119691E021E0819181549B -:10FFE0006A017B0104C0F694E794D794C7948A957C -:10FFF000D2F7C0FE02C02C9390E0119682E0E03A66 -:020000022000DC -:10000000F80761F7992329F081E089838A838B833C -:100010008C8360E089E40E94E1CA8823A1F08FEA22 -:1000200095E10F94843383E795E10F94843387E35C -:1000300095E10F9484338BEF94E10F9484338FEB2D -:1000400094E10F9484332C814B816A8189810E94D1 -:10005000FEDB0C940EEF9CE9C92E92E0D92EEE2423 -:10006000E394F12C70E060E0D6018D916D010E9467 -:10007000C4CA8C010097D9F1B2E0FB16C1F0E3E0ED -:10008000FE16E9F0F1E0FF1651F09093E915809328 -:10009000E815BC018FEA95E10F940F2127C09093DA -:1000A000AD158093AC15BC0183E795E1F5CF909336 -:1000B000711580937015BC0187E395E1EDCF6EEF6C -:1000C0007FEF84E50E94C4CA823008F050C0E82E59 -:1000D00018160CF49AC01093351500933415B80116 -:1000E0008BEF94E10F940F21E11092C0E12CF39477 -:1000F00024E0F212B7CFEE2011F40C940EEF88E555 -:100100000E949FCE6091E8157091E9158AEF91E306 -:100110000E9404DB89E50E949FCE6091AC1570912E -:10012000AD158CE092E30E9404DB8AE50E949FCE2D -:1001300060917015709171158EE192E30E9404DB5D -:1001400085E40E949FCE609134157091351580E34F -:1001500092E30E9404DB0E94A6CE6091F814709195 -:10016000F91482E492E30E9404DB0C940EEF8EEF0C -:10017000E82EB1CF83E0809335091092441260E0FD -:1001800083E50E94E1CA81110C940EEF0F94330FA6 -:100190000C940EEF1091C2080F941E1D60933B0645 -:1001A00070933C0680933D0690933E06812F012E6E -:1001B000000C990B209151092817190651F060E0A5 -:1001C00083E50E94E1CA682F812F0E947DB50C94BF -:1001D0000EEF81E0F8CFF11004C0002311F40C946D -:1001E0006AEE612C712C70EA872EE0E49E2E0C944E -:1001F000CAED83E50E94D1C9882311F40C949BF7C2 -:100200000E9447C77B010C949BF7813009F06ECFA9 -:100210001093F9140093F814B8018FEB94E13CCFDC -:1002200020E030E0A901C701B6010F94B13988235D -:1002300011F40C943BED1CAA1DAA1EAA1FAAA7012B -:100240009601505828AF39AF4AAF5BAF8CA99DA932 -:10025000AEA9BFA9B0588CAF9DAFAEAFBFAFA701DD -:100260009601C701B6010F94173A4B015C012CA906 -:100270003DA94EA95FA9CA01B9010F94173A9B0184 -:10028000AC01C501B4010F94083E0F94B640A89686 -:100290006CAF7DAF8EAF9FAFA897809076029090A5 -:1002A0007702A0907802B0907902A7019601C5016B -:1002B000B4010F94083EE9966CAF7DAF8EAF9FAF4F -:1002C000E997C0907A02D0907B02E0907C02F09097 -:1002D0007D022496CCAEDDAEEEAEFFAE2497A70134 -:1002E00096016CA97DA98EA99FA90F94083EED9651 -:1002F0006CAF7DAF8EAF9FAFED9740908A06509068 -:100300008B0660908C0670908D06E9962CAD3DAD05 -:100310004EAD5FADE997C301B2010F94073E289639 -:100320006CAF7DAF8EAF9FAF2897C0908E06D090F8 -:100330008F06E0909006F0909106ED962CAD3DADC5 -:100340004EAD5FADED97C701B6010F94073E2C96F9 -:100350006CAF7DAF8EAF9FAF2C97A3019201C5010B -:10036000B4010F94073E4B015C012DEB37E346E8E7 -:1003700055EB0F94684087FF02C00C943DEF2DEBC6 -:1003800037E346E855E3C501B4010F94B1391816B7 -:1003900014F40C943DEFA701960124966CAD7DAD4D -:1003A0008EAD9FAD24970F94073E6B017C012DEB22 -:1003B00037E346E855EB0F94684087FF02C00C9482 -:1003C0003DEF2DEB37E346E855E3C701B6010F9447 -:1003D000B139181614F40C943DEF0230110511F0E8 -:1003E0000C94DAEF08E410E08BED482E8FE0582EE5 -:1003F00089EC682E80E4782E9BEDC92E9FE0D92EE3 -:1004000099ECE92E90ECF92E20917E0230917F023A -:10041000409180025091810260962CAF3DAF4EAF6B -:100420005FAF6097609192067091930680919406F9 -:10043000909195060F94073E4B015C01A301920138 -:10044000A8966CAD7DAD8EAD9FADA8970F94173A71 -:1004500021966FAF219725967FAF259729968FAF6D -:10046000299765969FAF659727E137EB41ED58E3F4 -:100470000F94B13987FF0AC027E137EB41ED58E30C -:10048000C501B4010F94B13987FD70C38091960600 -:1004900090919706A0919806B091990669968CAFB5 -:1004A0009DAFAEAFBFAF69972091820230918302BA -:1004B000409184025091850264962CAF3DAF4EAFBF -:1004C0005FAF64972AE037ED43E25CE3609151024D -:1004D0007091520280915302909154020F94173AF6 -:1004E0002B013C016091200270912102072E000C2B -:1004F000880B990B0F94B8399B01AC01C301B20171 -:100500000F94173A68A779A78AA79BA721966FAD82 -:10051000219725967FAD259729968FAD29976596CA -:100520009FAD65970F94AA3F1B012C01B80190E085 -:1005300080E00F94B6393B018C019B01AC01B10105 -:10054000C2010F946840181614F43101820193011E -:10055000A80121966FAD219725967FAD2597299605 -:100560008FAD299765969FAD65970F94023F1B014C -:100570002C0120E030E040E85FE30F94684018165B -:1005800014F00C94E8EF21966FAD219725967FAD7E -:10059000259729968FAD299765969FAD65970F94FE -:1005A000E63E0F947B3F6B967FAF6EAF6B971C8ED2 -:1005B0001D8E1E8E1F8E18A219A21AA21BA21CA28B -:1005C0001DA21EA21FA26B964EAD5FAD6B9742306F -:1005D000510508F4A1C2BA0190E080E00F94B63949 -:1005E000A4966CAF7DAF8EAF9FAFA4979B01AC017B -:1005F000C701B6010F94023F6F966CAF7DAF8EAF0F -:100600009FAF6F979B01AC010F94173A6B017C0170 -:10061000AC019B016F966CAD7DAD8EAD9FAD6F97BC -:100620000F94173A20E030E040EC50E40F94023F82 -:100630009B01AC016F966CAD7DAD8EAD9FAD6F979C -:100640000F94073EC358DF4F688379838A839B8367 -:10065000CD57D04020E030E040E05FE3C701B60175 -:100660000F94173A9B01AC0160E070E080E89FE3D3 -:100670000F94073ECF57DF4F688379838A839B832C -:10068000C158D040A4962CAD3DAD4EAD5FADA49702 -:10069000C501B4010F94023FCB57DF4F68837983C4 -:1006A0008A839B83C558D04064962CAD3DAD4EAD3A -:1006B0005FAD649769966CAD7DAD8EAD9FAD69976A -:1006C0000F94073EA4962CAD3DAD4EAD5FADA49703 -:1006D0000F94023FC757DF4F688379838A839B83D8 -:1006E000C958D0406096CCACDDACEEACFFAC6097A6 -:1006F000C986DA86EB86FC866496CCACDDACEEACC3 -:10070000FFAC6497CD86DE86EF86F88A0F941E1DB7 -:100710009B01AC0128533F4F4F4F5F4FE5962CAFE5 -:100720003DAF4EAF5FAFE597C0905909D0905A09E1 -:10073000E0905B09F0905C09609155097091560951 -:100740008091570990915809C616D706E806F90610 -:1007500010F4C701B6010F94B639AC966CAF7DAFFB -:100760008EAF9FAFAC97A0907909B0907A090091B5 -:100770007B0910917C09C701B6010F94B6396B0152 -:100780007C019B01AC01B501C8010F94B13987FF11 -:1007900002C06501780168A579A58AA59BA59B0182 -:1007A000AC010F94173A2D966FAF2D9761967FAFDE -:1007B00061971C01AC962CAD3DAD4EAD5FADAC97D5 -:1007C000A8966CAD7DAD8EAD9FADA8970F94173AEE -:1007D0005B018C019601A701B601C7010F94173A7E -:1007E0006B017C019501A8012D966FAD2D97619647 -:1007F0007FAD6197C1010F94684018163CF42D96A7 -:10080000AFAE2D976196BFAE619718012D962FADB3 -:100810002D9761963FAD6197A101B601C7010F9475 -:10082000B13987FF07C02D96CFAE2D976196DFAE09 -:10083000619717012196CFAC2197AD96CFAEAD97BA -:100840002596DFAC2597AE96DFAEAE972996EFAC36 -:100850002997AF96EFAEAF976596FFAC6597E09698 -:10086000FFAEE09748AC59AC6AAC7BAC29E1A096EE -:100870002FAFA09741E050E067965FAF4EAF67970C -:100880000E94A5910F941E1D8B019C01E596CCAC96 -:10089000DDACEEACFFACE5970C191D092E093F0944 -:1008A00037FD0FC09B01AC0128533F4F4F4F5F4FA7 -:1008B000E5962CAF3DAF4EAF5FAFE59780E00E946D -:1008C000EADDA0963FADA0973150A0963FAFA0972C -:1008D000332311F40C941EF0C358DF4F2881398163 -:1008E0004A815B81CD57D040B201C3010F94173AC2 -:1008F0006B017C01CF57DF4F288139814A815B81B1 -:10090000C158D0406CAD7DAD8EAD9FAD0F94173A00 -:100910009B01AC01C701B6010F94083E7B018C011D -:10092000CF57DF4F288139814A815B81C158D04040 -:10093000B201C3010F94173A4B015C01C358DF4F5A -:10094000288139814A815B81CD57D0406CAD7DAD26 -:100950008EAD9FAD0F94173A9B01AC01C501B40158 -:100960000F94073E2B013C01C701D8018CAF9DAF0E -:10097000AEAFBFAF9201A301E9966CAD7DAD8EAD78 -:100980009FADE9970F94083E69837A838B839C839C -:100990002CAD3DAD4EAD5FADED966CAD7DAD8EAD8C -:1009A0009FADED970F94083E6D837E838F8398876C -:1009B000CB57DF4F288139814A815B81C558D040B0 -:1009C00069857A858B859C850F94083E69877A872F -:1009D0008B879C87C757DF4F288139814A815B818C -:1009E000C958D0406D857E858F8598890F94083EC3 -:1009F0006D877E878F87988BCE0101960E941AB3F0 -:100A0000A4962CAD3DAD4EAD5FADA49721966FADD4 -:100A1000219725967FAD259729968FAD29976596C5 -:100A20009FAD65970F94023F9B01AC01AD966FADF2 -:100A3000AD97AE967FADAE97AF968FADAF97E09680 -:100A40009FADE0970F94073EAD966FAFAD97AE9612 -:100A50007FAFAE97AF968FAFAF97E0969FAFE0971F -:100A6000AC962CAD3DAD4EAD5FADAC97CA01B901B2 -:100A70000F94083EAD962FADAD97AE963FADAE97B5 -:100A8000AF964FADAF97E0965FADE0970F94173AF2 -:100A90007B018C012D962FAD2D9761963FAD61970F -:100AA000A1010F94684018163CF42D96EFAC2D97D9 -:100AB0006196FFAC61978101C701D8018CA39DA30A -:100AC000AEA3BFA39E01245E3F4F40915109BE01DA -:100AD000685D7F4FCE0101960E94ACA68823E1F0AD -:100AE000A896CCACDDACEEACFFACA897C8A2D9A25E -:100AF000EAA2FBA267962EAD3FAD67972F5F3F4FEF -:100B000067963FAF2EAF67976B96CEACDFAC6B9717 -:100B1000C216D30609F0B4CE80E1EAE8F6E0DE01C1 -:100B2000119601900D928A95E1F7CE0101960E94EF -:100B30001AB318A219A21AA21BA21CA21DA21EA2BD -:100B40001FA29E01245E3F4F40915109BE01685D86 -:100B50007F4FCE0101960E94ACA680E1FE01319646 -:100B6000A6E7B2E001900D928A95E1F70F941E1D61 -:100B700060933B0670933C0680933D0690933E063F -:100B80000C940EEF4F925F926F927F928F929F9292 -:100B9000AF92BF92CF92DF92EF92FF920F931F938B -:100BA000CF93DF93CDB7DEB77C014DB65EB66090D4 -:100BB0005309709054098DB69EB66AE070E0C70183 -:100BC0000F94F3386C018C010E191F09892B21F445 -:100BD000C7010F94FE388C01C80101962DB73EB7AE -:100BE000281B390B0FB6F8943EBF0FBE2DBF8DB733 -:100BF0009EB701965C01A801B7010F941F39F5015A -:100C0000E00FF11F1082C5010E9457C881E00E94C9 -:100C1000D1EBC114D10451F076019FEFE91AF90A22 -:100C20000FB6F8949EBE0FBE8DBEC5CF0FB6F8941A -:100C30009EBE0FBE8DBEC3010E9457C80FB6F8946A -:100C40005EBE0FBE4DBEDF91CF911F910F91FF9001 -:100C5000EF90DF90CF90BF90AF909F908F907F905C -:100C60006F905F904F900895CF92DF92EF92FF9236 -:100C70000E947F8F8091A217877F8B7F8093A2171E -:100C800080919817811138C00E94E4BA6B017C01F1 -:100C90008DE3C816D104E104F10420F082E695E367 -:100CA0000F94C2058EE595E30F94C2058AE495E39F -:100CB0000E94ACCE8DE3C816D104E104F104A0F08B -:100CC0000E94F5CB81E08093C50840E060E477E7BF -:100CD0008BE190E00E947CE88091C508882321F098 -:100CE0000E94F1CB1092C50886E495E3FF90EF9047 -:100CF000DF90CF900D94C2050F941327882321F223 -:100D0000FF90EF90DF90CF900895CF93DF93C09145 -:100D1000761081E6C89FE0011124C858DF4E80910B -:100D2000D40580FF05C00E940FD8CE010E9425C5C2 -:100D3000CE010E9457C880E0DF91CF910C94D1EB97 -:100D4000FC01808108950F931F93CF93DF93582F59 -:100D5000FC0180E077E0919148E0282F30E0A92F56 -:100D6000B0E08901000F012F001F110B9170C92FF6 -:100D700090E0D92F880F0C171D0721F0C901880FAB -:100D8000991F8727B595A7959A2F415031F79E2F28 -:100D9000951B961700F3DF91CF911F910F91089546 -:100DA00008950895AF92BF92CF92DF92EF92FF9293 -:100DB0000F931F93CF93DF936C017B018B01040F83 -:100DC000151FEB015E01AE18BF08C017D10759F01F -:100DD0006991D601ED91FC910190F081E02DC60161 -:100DE0001995892B79F7C501DF91CF911F910F914B -:100DF000FF90EF90DF90CF90BF90AF9008953FB7F6 -:100E0000F8948091531890915418A0915518B0916E -:100E1000561826B5A89B05C02F3F19F00196A11DB5 -:100E2000B11D3FBFBA2FA92F982F8827BC01CD0134 -:100E3000620F711D811D911D42E0660F771F881F93 -:100E4000991F4A95D1F7089520912B18260F332723 -:100E5000331F21323105ECF420918518FC0190E01C -:100E600080E0243069F082E00895A0912B18219150 -:100E7000AC01455F574EA40FB52FB11D2C930196C1 -:100E8000861798F380912B18680F60932B1880E0D9 -:100E9000089581E008950895E0915C1880915B18B1 -:100EA000E81730F4F0E0E651F84E808190E00895C4 -:100EB0008FEF9FEF089590915C1880915B182FEF52 -:100EC0003FEF981748F4E92FF0E0E651F84E208103 -:100ED00030E09F5F90935C18C901089580915B1882 -:100EE00090915C18891B990B0895CF92DF92EF9235 -:100EF000FF920F931F93CF93DF937C01CB018A0165 -:100F00002091AE18222389F0EB016B01C40ED51E8F -:100F1000CC15DD0569F06991D701ED91FC91019047 -:100F2000F081E02DC7011995F3CF642F0F942407AA -:100F3000C801DF91CF911F910F91FF90EF90DF904B -:100F4000CF900895CF93DF931F92CDB7DEB769831B -:100F50002091AE182223F9F02091AB18203258F0DE -:100F600021E030E0FC013383228390E080E00F90A9 -:100F7000DF91CF9108958091AC18E82FF0E0E5570C -:100F8000F74E998190838F5F8093AC188093AB1854 -:100F900081E090E0ECCF61E0CE0101960F94240750 -:100FA000F7CF2091E8173091E9172817390771F426 -:100FB0009091E7178091E617981741F0E091E717B5 -:100FC000F0E0EA55F84E808190E008958FEF9FEFB2 -:100FD0000895EF92FF920F931F93CF93DF93DC015D -:100FE0005C96ED90FC905D97E114F10479F481E05A -:100FF00090E013969C938E93129790E080E0DF919F -:10100000CF911F910F91FF90EF9008955196ED9120 -:10101000FC91529750968C915097982F90950FB7BE -:101020005E962C915E97122F127021FD6095F894B8 -:101030002081112319F1282B2083E7012197F1F753 -:1010400028E0462F50E0308160FF1AC0382B3083F3 -:10105000E7012197F1F7BA0175956795215089F756 -:10106000112381F08081892380830FBF5C968D914D -:101070009C910197F1F781E090E0C1CF2923DCCF6B -:101080003923E5CF9081892BEFCF2091E81730915C -:10109000E9172817390771F48091E6172091E717AF -:1010A00090E0805C9F4F821B910960E470E00F9498 -:1010B0004841089590E080E008952091E81730912C -:1010C000E91728173907B9F49091E7178091E617C7 -:1010D000981789F0E091E717F0E0EA55F84E808123 -:1010E0002091E71730E02F5F3F4F2F733327209376 -:1010F000E71790E008958FEF9FEF0895E091E817CC -:10110000F091E917E817F90769F4A389B4899C916C -:101110008589809589238C931092E9171092E8179E -:1011200081E0089580E00895CF93DF93EC018A8DEC -:101130009B8D892B01F18091E8179091E9178C170D -:101140009D07C9F0009711F00F947E088E8D8E7F59 -:101150008E8F1092E6171092E717D093E917C0937D -:10116000E817EB89FC8980819D89892B808381E048 -:10117000DF91CF91089580E0FBCFFC01A4A5B5A538 -:10118000109749F0ED91FC9111970190F081E02DBD -:10119000CD011995089582A593A5009739F0DC013A -:1011A000ED91FC910190F081E02DF3CF80E0089566 -:1011B000FC01A4A5B5A5109741F0ED91FC91119704 -:1011C0000284F385E02DCD01199482A593A50097A3 -:1011D00039F0DC01ED91FC910284F385E02DF4CF30 -:1011E00090E080E00895FC01A4A5B5A5109741F01A -:1011F000ED91FC9111970084F185E02DCD011994BA -:1012000082A593A5009739F0DC01ED91FC91008453 -:10121000F185E02DF4CF90E080E00895DC01589650 -:101220004C91589760FB42F958964C935897242F4D -:1012300059964C915997342F337050E040E0ED911E -:10124000FC910190F081E02D60E01994DC01ED91BA -:10125000FC910280F381E02D6FE61994262F2F7008 -:10126000DC0195966C919597607F622B95966C93B7 -:10127000959792962D913D914D915C919597ED9119 -:10128000FC910190F081E02D6CE61994DC019496BC -:101290002C91949760FB21F994962C9394979296B5 -:1012A0002D913D914D915C919597ED91FC9101901F -:1012B000F081E02D6CE61994DC0193968C91939764 -:1012C00060FB87F993968C93939761FB882780F94D -:1012D00094966C9194976E7F682B94966C939497E8 -:1012E00092962D913D914D915C919597ED91FC9148 -:1012F00011970190F081E02D6CE6CD011994DC018D -:1013000092968C91929760FB87F992968C93929724 -:101310006695677093968C919397887F682B9396C8 -:101320006C93939792962D913D914D915C919597E9 -:10133000ED91FC9111970190F081E02D6CE6CD01CB -:1013400019946770262F2295207FDC0192966C916C -:1013500092976F78622B92966C93929792962D91BA -:101360003D914D915C919597ED91FC910190F081AB -:10137000E02D6CE61994DC01ED91FC910280F38183 -:10138000E02D6CE619940F94BB09892F8F70089596 -:101390000F94BB098695817008950F94BB09771F40 -:1013A0007727771F8170880F872B08950F94BB09CB -:1013B000862F881F8827881F7770770F872B0895BF -:1013C0000F94BB09862F8295877008952EE93FE020 -:1013D000009729F0F9013197F1F70197F9CF0895B6 -:1013E000089580E00895FC018491882321F08230E3 -:1013F00011F083E0089586E00895EF92FF920F9335 -:101400001F93CF93DF93EC01162FEC80FD80F70143 -:101410000491C7010F94F309A82F013049F10FEF90 -:101420002C813D81F9013A9644913196549133973C -:101430006491319684911136E8F070E0762F66273A -:10144000860F972F911D0097A9F08E0D9F1D41E6E5 -:10145000511730F5188A1B8A1C8A198A1A8A90E05B -:1014600080E0DF91CF911F910F91FF90EF90089551 -:101470000FE0D6CFF90136966491319684911134FC -:1014800060F070E0762F6627860F972F911D0097EA -:1014900021F08E0D9F1D41E4DBCFC7014196D8CFCF -:1014A0005417C0F2B0E0FC0164916F3F29F401963B -:1014B000451781F24F5FF7CF411333C0F9012491F3 -:1014C000AC014F5F5F4FFC01222311F0223091F4F9 -:1014D00024912B8BFA0144914C8BFC013396E491BF -:1014E000E88BFC013496E491E98BFC013596E4919C -:1014F000EA8BB7CF2491322F3F7032503A8B22952E -:101500002F70298BFA014491242F2F702C8B429538 -:101510004F704B8BFC013296E491E295EF70E88BB3 -:10152000A0CF3296649160236A0F7B2F711D860FC6 -:10153000971FBECF8EBD0DB407FEFDCF8EB50895AB -:101540000F93FC010150040F84A996A9941788F009 -:10155000081710F4041778F42150260F83A995A9D1 -:10156000961758F0281760F481E0261720F40F91A1 -:101570000895081778F780E0FACF2817A8F7FBCF6F -:1015800081E0F5CF0F94AC41FC01DB018C9120810F -:101590003181382798E0A901220F331F57FD05C07C -:1015A0009150C9F7318320830895B1E22B27B0E130 -:1015B0003B27F6CF8F929F92AF92BF92CF92DF924E -:1015C000EF92FF92CF93DF9390934F1480934E143A -:1015D0001092821482E090E0A0E0B0E080936B145F -:1015E00090936C14A0936D14B0936E1410924D14DC -:1015F0001092491410924A1410924B1410924C14E9 -:101600008FEF9FEFDC018093451490934614A093D5 -:101610004714B0934814662309F470C040E060E0BA -:1016200070E0CB010E94717A81110DC0C0E08C2F57 -:10163000DF91CF91FF90EF90DF90CF90BF90AF9070 -:101640009F908F900895809103148F7779F7809100 -:101650000F1490911014A0911114B09112148436AB -:101660009105A105B10510F3C0900B14D0900C1496 -:10167000E0900D14F0900E14C114D104E104F104B3 -:10168000A9F240E0C701B6010E94717AC82F8823F1 -:1016900069F280915012909151128115924031F669 -:1016A000A0915512AA2311F2609153127091541215 -:1016B0006115710509F4BACF20915212222309F461 -:1016C000B5CFA0937D1420936F1490E080E030E0BC -:1016D000E1E0F0E0D82FAF01082E02C0440F551F03 -:1016E0000A94E2F72417350769F041E0480F0196A4 -:1016F0008930910579F74093781498CFC12CD12C7B -:101700007601BFCF8093781420915B1230915C12E8 -:1017100050E040E02115310541F4209169123091EB -:101720006A1240916B1250916C1220937014309396 -:101730007114409372145093731446015701860E2E -:10174000971EA11CB11C80927E1490927F14A092CF -:101750008014B0928114E0915612F0915712F093D8 -:101760008414E0938314B0E00F94E53DDC01CB01D9 -:10177000880D991DAA1DBB1D809385149093861416 -:10178000A0938714B093881425E0EE0FFF1F2A95CD -:10179000E1F7E150FE4FEF2FFF27E6958E0F9F1FD9 -:1017A000A11DB11D8093791490937A14A0937B149A -:1017B000B0937C148090581290905912B12CA12CA7 -:1017C0008114910441F48090651290906612A0906B -:1017D0006712B0906812C81AD90AEA0AFB0AC80C44 -:1017E000D91CEA1CFB1C04C0F694E794D794C79458 -:1017F000DA95D2F7C0927414D0927514E0927614F0 -:10180000F092771485EFC8168FE0D806E104F10452 -:1018100020F48CE08093821409CF80E125EFC2167A -:101820002FEFD206E104F10488F0809171129091BB -:101830007212A0917312B0917412809385149093D8 -:101840008614A0938714B093881480E28093821446 -:10185000EECE8F929F92AF92BF92CF92DF92EF9295 -:10186000FF920F931F93CF93DF9300D01F92CDB7BA -:10187000DEB7FC018381813091F080E00F900F9002 -:101880000F900F90DF91CF911F910F91FF90EF90EC -:10189000DF90CF90BF90AF909F908F9008958181FF -:1018A00081FFEBCF81899289A389B489892B8A2B07 -:1018B0008B2B09F460C07F0140E050E0BA01CF01FA -:1018C0000E94827C8823C9F2F701C18CD28C858862 -:1018D0009688A788B08C82E090E0A0E0B0E0F601A6 -:1018E00080839183A283B3839E012F5F3F4FB50115 -:1018F000A401C6010E94457B882309F4BECF00E005 -:1019000010E09801B501A401C6010E94B37A8823B2 -:1019100009F4B3CF89809A80AB80BC80F6018789B7 -:10192000803101F5F8EF8F16FFEF9F06A104B10497 -:10193000D8F2F701158A168A178A108E118A128A30 -:10194000138A148A818180688183C7010E94297E5D -:10195000882309F492CF40E050E0BA01C7010E9409 -:10196000827C8CCF88EF88168FEF9806A8068FE0D0 -:10197000B806F8F6B9CF81E081CF2F923F924F920F -:101980005F926F927F928F929F92AF92BF92CF920F -:10199000DF92EF92FF920F931F93CF93DF9300D0CC -:1019A0001F92CDB7DEB7382E7B012DB73EB73C83F3 -:1019B0002B838091ED18811107C01092D2181092DC -:1019C000D51881E08093ED188091CA18811107C065 -:1019D0001092AF181092B21881E08093CA18DA0101 -:1019E0008C918F3209F08DC084EA94E1F7019183E4 -:1019F00080834F5F5F4F311010929717F70101906E -:101A0000F081E02DFA83E9838A0122EDC22E28E1DC -:101A1000D22E3BE1232E01151105E9F14DB65EB63C -:101A20006FE270E0C8010F94E2414C0108171907FA -:101A300068F53C01601A710A7724C30101962DB73D -:101A40003EB7281B390B0FB6F8943EBF0FBE2DBF13 -:101A50008DB79EB701965C01A301B8010F940242B5 -:101A6000F501E60DF71D1082C6010E945E7ED701CA -:101A70006D917C9121E0A501C6010E946A808111CF -:101A800046C0C5010E9455BE10E000E00FB6F894B4 -:101A90005EBE0FBE4DBE3320A9F0D701ED91FC9183 -:101AA0008BE1A9E8B4E101900D928A95E1F791E00C -:101AB00080919717811190E08091A21790FB86F991 -:101AC0008093A217C801EB81FC810FB6F894FEBF8A -:101AD0000FBEEDBF0F900F900F900F90DF91CF9141 -:101AE0001F910F91FF90EF90DF90CF90BF90AF903C -:101AF0009F908F907F906F905F904F903F902F902E -:101B0000089589E894E1D7018D939C9377CFF701ED -:101B10008081918129813A812817390711F00E942B -:101B20005E7ED701CD92DC92332099F0A091971779 -:101B3000AA3078F481E08A0F809397172A9ED0010B -:101B40001124A757B94EF601822D01900D928A9566 -:101B5000E1F7B2EDCB16B8E1DB0669F49FEAC92ED6 -:101B600098E1D92E84010F5F1F4F0FB6F8945EBE27 -:101B70000FBE4DBE50CF82EDC82E88E1D82EF2CFD9 -:101B80008F929F92AF92BF92EF92FF921F93CF934B -:101B9000DF93CDB7DEB7A0970FB6F894DEBF0FBEC8 -:101BA000CDBF611571058105910591F120E04AE0F5 -:101BB000842E912CA12CB12C11E0120FEE24E39471 -:101BC000F12CEC0EFD1EE20EF11C27FDFA94A5018E -:101BD00094010F94A43DF7016083B901CA01212F3C -:101BE000611571058105910539F7115018F1E1E092 -:101BF000F0E0EC0FFD1FE10FF11D17FDFA9590814C -:101C000087E39A3008F480E3890F0E949FCEEDCFDE -:101C100080E3A0960FB6F894DEBF0FBECDBFDF9174 -:101C2000CF911F91FF90EF90BF90AF909F908F90BA -:101C30000C949FCEA0960FB6F894DEBF0FBECDBF1A -:101C4000DF91CF911F91FF90EF90BF90AF909F9049 -:101C50008F900895CF92DF92EF92FF926B017C01FB -:101C6000F7FE0BC0F094E094D094C094C11CD11C3A -:101C7000E11CF11C8DE20E949FCEC701B601FF90CE -:101C8000EF90DF90CF900D94C00DCF93DF93209114 -:101C9000441221111EC0FC0101900020E9F7319788 -:101CA000EF01C81BD90BCB32D1052CF02291207C3F -:101CB0002038E1F3F5CFBC01DD27AE0189E192E1E7 -:101CC0000F940242C75EDD4E1882109218121092D5 -:101CD0001712DF91CF910895BF92CF92DF92EF92CA -:101CE000FF920F931F93CF93DF93EB01FC012381AE -:101CF000223008F49DC040855185628573854F71FF -:101D0000552766277727452B462B472B09F090C090 -:101D10008C011092FD111092FC11C12CDD24DA947B -:101D20007E01FBE0EF0EF11C8DE0B82E40E250E0AA -:101D3000BE01C8010E94167D8032910581F021E02C -:101D4000892B09F420E0822F8195DF91CF911F919B -:101D50000F91FF90EF90DF90CF90BF900895288172 -:101D6000222309F467C0253E11F02E3229F4109287 -:101D7000FD111092FC11DACF3B853F733F3009F023 -:101D800042C04A8D5B8D452B61F52F713FEF320FBD -:101D9000323038F58D85213041F1C81229C02150EB -:101DA000330BB29EC001B39E900D1124DC01A450F0 -:101DB000BE4EFE0120E02B30F0F0468157814F3FB0 -:101DC000510519F010F04FE550E04D932F5F32961A -:101DD0002D3089F7288126FF04C0FC01E75FFD4E06 -:101DE00010822B8523FDA2CFB0CFC82ED12CD7CF08 -:101DF000DD24D394D4CF253018F044815581DFCF32 -:101E000041815281DCCFD1100EC0FE0120E020FBC9 -:101E1000279527F93191230FEE16FF06C1F7C21659 -:101E200001F3DD24D3941092FD111092FC11D9CF4F -:101E30008FEF8BCF80E089CF9091771021E6929F32 -:101E4000F0011124E852FF4E80839F5F943040F4EC -:101E500090937710809175108F5F8093751008951F -:101E600010927710F7CFCF92DF92EF92FF92ECE8CB -:101E7000FFE080818183C0900E10D0900F10E09021 -:101E80001010F09011108FEFC81AD80AE80AF80A5B -:101E900082E89CE30E94ACCEC701B6010F942A0EE3 -:101EA0008AE00E949FCE8EE79CE3FF90EF90DF9048 -:101EB000CF900C94ACCECF92DF92EF92FF920F9323 -:101EC0001F93CF938C01C62F0E940BD8C0900E1089 -:101ED000D0900F10E0901010F0901110C8010E94E7 -:101EE000ACCEC701B6010F942A0E8AE00E949FCEA5 -:101EF0000E947BDD0196E1F78C2F0F94330F109237 -:101F0000131010921210CF911F910F91FF90EF902C -:101F1000DF90CF9008952F923F924F925F926F92F1 -:101F20007F928F929F92AF92BF92CF92DF92EF9269 -:101F3000FF920F931F93CF93DF93CDB7DEB76697D2 -:101F40000FB6F894DEBF0FBECDBF4C017B011A0166 -:101F50003E8B2D8B198A1A8AFB0180819181A28187 -:101F6000B3818F3F9105A105B10521F118F11D86BF -:101F70001E861F86188AAC01BD0137E076956795ED -:101F8000579547953A95D1F75A87498780688B8747 -:101F90008C870091890F10918A0F8091870F909103 -:101FA000880F9C8B8B8BAA24A394B12C011511054F -:101FB00009F050C0F7018081898BB401AE014F5EFA -:101FC0005F4FC101ED89FE89199566960FB6F894A9 -:101FD000DEBF0FBECDBFDF91CF911F910F91FF905C -:101FE000EF90DF90CF90BF90AF909F908F907F90B9 -:101FF0006F905F904F903F902F90089582179307B6 -:1020000020F19C818B85981708F445C09B818C85B5 -:102010008917D8F06091870F7091880F640D751D36 -:1020200048E050E0CE0109960F94DF386F8578893B -:102030006115710509F4BECF8616970609F4BECF67 -:10204000F70180818068898BB9CF86010A151B054D -:1020500008F4B0CF3501600E711E76946794630169 -:1020600091E0C91AD108260193E0440C551C9A95B9 -:10207000E1F76B897C89640D751D48E050E0CE0165 -:1020800001960F94DF3829813A8189859A8528172E -:10209000390708F0B3CF5301EFEFAE1ABE0AD6CF1F -:1020A0008F929F92AF92BF92CF92DF92EF92FF9268 -:1020B0000F931F93CF93DF9300D01F92CDB7DEB75E -:1020C0006C017B014A015901AE014F5F5F4FB401C2 -:1020D000C7010E94C23E7C0189819A81AB81BC818B -:1020E000892B8A2B8B2B49F09801A501BE016F5FCC -:1020F0007F4FC6010F948B0FE7CF0F900F900F907B -:102100000F90DF91CF911F910F91FF90EF90DF9093 -:10211000CF90BF90AF909F908F9008950E9481CDF7 -:1021200081111AC08091A21782FF0DC087FD0BC0DC -:102130008091FC11811104C089E79FE00D94450E48 -:102140008CEF91E1FBCF8091860F813041F08AE4E2 -:102150009CE36FEF0C941D3B81E79CE3FACF85E68F -:102160009CE3F7CF4F925F926F927F928F929F92F4 -:10217000AF92BF92CF92DF92EF92FF920F931F9395 -:10218000CF93DF93C6E7D2E04C845D846E847F8476 -:102190000DE61FE0F80124813581468157816C816D -:1021A0007D818E819F810F94083E4B015C01F80177 -:1021B0002085318542855385688579858A859B850B -:1021C0000F94083E6B017C01F8012081318142812E -:1021D0005381688179818A819B810F94083EAB018C -:1021E000BC0187E49CE30E94A4CFB501A40183E471 -:1021F0009CE30E94A4CFB701A6018FE39CE30E9459 -:10220000A4CFB301A2018BE39CE3DF91CF911F9197 -:102210000F91FF90EF90DF90CF90BF90AF909F9085 -:102220008F907F906F905F904F900C94A4CFCF933E -:10223000DF931F92CDB7DEB787E0898360E0CE01E0 -:1022400001960E94D9B261E0CE0101960E94D9B2F6 -:1022500062E0CE0101960E94D9B289810F90DF9190 -:10226000CF9108950F931F93CF93DF93CDB7DEB730 -:102270006E970FB6F894DEBF0FBECDBF0F94171147 -:102280008823E9F142EF53E082FF02C043EF53E0BD -:1022900022EF33E081FF02C025EF33E080FD2CC048 -:1022A00082EF93E05F934F933F932F939F938F938E -:1022B00089E29CE39F938F938E010F5F1F4F1F93C3 -:1022C0000F930F9448390E940FD8C8010E9425C56A -:1022D000C8010F94450E0FB6F894DEBF0FBECDBFF8 -:1022E00081E06E960FB6F894DEBF0FBECDBFDF91D2 -:1022F000CF911F910F91089587EF93E0D3CF80E0A6 -:10230000F0CFCF93DF938091091690910A16891B25 -:1023100080958F7019F40E94EADDF5CF809109163F -:102320008F5F8F70A09109169DE5A99FD0011124A0 -:10233000FD01E356F64FEF0119929A95E9F7908166 -:1023400098609083AE54B64F90E1EFE1F6E10190D2 -:102350000D929A95E1F72091091690910A1629138A -:1023600003C094E69093061680930916DF91CF91EF -:102370000C944995CF93DF93CDB7DEB760970FB636 -:10238000F894DEBF0FBECDBF80E1E6E7F2E0DE01EC -:10239000119601900D928A95E1F7CE0101960E9467 -:1023A000D0B160960FB6F894DEBF0FBECDBFDF91FF -:1023B000CF910895DC01ED91FC910190F081E02D29 -:1023C00027E030E040E050E061E01994DC01149631 -:1023D0008C911497807F8A6014968C931497129630 -:1023E0002C91129713963C911397482F4F7050E001 -:1023F000ED91FC9111970190F081E02D60E1CD010C -:1024000019946091EA1581E068278FEA95E10D94AF -:102410000E096091AE1581E0682783E795E10D9480 -:102420000E096091721581E0682787E395E10D94AC -:102430000E096091361581E068278BEF94E10D94C9 -:102440000E096091FA1481E068278FEB94E10D94F6 -:102450000E09CF93C82F41E00E946FD98C2FCF91E6 -:102460000C948ED9CF93DF936AE17CE30F94291209 -:10247000C5E5D9E04C895D896E897F8982E19CE35D -:102480000E94A4CF488D598D6A8D7B8D8FE09CE38F -:102490000E94A4CF4C8D5D8D6E8D7F8D8CE09CE372 -:1024A0000E94A4CF48A159A16AA17BA189E09CE325 -:1024B0000E94A4CF8AE0DF91CF910C949FCE80E55B -:1024C00094E10E94297E80E594E10E945E7E8091E5 -:1024D000A2178D7F8E7F8093A21710929E17109265 -:1024E0009F171092A0171092A11708950E940FD85D -:1024F000609153097091540986EF9BE30E94E0DDDF -:1025000083EF9BE30C94ACCE0E94D1C981110C9453 -:10251000A7C960E070E0CB0108954F925F926F927F -:102520007F928F929F92AF92BF92CF92DF92EF9263 -:10253000FF920F931F93CF93DF9300D01F92CDB7DD -:10254000DEB74C015B016A01F22E6E2D80E00E9425 -:102550006FE5182F81111CC0409151096E2D89E043 -:102560000E94092E812F0F900F900F900F90DF91F6 -:10257000CF911F910F91FF90EF90DF90CF90BF9080 -:10258000AF909F908F907F906F905F904F90089545 -:10259000002331F1409151096E2D84E00E94092EF3 -:1025A0000E940FD881ED9BE30E94ACCE61E08F2D9D -:1025B0000E9425CC0091500983E08093500981E06E -:1025C00080934F0980914F09882341F060E08F2D5F -:1025D0000E9425CC81E00E94EADDF4CF00935009EF -:1025E000409151096E2D85E00E94092E20E030E0D7 -:1025F000A901F40160817181828193810F94B139C5 -:10260000882371F080E090E0A0ECB0E489839A83A5 -:10261000AB83BC83BE016F5F7F4FC4010E944EB588 -:1026200020E030E0A901F501608171818281938110 -:102630000F94B139882351F140908D0950908E0943 -:1026400060908F097090900980E090E0A8ECB1E470 -:1026500080938D0990938E09A0938F09B093900970 -:1026600080E090E0A0ECB0E489839A83AB83BC83E4 -:10267000BE016F5F7F4FC5010E944EB540928D092C -:1026800050928E0960928F0970929009812C912C42 -:1026900080E4A82EBA2C03E020E030E0A901F60186 -:1026A00060817181828193810F946840181684F44F -:1026B0004091510960E086E00E94092E89829A8249 -:1026C000AB82BC82BE016F5F7F4FC6010E944EB5D8 -:1026D000F09050090093500910924F094091510910 -:1026E00060E087E00E94092E80914E09811104C0AC -:1026F00081E00E94EADDF8CFF0925009813061F26A -:1027000031CF4F925F926F927F928F929F92AF9252 -:10271000BF92FF920F931F93CF93DF93CDB7DEB796 -:10272000A0970FB6F894DEBF0FBECDBFF82E4A01BA -:102730005B012801390120E030E0A901C301B801A3 -:102740000F94B139811111C0FF2019F081E0F81206 -:1027500092C060E070E88BE395E420E030E040E771 -:1027600052E40F94023F2B013C014D8E5E8E6F8E22 -:1027700078A20F2D10E0F801E253F44CE491772495 -:1027800073941E160CF4712CFF24F39420E030E0B7 -:10279000A901C501B4010F94684018160CF0F12C82 -:1027A00080E00E9485B269837A838B839C8381E079 -:1027B0000E9485B26D837E838F83988782E00E941A -:1027C00085B269877A878B879C8783E00E9485B270 -:1027D0006D877E878F87988B000F111F000F111F49 -:1027E000E1E0F0E0EC0FFD1F0E0F1F1FF80110825B -:1027F000118212821382CE0101960E94D0B1F8019B -:1028000080829182A282B382198A1A8A1B8A1C8AC8 -:102810001D8A1E8A1F8A188E198E1A8E1B8E1C8E78 -:1028200080914C0990914D09892B61F49E012F5E96 -:102830003F4F40915109BE01635E7F4FCE0101962B -:102840000E94D6960E947F8F7F100E94D6BAA096D3 -:102850000FB6F894DEBF0FBECDBFDF91CF911F91B1 -:102860000F91FF90BF90AF909F908F907F906F904F -:102870005F904F90089560E070E080E793E46DCF43 -:10288000CF92DF92EF92FF920F931F93CF93DF933C -:1028900000D01F92CDB7DEB705E1041B442361F0E1 -:1028A00082E090E0A0E0B0E089839A83AB83BC83B0 -:1028B000CE0101960E946740E02FF0E086E0089F7D -:1028C000800111248091FC1181111AC089E79FE0D9 -:1028D000B8010E94DDC7081B190B80E2C82ED12C5D -:1028E000E12CF12C0730110588F0C982DA82EB82E5 -:1028F000FC82CE0101960E946740081B190BF2CFA3 -:10290000E450FE4E10828CEF91E1E2CF0F900F90D9 -:102910000F900F90DF91CF911F910F91FF90EF904B -:10292000DF90CF9008954F925F926F927F92AF9217 -:10293000BF92CF92DF92EF92FF920F931F93CF93AC -:10294000DF9300D01F92CDB7DEB77B01142F41FB80 -:10295000662760F90E94733F882309F45CC0D12C7C -:10296000C12CE114F10439F0C7010E94B43E96E095 -:10297000899F6001112410FF20C080E890E08C192D -:102980009D096CE070E00F9448415B0100E810E0A5 -:1029900090E2492E512C612C712C81E0A81AB108CB -:1029A000B7FC0DC049825A826B827C82CE010196AF -:1029B0000E946740081B190BF0CF00E810E0CD28FB -:1029C000B9F0C80166E070E00F94344120914A09E3 -:1029D00030914B094091480950914909062F609167 -:1029E0004709C7010E94A74196E0899F80011124F1 -:1029F00080E2C82ED12CE12CF12C0730110558F0C3 -:102A0000C982DA82EB82FC82CE0101960E94674085 -:102A1000081B190BF2CF0F900F900F900F90DF91C2 -:102A2000CF911F910F91FF90EF90DF90CF90BF90CB -:102A3000AF907F906F905F904F9008958F929F928C -:102A4000AF92BF92EF92FF920F931F93CF93DF93BA -:102A500000D01F92CDB7DEB7982F862F7A01122FA4 -:102A6000692F0E94733F882309F446C020914A09C8 -:102A700030914B09409148095091490904E1609116 -:102A80004709C7010E94A74196E0899F7001112460 -:102A900080E2882E912CA12CB12C87E0E816F1045D -:102AA00058F089829A82AB82BC82CE0101960E9444 -:102AB0006740E81AF90AF1CF812F110F990BAA0B81 -:102AC000BB0B89839A83AB83BC83809146099AE7C9 -:102AD0009093801680938116CE0101960E946740E4 -:102AE00080E290E0A0E0B0E089839A83AB83BC836E -:102AF000CE0101960E9467400F900F900F900F90AB -:102B0000DF91CF911F910F91FF90EF90BF90AF9009 -:102B10009F908F900895EF92FF920F931F93CF9302 -:102B2000DF93FB01D081DD2341F17B018C016D2F0F -:102B30000F94FD09F801C189C195FFEFEF1AFF0A53 -:102B4000F70181917F01F801882341F09089C90F35 -:102B5000D82F682FC8010F94FD09F2CFD03259F059 -:102B600083899189890F8C0FDF91CF911F910F91EC -:102B7000FF90EF9008958089F6CF80E0F5CF81E057 -:102B8000809345091092410910924209109243091D -:102B90001092440908952F923F924F925F926F9244 -:102BA0007F928F929F92AF92BF92CF92DF92EF92DD -:102BB000FF920F931F93CF93DF9300D000D0CDB738 -:102BC000DEB71C017E836D8329013A01470158015C -:102BD00020E030E040E05FECC301B2010F946840B8 -:102BE00018162CF0412C512C612C2FEC722EC301A5 -:102BF000B2010F94743F2B013C0120E030E040E033 -:102C00005FE4C501B4010F94B13987FD05C0812C83 -:102C1000912CA12C9FE4B92EC301B2010F94B839B5 -:102C20009B01AC01ED81FE81608171818281938184 -:102C30000F94073E0F947B3F69837A838B839C8339 -:102C4000C501B4010F94743F7B018C01E418F508B1 -:102C5000060917091F92912C812C88E0A82E88E480 -:102C6000B82EC980DA80A30192016D817E81C101F5 -:102C70000E94EB2C0F9026960FB6F894DEBF0FBE85 -:102C8000CDBFDF91CF911F910F91FF90EF90DF901B -:102C9000CF90BF90AF909F908F907F906F905F90FC -:102CA0004F903F902F9008952F923F924F925F92B6 -:102CB0006F927F928F929F92AF92BF92CF92DF924C -:102CC000EF92FF920F931F93CF93DF931C01EB01C1 -:102CD000CA01B9010F94B6392AE037ED43E25DE34A -:102CE0000F94173A2B013C0120E030E040E05FEC0C -:102CF0000F94684018162CF0412C512C612C3FEC9D -:102D0000732EC301B2010F94743F2B013C01688103 -:102D100079818A819B810F94B6392AE037ED43E2AD -:102D20005DE30F94173A6B017C01C301B2010F946C -:102D3000B8399B01AC01C701B6010F94073E0F944F -:102D40007B3F6B0188E79FE0A0E0B0E08419950924 -:102D5000A609B7091F9248012CEFA22E27E4B22E34 -:102D60007C018D01A3019201BE01C1010E94EB2CE7 -:102D70000F90DF91CF911F910F91FF90EF90DF9017 -:102D8000CF90BF90AF909F908F907F906F905F900B -:102D90004F903F902F9008952F923F924F925F92C5 -:102DA0006F927F928F929F92AF92BF92CF92DF925B -:102DB000EF92FF920F931F93CF93DF9300D000D039 -:102DC0001F921F92CDB7DEB71C0178876F83790100 -:102DD0001A830983BA01550F880B990B0F94B839E0 -:102DE0004B015C0120E030E040E05FEC0F94684074 -:102DF00018162CF0812C912CA12C2FECB22EC50191 -:102E0000B4010F94743F2B013C01B701FF0C880BF8 -:102E1000990B0F94B8394B015C0120E030E040E0A1 -:102E20005FE40F94B13987FD05C0812C912CA12C52 -:102E30009FE4B92EEF81F88560817181072E000C27 -:102E4000880B990B0F94B8396B017C01C301B20157 -:102E50000F94B8399B01AC01C701B6010F94073E2E -:102E60000F947B3F6B837C838D839E83C501B4016C -:102E70000F94743F7B018C01E418F50806091709CB -:102E80001F9289809A808EE0A82E88E4B82ECB808D -:102E9000DC80A30192016F817885C1010E94EB2C37 -:102EA0000F9028960FB6F894DEBF0FBECDBFDF910E -:102EB000CF911F910F91FF90EF90DF90CF90BF9037 -:102EC000AF909F908F907F906F905F904F903F90CA -:102ED0002F9008956F927F928F929F92AF92BF92A0 -:102EE000CF92DF92EF92FF920F931F93CF93DF93D6 -:102EF0003C01EB01688179818A819B810F947B3F42 -:102F00001F92912C812C84E1A82E88E4B82E6B01AD -:102F100018ECE12EF12C00E010E020E030E0A901F7 -:102F2000BE01C3010E94EB2C0F90DF91CF911F9146 -:102F30000F91FF90EF90DF90CF90BF90AF909F9058 -:102F40008F907F906F9008958F929F92AF92BF92D3 -:102F5000CF92DF92EF92FF920F931F93CF93DF9365 -:102F6000EC014B016091360970E090E080E00F9435 -:102F7000B63929EC38EC48EC5EE30F94173A20E0C0 -:102F800030E040E05FE30F94083E0F947B3F1F92D8 -:102F900084EEA82E87E4B82E6B0114E6E12EF12C06 -:102FA00000E010E020E030E0A90166E379E0CE0126 -:102FB0000E94EB2C0F90DF91CF911F910F91FF900A -:102FC000EF90DF90CF90BF90AF909F908F9008953B -:102FD0008F929F92AF92BF92CF92DF92EF92FF9229 -:102FE0000F931F93FB01C080D12C21E02F9328E089 -:102FF000822E2CEC922E3EEDA32E37E4B32EE12C44 -:10300000F12C8701EA9420E030E0A9010E94EB2C2A -:103010000F901F910F91FF90EF90DF90CF90BF9096 -:10302000AF909F908F9008956F927F928F929F9212 -:10303000AF92BF92CF92DF92EF92FF920F931F93C6 -:10304000CF93DF933C01EB014A016881798190E0E5 -:1030500080E00F94B6392DEC3CEC4CEC5DE30F9422 -:10306000173A20E030E040E251E40F94073E0F941D -:103070007B3F1F9288EDA82E87E4B82E6B0112E2E9 -:10308000E12EFF24F39400E010E02AE030E040E07D -:1030900050E0BE01C3010E94EB2C0F90DF91CF9155 -:1030A0001F910F91FF90EF90DF90CF90BF90AF9066 -:1030B0009F908F907F906F900895282F30E0F901B6 -:1030C000E151F84C9491F901E857F44C44912E5B8E -:1030D000344CF9012491222309F435C0992311F1CC -:1030E00091509231F8F4E92FF0E08827E558F74E37 -:1030F0008E4F0D945C41F601A8003C01E201CA002C -:10310000A0014C02F0012402420186025E01B401DA -:103110000802A001660174026802809180008F7726 -:1031200080938000E22FF0E0EE0FFF1FE85DF44C8B -:10313000A591B4918FB7F894EC91611148C0409576 -:103140004E234C938FBF0895809180008F7DE8CFF0 -:1031500080918000877FE4CF84B58F7784BDE2CFF4 -:1031600084B58F7DFBCF8091B0008F778093B000C6 -:10317000D9CF8091B0008F7DF9CF809190008F776B -:1031800080939000CFCF809190008F7DF9CF809178 -:103190009000877FF5CF8091A0008F778093A0006B -:1031A000C1CF8091A0008F7DF9CF8091A000877F53 -:1031B000F5CF809120018F7780932001B3CF80914C -:1031C00020018F7DF9CF80912001877FF5CF4E2B95 -:1031D000B8CFEF92FF920F931F93CF93DF93CDB7AA -:1031E000DEB762970FB6F894DEBF0FBECDBF611594 -:1031F000710579F460E062960FB6F894DEBF0FBEF9 -:10320000CDBFDF91CF911F910F91FF90EF900D9463 -:103210005D186F3F710511F461E0EDCF8B01F82E61 -:10322000682FCE0101960E949ECD8989882309F4DA -:1032300077C0E981FA819F858889911134C06081C6 -:1032400090E023E030E0A901481B590B440F551FC3 -:10325000042E01C0220F0A94EAF72095262362E08B -:1032600070E001C0660F4A95EAF7262B2083FC0127 -:103270003396EE0FFF1F21E030E02C0F3D1FE20FD1 -:10328000F31F0190F081E02D1183008362960FB649 -:10329000F894DEBF0FBECDBFDF91CF911F910F918C -:1032A000FF90EF9008952A892111F0CFAFEFB0E0A1 -:1032B000923029F0AD85BE850D90BC91A02D608126 -:1032C00090E023E030E0A901481B590B440F551F43 -:1032D000042E01C0220F0A94EAF72095262362E00B -:1032E00070E001C0660F4A95EAF7262B208303960B -:1032F000880F991FE1E0F0E0EC0FFD1F8E0F9F1F7C -:10330000FC01E080F18098010F94F83D2FEF30E050 -:1033100040E050E00F94A43DF70131832083B6CF05 -:1033200061E00F37110508F460E08F2D64CF109233 -:10333000851881E08093841810925F1861E084E121 -:103340000F945D1861E085E10F945D18E9EBF0E002 -:1033500080818E7F808380818D7F808388E48093CD -:10336000B80085E48093BC000895CF93DF9391E08B -:1033700090930A188823B9F0C091B800D091BA0090 -:103380008091BC008A7B8093BC0060E084E10F9454 -:103390005D1860E085E10F945D180F949719D09344 -:1033A000BA00C093B800DF91CF9108958F929F9299 -:1033B000AF92BF92CF92DF92EF92FF920F931F9343 -:1033C000CF93DF9300D000D0CDB7DEB791E19983E2 -:1033D0001A828B831C826D834E8381E08093AE18AA -:1033E00082E68093AD181092AC181092AB1846E0AC -:1033F00050E0BE016F5F7F4F85EF98E10F94750736 -:103400000091AB18013208F094C01091AD180F94E0 -:10341000FF066B017C0180918518811165C082E0F7 -:103420008093851881E0809384188FEF80938318B0 -:103430001092821800938118ABE8B8E1E1E6F8E158 -:1034400080E008138FC01092601880916018110FEF -:10345000182B1093601880915F18813009F086C096 -:1034600010925F180F94FF066B017C018091601829 -:103470008093BB008091871890918818A09189183B -:10348000B0918A18892B8A2B8B2B99F00F94FF0609 -:1034900000918718109188182091891830918A1806 -:1034A0006C197D098E099F09061717072807390728 -:1034B000E0F18091BC0083FDD9CF85EC8093BC0006 -:1034C0000F94FF066B017C0180918518823009F40E -:1034D0004FC0809183188F3F61F1809183188032B3 -:1034E00041F18091831825C08091871890918818A8 -:1034F000A0918918B0918A18892B8A2B8B2B09F4FB -:103500008ACF0F94FF068090871890908818A0901B -:103510008918B0908A186C197D098E099F09861642 -:103520009706A806B90608F076CF809186180F9402 -:10353000B5191092AC181092AB181092AE182696CE -:103540000FB6F894DEBF0FBECDBFDF91CF911F91B4 -:103550000F91FF90EF90DF90CF90BF90AF909F9032 -:103560008F9008959D9191938F5F6BCF85EEA6CF3D -:103570008091871890918818A0918918B0918A1825 -:10358000892B8A2B8B2B09F49FCF0F94FF06009178 -:103590008718109188182091891830918A186C1911 -:1035A0007D098E099F09061717072807390708F0B4 -:1035B0008BCFBBCF85ED8093BC0080918718909115 -:1035C0008818A0918918B0918A180796A11DB11D7D -:1035D00023E0B695A795979587952A95D1F72091E1 -:1035E000BC0024FD03C010928518089540918718EF -:1035F000509188186091891870918A18452B462B34 -:10360000472B69F30097A105B10541F025E32A9501 -:10361000F1F700000197A109B109E1CF8091861867 -:103620000D94B519CF93DF93EC016C8161708881A3 -:103630000F945D186C81669561708A81DF91CF91DE -:103640000D945D18860F911DFC0183A18F3F19F029 -:10365000642F0D945D180895CF93DF9390E0FC01E3 -:10366000E857F44C24918E5B944CFC0184918823A0 -:10367000C9F090E0880F991FFC01EB52F84CA5911E -:10368000B491FC01E85DF44CC591D49161110DC079 -:103690009FB7F8948C91209582238C93888128235E -:1036A00028839FBFDF91CF910895623051F49FB777 -:1036B000F8943C91822F809583238C93E8812E2B64 -:1036C000EFCF8FB7F894EC912E2B2C938FBFEACFCE -:1036D000CF93DF93EC01ECA5FDA5309709F470C002 -:1036E000138E128E118E108E178A168A82E490E045 -:1036F000958F848F848596EF980F943048F02EEC48 -:10370000280F243028F022EC280F283008F051C070 -:103710002FE030E0378B268B20E430E0318F208F94 -:1037200027E230E0338F228F943050F02EEC280FB8 -:10373000243030F022EC280FB0E0A0E0283010F464 -:10374000A8E6B0E02C91943028F032EC380F3830F5 -:1037500008F443C031E0232B943048F09EEC980FDE -:10376000943028F08E53B0E0A0E0883010F4A8E642 -:10377000B0E02C93248536EF320F343080F18EEC9C -:10378000820F843060F182EC820F883058F190E033 -:1037900080E0948B838B343040F52650330B81E0EE -:1037A00001C0880F2A95EAF7858B848D958D019746 -:1037B000F1F7CF010F9494088CA59DA50F947E0876 -:1037C0008EA59FA5009719F161E00F945D1861E047 -:1037D0008EA5DF91CF910D942C1B34E0BCCF8BE6EE -:1037E00090E0D7CF8DE690E0D4CF88E02233E1F2AD -:1037F00084E02333C9F282E02433B1F282EC820FF9 -:10380000883018F42E53330BCACF81E0CDCFDF912F -:10381000CF910895EF92FF920F931F93CF938C0156 -:10382000C42F79016150673008F045C0E62FF0E001 -:103830008827E25EF34E8E4F0D945C41DA0022023F -:10384000F40078019A0168016202780183E2E80ECF -:10385000F11C005D1F4FF70181917F018F3F49F0FF -:1038600061E00F942C1B61E0F701319780810F9488 -:103870005D18E016F10679F761E084E30F942C1BE4 -:1038800060E084E30F945D1861E083E30F942C1BE8 -:1038900060E083E30F945D1861E085E30F942C1BD7 -:1038A00061E085E30F945D181CBC80E58CBDC230DF -:1038B00010F481E08DBD81E0CF911F910F91FF90B9 -:1038C000EF90089561E0C8010F94221BF4CF4111DD -:1038D00003C041E062E0F7CF40E064E0C8010F942C -:1038E000221B40E0F7CFF80183A160E08F3F19F37E -:1038F000EACF842F0F949A0ADECFF70181917F01DE -:103900000F949A0AC150C111F8CFD5CFF701849115 -:103910000F949A0AFFEFEF1AFF0AC150C111F6CFB8 -:10392000CACF8F929F92AF92BF92CF92DF92EF92C7 -:10393000FF926B017C010F94FF064B015C01C114E7 -:10394000D104E104F104B9F00F94FF066819790974 -:103950008A099B09683E73408105910580F321E047 -:10396000C21AD108E108F10888EE880E83E0981E9B -:10397000A11CB11CE4CFFF90EF90DF90CF90BF90DF -:10398000AF909F908F900895CF92DF92EF92FF9229 -:103990000F931F93CF93DF9300D000D01F921F92FD -:1039A000CDB7DEB77C0118861F8285E08983F701D9 -:1039B00082A98A8360686B835C834D833E832F83F7 -:1039C00067E0CE0101960F94A3068887F70182A5D0 -:1039D00093A5892B31F080A991A9009711F00F943C -:1039E000121B8E010F5F1F4F6E01F9E0CF0ED11C2D -:1039F000F80161918F01C7010F94BD08F70121897A -:103A00003289820F932F911D928B818B0C151D058E -:103A100079F762E070E080E090E00F94911C2896C6 -:103A20000FB6F894DEBF0FBECDBFDF91CF911F91CF -:103A30000F91FF90EF90DF90CF9008952FB7F894FB -:103A400060914F18709150188091511890915218B0 -:103A50002FBF0895CF92DF92EF92FF920F941E1D19 -:103A60006B017C0128E5C20E22E0D21EE11CF11C94 -:103A70000E94C8DD8F3F71F00F941E1D6C197D09E7 -:103A80008E099F0997FDF4CF80E0FF90EF90DF90C3 -:103A9000CF90089581E0F9CF2F923F924F925F929D -:103AA0006F927F928F929F92AF92BF92CF92DF924E -:103AB000EF92FF920F931F93CF93DF93CDB7DEB7B3 -:103AC00061970FB6F894DEBF0FBECDBF1C011C86F8 -:103AD0001B8685E08987F10182A98A876B8763E06D -:103AE000CE0109960F94A3068C87F2E0F98B9E0114 -:103AF000235F3F4F3E872D87F10184A595A5009751 -:103B000061F00F949408C1010F94F3081816190678 -:103B10007CF4C1010F94D808F6CF82A593A5892B18 -:103B200091F380A991A9009771F30F94121BEBCF29 -:103B3000F10186A597A5009741F061E00F945D180B -:103B400061E0F10186A50F942C1B8E01075F1F4FCA -:103B5000F80161918F01C1010F94BD082D853E854B -:103B600002171307A9F7F10186A597A5009719F089 -:103B700062E00F942C1B62E070E080E090E00F9414 -:103B8000911C0F941E1D2B013C018985CB84D12CE7 -:103B9000F12CE12CDD24DA94E82A812C912C5401BB -:103BA00005E010E00F941E1D641575058605970548 -:103BB00031F00150110909F474C02B013C01C1011D -:103BC0000F94D80897FD0FC07A2D692D582D4427E2 -:103BD0004C019924092C000CAA08BB08842A952AB8 -:103BE000A62AB72ABB24C814D904EA04FB04D1F6D8 -:103BF00026013701812C912C54010F941E1D6B015D -:103C00007C0125E030E0388B2F8710E00F941E1DDB -:103C10006C157D058E059F0549F0EF85F889319774 -:103C2000F88BEF87EF2BE9F16B017C01C1010F9459 -:103C3000D808DC0197FD1CC09201A301B401C501A5 -:103C400008E00F947641BB27EB2FEE0FEE0B422ED0 -:103C50004A2A532E5B2A6E2E642A7E2E752A8E2EB9 -:103C6000862A9E2E972AAE2EA82ABE2EB92A1F5F1C -:103C7000153061F6F10186A597A5009741F061E046 -:103C80000F945D1861E0F10186A50F942C1BC10112 -:103C90000F94F3081816190664F4C1010F94D8089C -:103CA000F6CF412C512C612C712C812C912CA12C04 -:103CB000B12CF10184A595A5009711F00F947E0811 -:103CC00062E070E080E090E00F94911CF101178AAF -:103CD0009201A301B401C50108E30F949141298326 -:103CE0009201A301B401C50100E30F9491412A831D -:103CF0009201A301B401C50108E20F9491412B8305 -:103D00009201A301B401C50100E20F9491412C83FB -:103D10009201A301B401C50108E10F9491412D83E3 -:103D20009201A301B401C50100E10F9491412E83DA -:103D30009201A301B401C50108E00F9491412F83C2 -:103D4000488667E0CE0101960F94A306481202C090 -:103D5000411011C081E0F101878BF989F13019F030 -:103D600021E0298BC9CE412C512C612C712C812C46 -:103D7000912CA12CB12C9201A301B401C50108E042 -:103D80000F949141B901CA0161960FB6F894DEBF54 -:103D90000FBECDBFDF91CF911F910F91FF90EF909C -:103DA000DF90CF90BF90AF909F908F907F906F905B -:103DB0005F904F903F902F9008951F920F920FB6F3 -:103DC0000F9211242F933F938F939F93AF93BF93A1 -:103DD00080914F1890915018A0915118B09152189D -:103DE00030914E1823E0230F2D3758F50196A11D71 -:103DF000B11D20934E1880934F1890935018A093A4 -:103E00005118B09352188091531890915418A09162 -:103E10005518B09156180196A11DB11D80935318E5 -:103E200090935418A0935518B0935618BF91AF9122 -:103E30009F918F913F912F910F900FBE0F901F90E8 -:103E4000189526E8230F0296A11DB11DD2CF1F920F -:103E50000F920FB60F9211240BB60F922F933F9330 -:103E60004F935F936F937F938F939F93AF93BF9382 -:103E7000EF93FF938091B900887F803609F44DC09D -:103E800008F040C0883209F4A9C028F5803109F44F -:103E90009DC0C8F4882309F4FBC0883009F496C09B -:103EA000FF91EF91BF91AF919F918F917F916F9112 -:103EB0005F914F913F912F910F900BBE0F900FBECE -:103EC0000F901F901895883109F488C0803241F70F -:103ED0008093831814C0803409F49DC040F480336B -:103EE000B9F38833E9F68093831885ECB0C0803548 -:103EF00009F485C0883509F496C0883489F60F9492 -:103F0000DA1ACECF883909F48CC038F5883729F011 -:103F100050F4883611F0803719F683E080938518C5 -:103F200010924D1857C0883809F47BC0803919F0B9 -:103F3000803809F0B5CF80914D18803208F071C0FB -:103F4000E0914D1881E08E0F80934D188091BB0059 -:103F5000F0E0E35DF74E80833DC0803B39F0E0F454 -:103F6000803A09F479C0883A09F09ACF84E08093C6 -:103F7000851810922C1810922B18E0915918F09176 -:103F80005A18199580912B1881110FC081E08093E8 -:103F90002B1810920B1809C0803C09F4A6CF883C5E -:103FA00009F4A3CF883B09F07BCFE0912C1881E086 -:103FB0008E0F80932C18F0E0E55FF74E80818093A0 -:103FC000BB0090912C1880912B1829C0809160180B -:103FD0008093BB0085EC8093BC0062CF90918218E7 -:103FE00080918118981758F5E091821881E08E0F22 -:103FF00080938218F0E0EF59F74E8081E9CFE0918D -:10400000821881E08E0F809382188091BB00F0E0CF -:10401000EF59F74E808390918218809181189817FC -:10402000C8F285E8D8CFE091821881E08E0F8093A6 -:1040300082188091BB00F0E0EF59F74E80838091A9 -:10404000841881115CCF81E080935F1884EA8093AB -:10405000BC001092851824CF85EC8093BC00109290 -:10406000851880914D18803230F4E0914D18F0E0C1 -:10407000E35DF74E108260914D1870E0E0915718A3 -:10408000F09158188DE298E1199510924D1808CFCB -:104090001092831834CF1F920F920FB60F921124F3 -:1040A0000BB60F922F933F934F935F936F937F9332 -:1040B0008F939F93AF93BF93EF93FF93E091E81794 -:1040C000F091E917309749F0A685B7858585968DDB -:1040D00091FF16C09C918923B1F4FF91EF91BF919C -:1040E000AF919F918F917F916F915F914F913F9190 -:1040F0002F910F900BBE0F900FBE0F901F90189531 -:104100009C91892351F7A389B4899C9185898095D5 -:1041100089238C93868997890197F1F7608D718D3A -:10412000A685B785558538E020E0CB010197F1F7EA -:10413000822F90E095958795282F4C91452309F083 -:104140002068315091F7868D81FD20958091E6178A -:1041500090E001968F7399273091E717381799F0FF -:10416000A091E617B0E0AA55B84E2C938093E617BD -:10417000828D938D0197F1F7A389B4898C919589EC -:10418000892B8C93AACF868D8160868FF1CFDC013D -:1041900015966C931597262F30E050E040E0ED9196 -:1041A000FC910190F081E02D61E11994DC01ED9129 -:1041B000FC910088F189E02D19958F5F0895615079 -:1041C000DC01ED91FC910684F785E02D1994DC016A -:1041D000ED91FC910484F585E02D199583500895A7 -:1041E0006D5FDC01ED91FC910284F385E02D199463 -:1041F000DC01ED91FC910084F185E02D19956115AC -:1042000071058105910539F06F3F7F4F8F4F9F4FAB -:1042100021F080E0089582E0089581E00895CF9232 -:10422000DF92EF92FF921F93CF93DF93EC0190E028 -:1042300080E00F94B63925ED34E045E352E40F9465 -:10424000173A20E030E04AE754E40F94023F6B0154 -:104250007C012AE037ED43EA5CE369857A858B854A -:104260009C850F94083EA70196010F94173A26E605 -:1042700036E646EA5EE30F94023F20E030E040E895 -:104280005FE30F94073E0F947B3F162FE881F9817F -:104290000480F581E02D603108F060C061E0CE015E -:1042A00019952AE037ED43EA5CE369857A858B85C9 -:1042B0009C850F94083EA70196010F94173A2CEEA7 -:1042C00031E548E35EE30F94023F20E030E040E850 -:1042D0005FE30F94073E0F947B3F162F103208F0D8 -:1042E0001FE1912F9F718B81807E892B8B832A8187 -:1042F000382F8C81482F4F7050E0E881F981019070 -:10430000F081E02D60E1CE011995612F70E090E021 -:1043100080E00F94B8392D853E854F8558890F94DC -:10432000173A0F947B3F862F8F716A81607E682BCE -:104330006A83262F3B818C81482F4F7050E0E881A3 -:10434000F9810190F081E02D60E1CE01DF91CF9104 -:104350001F91FF90EF90DF90CF90199460E0CE0115 -:104360001995BCCFDC0196964D935D936D937C932C -:104370009997ED91FC910190F081E02D9A01AB01AC -:1043800060E71994DC01ED91FC910280F381E02D4E -:1043900060E0199562FB882780F908959A01AB01C6 -:1043A000DC0158962C935897632F63705996EC91C3 -:1043B0005997EC7FE62B5996EC935997ED91FC9128 -:1043C0000190F081E02D60E019940F94BB09862FD5 -:1043D0008F700895262F2F70DC0192966C91929722 -:1043E000607F622B92966C93929792962D913D915D -:1043F0004D915C919597ED91FC910190F081E02DAC -:104400006CE61994DC0192964D935D936D937C93C9 -:104410009597ED91FC910190F081E02D9A01AB010F -:104420006CE61994CF93DF93DC01EB01298112969E -:104430009C911297291718F113968C911397821754 -:10444000F0F0E88115968C911597E817C0F43C813F -:1044500016964D915C91291B283018F0480F511D7C -:10446000277081E090E001C0880F2A95EAF7E40FF9 -:10447000F52FF11D2081332329F0822B8083DF91DA -:10448000CF91089580958223F9CFDB01ED91FC91C6 -:1044900019940F931F93CF93DF931F92CDB7DEB77D -:1044A00000914B1610914C16E0917A16F0917B1604 -:1044B00082E0199530E020E04AE0B80189E496E115 -:1044C0000F944522182FE0917A16F0917B1683E025 -:1044D0001995E0917A16F0917B1680E019951123D9 -:1044E000B9F160914B1670914C169E012F5F3F4FB2 -:1044F00046E489E496E10F94452289818093491628 -:1045000060914B1670914C169E012F5F3F4F47E410 -:1045100089E496E10F944522898180934A1660913F -:104520004B1670914C1630E020E048E489E496E1A7 -:104530000F9445228093541660914B1670914C163F -:104540002CE736E147E189E496E10F94452211E03A -:10455000812F0F90DF91CF911F910F910895DF92DE -:10456000EF92FF920F931F93CF93DF93182F062F95 -:10457000C42FD42FF62EF40EEE24E394DD24DA9427 -:104580008F2D8D1BD83090F58C2F887F800F9C2F1E -:1045900096959695969528EF929FC00D1124CC2361 -:1045A000D1F197E0C92760914B1670914C1610938A -:1045B00065168093661681E080936816CF5FC7709A -:1045C0008FEF90E001C0880FCA95EAF780936716D5 -:1045D00025E636E14BE389E496E1DF91CF911F9127 -:1045E0000F91FF90EF90DF900D94452260914B1654 -:1045F00070914C161093651680936616E0926816BB -:10460000D092671625E636E14BE389E496E10F94F4 -:104610004522D850B5CFDF91CF911F910F91FF90D8 -:10462000EF90DF900895AF92BF92CF92DF92EF921A -:10463000FF920F931F93CF93DF93EC01E62EF42E9E -:10464000122F022FD62ED20ECC24CA945C012CE15C -:10465000A20EB11C8D2D801B083070F5812F887F34 -:104660008E0D912F96959695969528EF929F100D09 -:104670001124112371F197E019276A817B818C8FB6 -:10468000FD8E1F8E1F5F17708FEF90E001C0880FA7 -:104690001A95EAF78E8F9E01245E3F4F4BE3CE01C1 -:1046A000DF91CF911F910F91FF90EF90DF90CF900E -:1046B000BF90AF900D9445226A817B818C8FFD8ED7 -:1046C0001F8ECE8E95014BE3CE010F9445220850EC -:1046D000C1CFDF91CF911F910F91FF90EF90DF90AD -:1046E000CF90BF90AF9008950F93CF93C82F01E064 -:1046F00020E8482F60E089E496E10F94A00A88231F -:1047000049F020E84C2F60E089E496E1CF910F91C9 -:104710000D941323CF910F910895FF920F931F9340 -:10472000CF93DF93D82F162FF42EC22F022F242FD2 -:10473000462F682F89E496E10F94A00A882309F197 -:104740002F2D412F6D2F89E496E10F9413234C2FC9 -:10475000612F8D2F0F94AF228FEF8F0D4C2F612F74 -:104760008D0F0F94AF224FEF4C0F410F2F2D6D2F58 -:1047700089E496E1DF91CF911F910F91FF900D9405 -:104780001323DF91CF911F910F91FF900895DF9236 -:10479000EF92FF920F931F93CF93DF937C01162F1D -:1047A000C42FD22ED02F0F94A00A882351F0DC0FF3 -:1047B0002D2D4C2F612FC7010F941323CF5FDC13D6 -:1047C000F7CFDF91CF911F910F91FF90EF90DF9086 -:1047D0000895EF92FF920F931F93CF93DF93C82F0B -:1047E0007B01142FCB010E94B43E26E0C29FE00162 -:1047F0001124112389F091E090936916829F900112 -:1048000011242E5F0CE042E36C2F615089E496E1A5 -:104810000F94C72310926916A7016CE38C2F0E9496 -:10482000C464112319F081E080936916DF91CF9160 -:104830001F910F91FF90EF9008953F924F925F92DA -:104840006F927F928F929F92AF92BF92CF92DF92A0 -:10485000EF92FF920F931F93CF93DF931F921F92BC -:10486000CDB7DEB75C01680181E0809340094090DC -:104870003B0950903C0960903D0970903E094114FD -:1048800051046104710479F091E0141415040CF0E2 -:1048900090E090933A0910923B0910923C091092D3 -:1048A0003D0910923E0910913A0930903F0910924B -:1048B0003F09311005C080917502882309F470C04A -:1048C00049012A013B01C9010E94B43E082F80E042 -:1048D000E114F10419F0C7010E94B43E1A82198252 -:1048E000C114D104B1F4402F50E0282F30E0CA01A8 -:1048F000820F931F46976CF485E190E0841B950B23 -:10490000821B930B97FD0196959587958A8381E08D -:10491000898301E021EA34E2A401BE016F5F7F4F89 -:10492000CE0102960E94D840C114D10491F08A8130 -:10493000882321F01A8289818F5F898300E024EA2D -:1049400034E2A601BE016F5F7F4FCE0102960E9446 -:10495000D840E114F10459F000E021EA34E2A70163 -:10496000BE016F5F7F4FCE0102960E94D84041E0AA -:104970004127B30181E00F94E923C5010E94B43EB1 -:10498000412FB50194E1981B892F0F94E92333201F -:1049900039F01123C9F041145104B1F0F201199515 -:1049A0000F900F90DF91CF911F910F91FF90EF909B -:1049B000DF90CF90BF90AF909F908F907F906F903F -:1049C0005F904F903F9008950E946C2EE9CFEF9238 -:1049D000FF921F93CF93DF93EC01EE85FF85309715 -:1049E00009F01995EA80FB80E9A9FAA982E01995F6 -:1049F000E9A9FAA981E0199530E020E045E1B70185 -:104A0000CE010F944522182F882341F09E012D5C82 -:104A10003F4F47E1B701CE010F944522E9A9FAA91A -:104A200080E01995812FDF91CF911F91FF90EF903A -:104A30000895DC0114968D919C9115978617970720 -:104A400009F43CC015967C936E931497611571051B -:104A500079F157968C915797FB01811130C03596AB -:104A6000E4915896EC935897645F7F4FFB016491F3 -:104A700059966C93599758968C915897082E000C1C -:104A8000990B59962C915997821B910927FD939563 -:104A90005A962C915A97203441F0829FC0011124DC -:104AA00026E0969587952A95E1F75B968C935B9720 -:104AB00082E192E056969C938E93559708958130AB -:104AC00041F43F96E4915896EC935897605F7F4F7E -:104AD000CDCF3D96E4915896EC935897625F7F4F07 -:104AE000C5CF5F926F927F928F929F92AF92BF924B -:104AF000CF92DF92EF92FF920F931F93CF93DF93AA -:104B0000EC01562E142F622F0F94FD096C0180E0EA -:104B1000C114D104B1F08C819D810F94F309B82E9A -:104B2000FB88EC888989580E1E198A89181B0E2D5E -:104B30002F2D412F652DCE010F94A00A811111C098 -:104B40008889DF91CF911F910F91FF90EF90DF90B7 -:104B5000CF90BF90AF909F908F907F906F905F901D -:104B60000895CB0CD11C87E0F80EF694F694F694D9 -:104B7000E10E4E01ECE18E0E911C6F2C712C1E1576 -:104B8000F9F2052D560111C0F50184916A817B81EE -:104B90000C8F1D8F1F8E8E8F94014BE3CE010F94CF -:104BA0004522FFEFAF1ABF0A085F8A2D8C198F15B7 -:104BB00058F3C60CD71C1F5FE2CFFF920F931F93D1 -:104BC000CF93DF93D82FF62E8A01E0915E16F091F5 -:104BD0005F1689E496E11995F80EC0E0F80124917A -:104BE000222359F04F2D6D2F89E496E10F94712502 -:104BF000D80FC80F0F5F1F4FF1CF8C2FDF91CF91D0 -:104C00001F910F91FF900895DB011496ED91FC9197 -:104C100030E020E065E01994DB011496ED91FC9101 -:104C200030E020E062E01994DB011496ED91FC91F4 -:104C300030E020E063E01994CF92DF92EF92FF9290 -:104C40000F931F93CF93DF938C017B016A0180E068 -:104C5000F601C491811110C081E0CF3F49F04C2F83 -:104C6000B701C8010F940426882309F444C080E0EA -:104C7000BFEFCB1ADB0AECCF4FEFCF3F89F3CE3F2C -:104C8000D9F1C03FA0F7C03E38F04C2F4F70B701AC -:104C9000C8010F940C26EBCFC03D38F04C2F4F705D -:104CA000B701C8010F941426E2CFC03CF8F0D70139 -:104CB0001496ED91FC9130E020E040E064E0C80102 -:104CC0001995C295C07FCE5FD0E0CE010F94E60962 -:104CD000D7011496ED91FC9130E020E041E064E0D2 -:104CE000C8011995CE010F94E609C1CFC7FDBFCF0A -:104CF0008C2F90E0F8CF80E0DF91CF911F910F9142 -:104D0000FF90EF90DF90CF9008954F925F926F9257 -:104D10007F928F929F92AF92BF92CF92DF92EF924B -:104D2000FF920F931F93CF93DF93EC01562E142F16 -:104D3000622E402E220F220F220F0F94A00A8823EA -:104D400021F1410E4E018CE1880E911CA62CB12C54 -:104D50006701762C052D12C0F60184916A817B8152 -:104D60000C8F1D8F1F8E8E8F94014BE3CE010F94FD -:104D70004522FFEFCF1ADF0A7A94085F7110ECCF5B -:104D8000EA0CFB1C1F5F4112E3CFDF91CF911F9113 -:104D90000F91FF90EF90DF90CF90BF90AF909F90DA -:104DA0008F907F906F905F904F900895CF93DF9397 -:104DB000EC018991882319F00E949FCEFACFDF91F0 -:104DC000CF9108950E94E0DD8AE00C949FCE1F935E -:104DD000CF93DF93182FEB010E940FD886EC97E357 -:104DE0000E94ACCE82EB97E3113011F488EB97E38D -:104DF0000E94ACCEBE018EEB97E3DF91CF911F9165 -:104E00000D94E2268BE1E4EAF4E1A9E8B4E1019033 -:104E10000D928A95E1F78091A21780648093A21782 -:104E2000109297170895EF92FF920F931F93CF93CD -:104E3000DF93CDB7DEB7A7970FB6F894DEBF0FBEEE -:104E4000CDBF8091A21784FF0E948F7E8091A21710 -:104E500084FF58C08091981790E08F969F938F930E -:104E60008BEC97E39F938F938E01045E1F4F1F93EC -:104E70000F930F9448398091A2170F900F900F90C5 -:104E80000F900F900F9084FBFF24F0F884FF3AC03E -:104E90001FA21EA2A801BE016A5D7F4F80E00F9491 -:104EA000BD0C009779F119821C826EA17FA121E0CF -:104EB000AC01CE0101960E946A80E82E882321F081 -:104EC000CE0101960E945E7ECE0101960E94648012 -:104ED000EE20C1F00F940227C8010E949B798091B7 -:104EE00098178F5F809398178F2DA7960FB6F89419 -:104EF000DEBF0FBECDBFDF91CF911F910F91FF900D -:104F0000EF90089510929817F12CEECF0F931F9306 -:104F1000CF93DF9300D01F92CDB7DEB79C010AE894 -:104F200016E090E1E6E7F2E0D80101900D929A9543 -:104F3000E1F7F9012081318142815381F8016085D7 -:104F40007185828593850F94083EF801608771878B -:104F50008287938780E090E0A0EAB0E489839A8317 -:104F6000AB83BC83CE0101960E94E3B40F900F90F7 -:104F70000F900F90DF91CF911F910F910895109294 -:104F8000F8181092F71888EE93E0A0E0B0E0809354 -:104F9000F9189093FA18A093FB18B093FC1889E9BC -:104FA00093E09093F6188093F5181092A414109241 -:104FB000A7141092891410928C14E9E8F6E187E99D -:104FC00097E1108213827B968E179F07D1F78BEAA9 -:104FD00093E090930219809301191092031989E1CB -:104FE000809305191092081910928214109250148F -:104FF0001092531448E250E06FE370E08FEA95E1BD -:105000000F9457291092E2151092E3158091E41540 -:10501000807F8093E4151092E5151092E7151092A9 -:10502000E6151092E9151092E8151092EA1589EC30 -:1050300093E09093B0158093AF154BE350E060E49C -:1050400070E083E795E10F9457291092A61510920E -:10505000A7158091A815807F8093A8151092A91597 -:105060001092AB151092AA151092AD151092AC15B6 -:105070001092AE1589EC93E090937415809373159C -:105080004AE250E061E470E087E395E10F9457292C -:1050900010926A1510926B1580916C15807F809329 -:1050A0006C1510926D1510926F1510926E1510926E -:1050B0007115109270151092721589EC93E090930F -:1050C0003815809337154CE250E062E470E08BEFC6 -:1050D00094E10F94572910922E1510922F1580915C -:1050E0003015807F80933015109231151092331552 -:1050F0001092321510923515109234151092361503 -:1051000089EC93E09093FC148093FB1444E150E00D -:105110006CE070E08FEB94E10F9457291092F21439 -:105120001092F3148091F414807F8093F414109201 -:10513000F5141092F7141092F6141092F9141092BC -:10514000F8141092FA1489EC93E09093C0148093B1 -:10515000BF141092EB151092EC151092ED151092F1 -:10516000EE151092EF151092F4151092F51510929D -:10517000F6151092F7151092F8151092FD15109271 -:10518000FE151092FF151092001610920116109243 -:105190002B1610922C1610922D1610922E1610927D -:1051A0002716109228161092291610922A1610927D -:1051B000231610922416109225161092261610927D -:1051C0001F1610922016109221161092221610927D -:1051D0000B1610920C1610920D1610920E161092BD -:1051E0000A161092091610920816109207161092BD -:1051F000061684E0809332161092301610922F1605 -:10520000109231168DEC94E69093441680934316D9 -:10521000109248161092471687EE93E09093461628 -:10522000809345168FEF8093861680938716809320 -:10523000881680938316809384168093851681E068 -:1052400099E19093A4178093A3178091A217847E6D -:105250008B7F8093A21710929E1710929F17109227 -:10526000A0171092A11710929A1710929B171092E4 -:105270009C1710929D1710929917109298171092E0 -:105280009717E9E8F6E18EE091E0DF019C011D92BD -:1052900021503040E1F780910A018E7F80930A010E -:1052A00080910B0180958170809309010895CF92C0 -:1052B000DF92EF92FF920F931F93CF93DF93EC0156 -:1052C0008B016A011A821B828C81807F8C831D82F4 -:1052D0001E821F828885807F88878EEA97E4A1EEF0 -:1052E000BDE389879A87AB87BC8740E050E060E0E8 -:1052F0007FE34D875E876F87788B29EC33E03983B6 -:1053000028831A8A198A8B8B9C8BAD8BBE8B1F8A44 -:10531000188E898D8C7F898F1A8E8B8D807F8B8FD5 -:105320001D8E1C8E1E8E1F8E18A219A21AA21BA2E1 -:105330001CA21DA21EA21FA218A619A61BA61AA671 -:105340001DA61CA690E080E00C151D0511F4902F01 -:10535000812F9EA78FA719AA18AA1AAA8FE190E0F9 -:105360000F9422347C01DC0113961C921E9212973A -:1053700088EE93E0A0E0B0E0F70184839583A683F4 -:10538000B78387E893E091838083178A168A118E0A -:10539000108E138E128E158E148E668D6E7F6D7F1D -:1053A000668F6695617081E068278C2D0F945D187B -:1053B00061E08C2D0F942C1BF601E857F44CE4911E -:1053C000D7015096EC93F601EE5BF44CE491F0E0DB -:1053D000EE0FFF1FE85DF44C85919491F701928BDD -:1053E000818B60E0802F0F942C1BD7015E968C91EF -:1053F00081FD04C061E0802F0F945D18F7010487E0 -:10540000F801E857F44CE491D7011D96EC93F801AC -:10541000EE5BF44CE491F0E0EE0FFF1FE25FF44C22 -:1054200085919491F70197878687FDA6ECA6888DD4 -:1054300081608D7F8B7F888F898D8160898F8C8142 -:10544000807F81608C8384E18D8383E590E0A0E0A0 -:10545000B0E18AA39BA3ACA3BDA384E290E0ADE03E -:10546000B1EC8EA39FA3A8A7B9A7DF91CF911F91FD -:105470000F91FF90EF90DF90CF900895CF93DF933F -:10548000CDB7DEB7CF54D1090FB6F894DEBF0FBE4B -:10549000CDBF789484B5826084BD84B5816084BDBD -:1054A00085B5826085BD85B5816085BD80916E00C2 -:1054B000816080936E0010928100809181008260F3 -:1054C0008093810080918100816080938100809130 -:1054D00080008160809380008091B100846080931F -:1054E000B1008091B00081608093B0008091910004 -:1054F00082608093910080919100816080939100FF -:10550000809190008160809390008091A1008260E2 -:105510008093A1008091A10081608093A10080917F -:10552000A00081608093A00080912101826080931F -:1055300021018091210181608093210180912001CE -:1055400081608093200180917A00846080937A004A -:1055500080917A00826080937A0080917A008160E5 -:1055600080937A0080917A00806880937A0010920C -:10557000C10040900F194BA614BE1092C00080913C -:10558000C00082608093C0001092C50087E08093C5 -:10559000C4008091C10080618093C1008091C100EE -:1055A00088608093C1008091C10080688093C100B1 -:1055B0000F941E1D6B017C0128EEC20E23E0D21E4B -:1055C000E11CF11C8BE89FE00E949CCD882309F42C -:1055D0009DC089E99AE30E94ACCE9898A09A8091E8 -:1055E0006F0390917003A0917103B091720389A32E -:1055F0009AA3ABA3BCA3AE014F5D5F4F59AF48AFB9 -:10560000CE0185969EA38DA3C12CA4E2DA2EA4EF31 -:10561000EA2EF12CA8ADB9AD6D91B9AFA8AFCE010E -:1056200001960E949ECD8A89811190C18989882323 -:1056300009F48CC14F844FA6242D0FEF10E02230C7 -:1056400011F00FEF1FEF49805A805BAE4AAE6B80BE -:105650007C807EA66DA68EE0E3E7F3E0DE01539644 -:1056600001900D928A95E1F72FA5223009F057C0DD -:1056700031E023963FAF239743E024964FAF249722 -:10568000CE01439622969FAF8EAF229791E09CA7C2 -:10569000A1E0A8AB1DAAEFEFF0E0FFABEEAB2DEF62 -:1056A00030E038A72FA32296AEADBFAD22972D9044 -:1056B0003D902296BFAFAEAF2297BFA5B230C1F1E9 -:1056C000E0E22E16310409F413C1F0E82F1631047C -:1056D00009F40EC1E8EE4E2EE3E05E2E249C90010C -:1056E000259C300D349C300D112450E040E0C70162 -:1056F000B6010F94C63DC9010197369527950097CD -:10570000C9F441E050E05AAB49AB1BC00F941E1DD9 -:105710006C197D098E099F0997FDF8CF5ACF5AE081 -:1057200023965FAF23976EE024966FAF2497A8CFA0 -:105730009801C8011AAB09AB8017910710F49AAB16 -:1057400089AB2115310509F485C21CAB0BAB2017C1 -:10575000310710F43CAB2BAB4FA058A429EE4216F6 -:1057600023E0520608F47BC2C20128EE33E0821B1C -:10577000930B2C01712C612C4CAE5DAE6EAE7FAEE6 -:1057800089A99AA90196829D9001839D300D929DD1 -:10579000300D112450E040E0C701B6010F94C63D22 -:1057A00049015A0129013A0128EE821623E09206A6 -:1057B000A104B10430F478EE472E73E0572E612C2B -:1057C000712CD501C40139EE831633E09306A10490 -:1057D000B10420F088EE93E0A0E0B0E0A3019201D4 -:1057E000281B390B4A0B5B0B2C962CAF3DAF4EAFF1 -:1057F0005FAF2C97C101880F991F4BA85CA8849DAF -:105800009001859D300D949D300D112450E040E0B5 -:10581000C701B6010F94C63D60962CAF3DAF4EAFA9 -:105820005FAF6097283E63E036074105510550F4AD -:1058300088EE93E0A0E0B0E060968CAF9DAFAEAF95 -:10584000BFAF609728962CAF3DAF4EAF5FAF2897A4 -:10585000293E93E039074105510560F058EE452E89 -:1058600053E0552E612C712C28964CAE5DAE6EAE79 -:105870007FAE289760968CAD9DADAEADBFAD609705 -:1058800028964CAC5DAC6EAC7FAC2897841995091A -:10589000A609B70928968CAF9DAFAEAFBFAF2897CA -:1058A0004CAC5DAC6EAC7FAC2C968CAD9DADAEAD12 -:1058B000BFAD2C9784159505A605B70508F0D4C192 -:1058C00028964CAC5DAC6EAC7FAC28974816590658 -:1058D0006A067B0608F4C8C198A68FA224965FAC1E -:1058E000249758AA6CA46DAA89A89AA89FAA8EAAE0 -:1058F0002CA52F5F2CA7283009F0D5CEAAADBBADC3 -:105900008C918C7F98A99370892B8C93EDA5FEA523 -:10591000208148A8842D90E0959587959595879549 -:1059200043E0880F991F4A95E1F7277E822B8083F9 -:105930008081887F5DA8852980832FA5223031F062 -:10594000ED85FE854EA85FA8518240826DA07EA0A5 -:1059500088AC99AC6814790409F05CCE8FEA95E1C3 -:105960000F94681B83E795E10F94681B87E395E12B -:105970000F94681B8BEF94E10F94681B8FEB94E1FD -:105980000F94681B9BA490FE04C080E99AE30E94D8 -:10599000ACCEABA4A1FE04C08FE79AE30E94ACCECC -:1059A000BBA4B2FE04C08DE69AE30E94ACCECBA4A9 -:1059B000C3FE04C08CE59AE30E94ACCEDBA4D5FE06 -:1059C00004C08BE49AE30E94ACCE8BE39AE30E947E -:1059D000ACCE0E940FD88DE09AE30E94ACCE0E941C -:1059E0000FD885EF99E30E94ACCE0E940FD880912A -:1059F000091990910A199E012F5F3F4F5901B90172 -:105A0000009709F44EC1681B790B86EE99E30E945A -:105A100087DA60ED75E08FEC99E30E9404DB389A39 -:105A200040981092CB081092CC081092CD0810929A -:105A3000CE0810925C1810925B181092AC1810925D -:105A4000AB180F94971984E892E090935A188093BA -:105A5000591884E991E0909358188093571840E0C2 -:105A600060E080E00F94D6190E94594080915D1843 -:105A7000811107C00E940FC5882319F081E080932F -:105A80005D1885E496E10E94126B2AE4E22E28E379 -:105A9000F22E03E127E047E064E289E496E10F9407 -:105AA000852683E00E94AA3F42E458E36BE28BE242 -:105AB0000E94C46445E358E367E38CE10E94C46438 -:105AC00089E496E10F94E7248111DFCF0F941E1D26 -:105AD0002B013C012091E6083091E7084091E8084D -:105AE0005091E90860917602709177028091780276 -:105AF000909179020F94083E60937602709377023A -:105B000080937802909379022091EA083091EB0813 -:105B10004091EC085091ED0860917A0270917B02FF -:105B200080917C0290917D020F94083E60937A02EE -:105B300070937B0280937C0290937D022091EE080B -:105B40003091EF084091F0085091F10860917E0289 -:105B500070917F0280918002909181020F94083EA3 -:105B600060937E0270937F02809380029093810203 -:105B70000E947BB5249A2C988091010180618093CA -:105B800001018091020180718093000180910101E7 -:105B900080628093010180910201807280930001F4 -:105BA0009D9A8091010180648093010187ED80932B -:105BB0007A0010927E0010927D0080917D008062BC -:105BC00080937D0080917D00806880937D0080912E -:105BD0007D00806480937D0080E887BD80916E00A9 -:105BE000826080936E000DEC19E3F801C590D490AB -:105BF00035E0C316D1041CF495E0C92ED12CD09207 -:105C00006902C09268020D2C000CEE08FF0860E0EB -:105C100080916402909165020E9451836FA378A7DE -:105C200089A79AA7C701B6010F94B8399B01AC01A7 -:105C30006FA178A589A59AA50F94B13987FF34C0C3 -:105C400080916402909165024097909365028093E1 -:105C50006402DDCF81E090E09CAB8BAB7DCD2FA1CA -:105C600038A588EE93E083CD4CAC5DAC6EAC7FACD8 -:105C700028968CAC9DACAEACBFAC28978414950430 -:105C8000A604B70408F034CE38A72FA323969FAC00 -:105C9000239798AAACA4ADAA4BA85CA85FAA4EAA69 -:105CA00027CE6F507941B1CE81ED882E88E3982EB2 -:105CB000F401C590D49041E0C41AD10855E0C5164E -:105CC00051E0D50624F0B4E0CB2EDD24D394D0925D -:105CD0006B02C0926A020D2C000CEE08FF0860E017 -:105CE00080916602909167020E9451836FA378A70A -:105CF00089A79AA7C701B6010F94B8399B01AC01D7 -:105D00006FA178A589A59AA50F946840181654F438 -:105D1000809166029091670240969093670280930B -:105D20006602DDCFF801C590D49065E0C616D104B7 -:105D30001CF4A5E0CA2ED12CD0927102C092700240 -:105D40000D2C000CEE08FF0861E080916C02909130 -:105D50006D020E9451836FA378A789A79AA7C701F4 -:105D6000B6010F94B8399B01AC016FA178A589A544 -:105D70009AA50F94B13987FF0AC080916C02909167 -:105D80006D02409790936D0280936C02DDCFF40119 -:105D9000C590D49081E0C81AD10895E0C91691E069 -:105DA000D90624F0F4E0CF2EDD24D394D0927302F0 -:105DB000C09272020D2C000CEE08FF0861E0809189 -:105DC0006E0290916F020E9451836FA378A789A7FA -:105DD0009AA7C701B6010F94B8399B01AC016FA116 -:105DE00078A589A59AA50F946840181654F4809157 -:105DF0006E0290916F02409690936F0280936E02B4 -:105E0000DDCF80916202909163020E94E98520E0DB -:105E100030E040EA50E40F94B13987FF0AC0809126 -:105E200062029091630240979093630280936202B2 -:105E3000E8CF8091CF089091D0080E94E98520E0BA -:105E400030E04CED52E40F946840181654F4809101 -:105E5000CF089091D00840969093D0088093CF08B7 -:105E6000E8CF0E948BBB19A282E390E09C8B8B8BC6 -:105E70001A82198201E0950141E050E0BE016F5D98 -:105E80007F4FCE0143960E9461CE89A1863109F4ED -:105E90003EC10E94DE8E81E08093D1088091040192 -:105EA0008D7F80930401809105018095827080939D -:105EB000030153985B9A6C98749A1092E3081092BD -:105EC000E2080E9471B9819A879A80910A018260E2 -:105ED00080930A010E9A3B9A579A5F9A829A8A9AFD -:105EE000809107018160809307018091080180956E -:105EF0008170809306010A9A129A3F9A479A809A73 -:105F000088985F9A8091E4088E7F8093E408869A4F -:105F10008E988A9A8091E4088D7F8093E40880911E -:105F20000A01886080930A0180910B018870809338 -:105F3000090180910801809581708093060180910C -:105F4000E4088B7F8093E40880E090E0A6E1B3E46E -:105F500080937E0290937F02A0938002B09381028F -:105F60000E947BB50C9A1498129A399A4198479AD4 -:105F7000809180008C7F8093800080918100877E5B -:105F8000886080938100809180008F73809380006F -:105F900080918100887F82608093810080E090E41E -:105FA000909389008093880010928500109284005D -:105FB0000E944995789487E08093E5080E945A886A -:105FC00088E198E20FB6F894A895809360000FBE20 -:105FD000909360000F941E1DDC01CB01841995097C -:105FE000A609B709803AEFE09E07A105B10570F454 -:105FF00000EA1FE020E030E028013901481A590A80 -:106000006A0A7B0AC301B2010E9421CD21E041E06E -:1060100061E081E00E94FEDB83E080933509212C62 -:10602000E2E03E2E71E6972E6AE0862E80E00E9426 -:10603000EADD8091A21787FF21C010929817877F11 -:106040008B7F8093A2170E94677E10927710109228 -:106050007610109275100E9439B880E00E9416BB2D -:106060000E94B4850E9497CD1092740250EA652E6A -:106070005AE3752E7092F3086092F2088091350908 -:10608000CDB6DEB610E000E0843009F452C0ADB603 -:10609000BEB66091F2087091F30810E000E061155F -:1060A000710509F08DC08091F408882309F42BC193 -:1060B000E4EFF8E08F01045F1840F190FF2019F041 -:1060C0003AE0F312F7CF0115110559F0F801EC5041 -:1060D000F74F108284EF98E00E9457C880E00E943A -:1060E000D1EB81E0F11001C080E0080F802FE82F94 -:1060F000F0E0EC50F74F9081E82FE01BF0E0EC501F -:10610000F74F9083992309F498C08F5FF0CF83E312 -:1061100090E09C8B8B8B1A82198201E0950140E103 -:1061200050E062ED78E0CE0143960E9461CEB3CE9E -:106130008C01F801EC55F54CE491C8010196EE2371 -:1061400011F0EA30A9F7ADB6BEB6A81AB90A0FB673 -:10615000F894BEBE0FBEADBE2DB73EB72F5F3F4F0A -:106160007901A80164EA7AE3C9010F94DF38F701E5 -:10617000E00FF11F1082D7018C918B3331F40FB6F1 -:10618000F894DEBE0FBECDBE82CF809175108430F4 -:10619000B0F780917710899DC0011124B70188580C -:1061A0009F4E0F94ED4181E00F941C0F0FB6F894B1 -:1061B000DEBE0FBECDBEB3E0B093350968CF860119 -:1061C000FB01E00FF11F74906801EFEFCE1ADE0AB9 -:1061D000772019F0FAE07F12F2CF4DB65EB64C1878 -:1061E0005D080FB6F8945EBE0FBE4DBE2DB73EB72C -:1061F0002F5F3F4F7901A801C9010F94DF38F701E4 -:10620000E00FF11F1082772009F47AC08091F20824 -:106210009091F308C80ED91ED092F308C092F208EC -:10622000012B31F0C7010E9457C880E00E94D1EBDA -:106230000FB6F894BEBE0FBEADBE909134098091EA -:106240005E18981709F4F2CE8091340980935E1895 -:1062500080913409882309F4E7CE0E940FD88FEF8C -:106260009AE30E94ACCE8091340910E280FF0AC00C -:1062700080E00E94AFB2AB01BC018BEF9AE30E94B9 -:10628000A4CF18E58091340900E281FF0AC081E0C3 -:106290000E94AFB2AB01BC0187EF9AE30E94A4CF8A -:1062A00009E58091340982FF2CC282E00E94AFB2DE -:1062B000AB01BC0183EF9AE30E94A4CF9AE5F92ECB -:1062C0008AE00E949FCE1F9280E28F931F92FF92DE -:1062D0001F920F931F921F938BED9AE39F938F93BF -:1062E00084EE9AE39F938F931F920E94FA3AEDB740 -:1062F000FEB73D960FB6F894FEBF0FBEEDBF92CE2F -:10630000D12CC12C89CF80917510882309F495CFA9 -:106310008091A21780FFEFC100917610099D800146 -:10632000112408581F4E67ED7AE3C8010F942E39E7 -:10633000009739F0DC0113968C9180538A3008F075 -:10634000C5C1F80101900020E9F731977F01E01AFB -:10635000F10A109250146EE470E0C8010F94E2410B -:106360006C01009709F085C0B1E0EB1AF108F80163 -:10637000EE0DFF1D4DE0442E418282821382F80112 -:1063800001900020E9F731976F01C01AD10A80917E -:106390005314813009F069C08091511481FF65C0A8 -:1063A00082FF1CC04091611450916214609163148B -:1063B000709164148091581490915914A0915A14BA -:1063C000B0915B1484179507A607B70739F080E5ED -:1063D00094E10E94827C882309F447C040915814BC -:1063E0005091591460915A1470915B14C114D104E6 -:1063F00009F427C18091691490916A14DC01149604 -:106400007C902FEF270D2A013B0139E076946794A9 -:10641000579447943A95D1F742227A01B1E0FB2292 -:10642000411057C0E114F10409F053C040915414D5 -:10643000509155146091561470915714411551059F -:106440006105710529F58091651490916614A091FC -:106450006714B09168140097A105B10591F580E526 -:1064600094E10E94647F811134C081E080935014D4 -:106470000DC160E270E00F94E2418C010F5F1F4F8D -:106480006AE270E0C6010F94E241FC01319772CFDD -:106490009E012F5F3F4F0E94457B882331F3898106 -:1064A0009A81AB81BC81E0916914F0916A142789CB -:1064B000203109F085C0883FEFEF9E07A105B105A7 -:1064C00070F68093541490935514A0935614B0937F -:1064D00057145101AE18BF08CA14DB0408F4560162 -:1064E000E0916914F0916A148091541490915514BC -:1064F000A0915614B09157140297A109B1092585AE -:1065000004C0880F991FAA1FBB1F2A95D2F7468582 -:10651000578560897189840F951FA61FB71F9C013D -:10652000AD01240D311D411D511D29013A01A11458 -:1065300032E0B30609F04DC08091451490914614A5 -:10654000A0914714B0914814481659066A067B0674 -:1065500069F410924D148FEF9FEFDC018093451486 -:1065600090934614A0934714B093481480914E140E -:1065700090914F14DC01ED91FC910288F389E02D9C -:106580009801B301A2011995882309F46ECF809177 -:10659000581490915914A0915A14B0915B148A0D1B -:1065A0009B1DA11DB11D8093581490935914A09365 -:1065B0005A14B0935B140A0D1B1DCA18DB080ECFCA -:1065C000883FFFEF9F07AF07FFE0BF0708F479CFD1 -:1065D00046CFE114F10469F54091581450915914D3 -:1065E00060915A1470915B148091611490916214BF -:1065F000A0916314B0916414481759076A077B0788 -:10660000C0F00E94287A882309F42FCF81E080937C -:106610004D14409245145092461460924714709263 -:106620004814A501B801C7018B5B9D4E0F94C6416C -:10663000AECF41E0C301B2010E94717A8111F1CF66 -:1066400014CF8091611490916214A0916314B09161 -:10665000641484179507A607B70768F4809151144E -:1066600040936114509362146093631470936414A4 -:106670008068809351148091511483FF07C080E596 -:1066800094E10E94297E882309F4EFCE8091501472 -:10669000882331F00E940BD88DEA9AE30E94ACCE99 -:1066A0008091A21781FD27C0E09176109E9EF00197 -:1066B0001124E852FF4E8081811110C08AEA9AE3CA -:1066C0000E94ACCE8AE00E949FCE08C00F945F1259 -:1066D00084EC9AE30E94ACCE0E9491CF8091761018 -:1066E0008F5F843058F480937610809175108150BC -:1066F00080937510A2CD0F948506F0CF109276107E -:10670000F4CF80E2F82EDCCDCF93DF93EC012A8129 -:106710003B818C81482F4F7050E0E881F9810190D6 -:10672000F081E02D60E1CE0119956D81CE010F94CD -:10673000C7202E813F818885482F4F7050E0E88127 -:10674000F9810190F081E02D63E1CE011995488D2A -:10675000898D582F537070E060E0CE010F94CE21E8 -:106760002A8D8B8D382F3F7022273F702A8F932FD1 -:106770009F70807F892B8B8F50E040E0E881F9810A -:106780000190F081E02D63E0CE0119952E8D3F8DB3 -:1067900048A159A1E881F9810190F081E02D62E2E0 -:1067A000CE0119954AA15BA16CA17DA1CE010F94E8 -:1067B00002224EA15FA168A579A5CE010F94B22156 -:1067C0002BA93CA98DA9482F4F7050E0E881F98191 -:1067D0000190F081E02D64E1CE0119952EA930E001 -:1067E00050E040E0E881F9810190F081E02D60E423 -:1067F000CE0119952FA938AD50E040E0E881F9812C -:106800000190F081E02D62E4CE01DF91CF911994E7 -:10681000CF93DF9380E594E10E946480C7E9D7E1DC -:106820006B97CE010E94648086E1C938D807C1F712 -:1068300089E894E10E94648084EA94E1DF91CF9139 -:106840000C9464800F931F93CF93DF938230910554 -:1068500010F482E090E0E0910B19F0910C1930E017 -:1068600020E0B0E0A0E0309799F42115310509F45B -:106870004AC0281B390B24303105D8F58A819B8109 -:106880006115710589F1FB0193838283FE0111C0BB -:10689000408151810281138148175907E0F0481760 -:1068A000590799F4109761F012960C93129713966A -:1068B0001C933296CF01DF91CF911F910F910895D4 -:1068C00000930B1910930C19F4CF2115310551F0D9 -:1068D0004217530738F0A901DB019A01BD01DF011E -:1068E000F801C1CFEF01F9CF90930C1980930B19E8 -:1068F000CDCFFE01E20FF31F819391932250310916 -:1069000039832883D7CF2091091930910A19232B75 -:1069100041F4209188023091890230930A19209322 -:10692000091920918602309187022115310541F421 -:106930002DB73EB740918A0250918B02241B350B34 -:10694000E0910919F0910A19E217F307A0F42E1B40 -:106950003F0B2817390778F0AC014E5F5F4F2417C3 -:10696000350748F04E0F5F1F50930A1940930919DD -:10697000819391939FCFF0E0E0E09CCFCF93DF93A2 -:106980000097E9F0FC01329713821282A0910B1953 -:10699000B0910C19ED0130E020E01097A1F42081B6 -:1069A0003181820F931F2091091930910A192817FC -:1069B000390709F061C0F0930A19E0930919DF91D2 -:1069C000CF910895EA01CE17DF07E8F54A815B8190 -:1069D0009E0141155105B1F7E901FB83EA83499115 -:1069E0005991C40FD51FEC17FD0761F48081918187 -:1069F0000296840F951FE901998388838281938190 -:106A00009B838A83F0E0E0E012968D919C9113972E -:106A10000097B9F52D913C911197CD010296820F07 -:106A2000931F2091091930910A192817390739F64F -:106A3000309751F510920C1910920B19B0930A1956 -:106A4000A0930919BCCFD383C28340815181840FA5 -:106A5000951FC817D90761F44E5F5F4F88819981F0 -:106A6000480F591F518340838A819B81938382837E -:106A70002115310509F0B0CFF0930C19E0930B19F3 -:106A80009ECFFD01DC01C0CF13821282D7CF8F923F -:106A90009F92AF92BF92CF92DF92EF92FF920F93AD -:106AA0001F93CF93DF935C017B016115710519F092 -:106AB000DB018D939C9385010F5F1F4FF501D08102 -:106AC0008D2F90E00F94D6386C01892BB9F5DD320B -:106AD000B9F50F5F1F4FD5011196DC91C1E0580148 -:106AE000F1E0AF1AB10843E050E064E275E0C5019F -:106AF0000F940739892B69F5680182E0C80ED11C13 -:106B000045E050E06FE175E0C6010F940739892B2D -:106B100021F4680197E0C90ED11CE114F10419F0C9 -:106B2000D701CD92DC9260E070E080E89FEFC11168 -:106B3000FFC060E070E080E89FE7FAC05801BBCF7B -:106B4000DB3229F485010E5F1F4FF501D181C0E0D2 -:106B5000C6CF43E050E06CE175E0C5010F94073902 -:106B6000892BE9F0F80110E000E020E030E0A90115 -:106B70005F01B0ED8B2E8D0E89E08815C8F19C2E3B -:106B8000689491F88C2F8870C2FF16C0811102C0E2 -:106B90000F5F1F4F3196D501DC91C92DE9CFE1146C -:106BA000F10429F00E5F1F4FF7011183008360E0AD -:106BB00070E080EC9FE7BCC0882311F00150110900 -:106BC000A5E0B0E00F94E53D9B01AC01220F331F1F -:106BD000441F551F280D311D411D511D283999E9AC -:106BE0003907490799E15907A8F2C6609C2ED2CF10 -:106BF000AEEF8A1206C0C3FD3CC09C2E689493F889 -:106C0000C9CFDF7DD534A9F580818D3239F4C061DB -:106C1000DF011296818162E070E006C0DF018B32F5 -:106C2000C1F3119661E070E080535D01A61AB70AC6 -:106C30008A30F8F4E0E8CE16ECE0DE065CF4B6014B -:106C4000660F771F660F771FC60ED71ECC0CDD1C94 -:106C5000C80ED11C5D01FFEFAF1ABF0A8C918053A3 -:106C60008A30A8F1C4FF03C0D194C194D1080C0D9F -:106C70001D1DC1FF09C0E114F10431F081E0A81A23 -:106C8000B108D701AD92BC92CA01B9010F94B639CF -:106C9000C370C33009F490584B015C0120E030E030 -:106CA000A9010F94B139882309F440C0C3E5D5E0A8 -:106CB00017FF05C0119501951109CBE3D5E06E01D1 -:106CC000B8E1CB1AD10880E2E82EF12C0FC0D50133 -:106CD000B1CFFE0125913591459154910E191F09AF -:106CE000C501B4010F94173A4B015C01D501C401F1 -:106CF0000E151F0574F72497F594E794CC16DD065E -:106D0000A9F78A2F880F8B2F881F8F3F49F020E02B -:106D100030E0A901C501B4010F94B139811106C059 -:106D200082E290E090930E1980930D19C501B40191 -:106D3000DF91CF911F910F91FF90EF90DF90CF9057 -:106D4000BF90AF909F908F9008953F924F925F9227 -:106D50006F927F928F929F92AF92BF92CF92DF926B -:106D6000EF92FF920F931F93CF93DF935C016B0120 -:106D70007A016115710519F0FB0191838083E1149B -:106D8000F10451F0C7010297839730F040E030E002 -:106D900020E090E06BC05E01E5012196F5011081D5 -:106DA000812F90E00F94D638892BA9F71D3201F579 -:106DB0002196F501118101E0E114F10409F4E6C026 -:106DC000F0E1EF16F10409F088C0103359F488811E -:106DD0008F7D883509F07CC0198122960260F0E130 -:106DE000EF2EF12C812C912CA12C88E0B82E92C092 -:106DF0001B3221F4E5012296F501118100E0DCCF80 -:106E0000EAE0EE16F10409F4C7C0F0E1EF16F10470 -:106E100009F073C0E7CF78E0E72EF12C812C912C9C -:106E2000A12C60E1B62E76C021E0ADC0302F3170CC -:106E3000C114D10431F0222371F12197F601D183DD -:106E4000C08327FF2EC060E070E080E090E8311141 -:106E500004C06FEF7FEF8FEF9FE722E230E03093C7 -:106E60000E1920930D19462F372F282F642F732FBB -:106E7000822FDF91CF911F910F91FF90EF90DF90C4 -:106E8000CF90BF90AF909F908F907F906F905F90CA -:106E90004F903F90089501FF04C02297F601D183DF -:106EA000C083332341F090958095709561957F4F15 -:106EB0008F4F9F4FD8CF97FFD6CF82E290E090932D -:106EC0000E1980930D196FEF7FEF8FEF9FE7CBCFF8 -:106ED00010E3E114F10409F49ECF28E0E216F10476 -:106EE00009F49CCF0CF08CCF812C912CA12CE0E4E8 -:106EF000BE2E82E0E816F10469F060E070E080E008 -:106F000090E897010F2C000C440B550B0F94A43DF7 -:106F100049015A0120E060E070E0CB0127010F2C0D -:106F2000000C66087708FE0150ED352E310E39E071 -:106F3000331570F43FEB310F49EC342E3A3138F011 -:106F40003FE9310F3A3108F071CF39EA332E310E73 -:106F50003E141F040CF06ACF27FD15C08616970655 -:106F6000A806B90678F0A30192010F94943D630D31 -:106F7000711D811D911D61307105810520E8920709 -:106F800008F452CF2FEF21961081CDCF103309F4A2 -:106F90001ECF2AE0E22EF12C9CEC892E982CA82CF6 -:106FA0009CE0B92EB7CF3F924F925F926F927F9243 -:106FB0008F929F92AF92BF92CF92DF92EF92FF9209 -:106FC0000F931F93CF93DF935C016B017A016115DF -:106FD000710519F0FB0191838083E114F10449F0FC -:106FE000C7010297839728F060E070E0CB019BC057 -:106FF0005E01E5012196F5011081812F90E00F944B -:10700000D638892BA9F71D3209F05CC02196F5010D -:10701000118101E0E114F10409F4BBC0F0E1EF16C5 -:10702000F10409F09BC0103341F488818F7D8835CD -:1070300009F08FC0198122960260E0E1EE2EF12C5A -:1070400088248A94982CA82CFFE0BF2E20E060E0D2 -:1070500070E0CB0127010F2C000C66087708FE01B9 -:1070600050ED352E310E39E0331568F43FEB310F1A -:1070700049EC342E3A3130F03FE9310F3A31B0F576 -:1070800039EA332E310E3E141F0484F52F3FB9F038 -:1070900086169706A806B90638F1A30192010F9447 -:1070A000943D232D30E050E040E0620F731F841FB9 -:1070B000951F6217730784079507B0F021E02196AA -:1070C0001081CDCF1B3221F4E5012296F50111810B -:1070D00000E0A0CF78E0E72EF12C88248A94982C49 -:1070E000A82C6FE1B62EB2CF2FEFE9CFC114D10497 -:1070F00031F0222351F12197F601D183C08300FFA3 -:1071000007C090958095709561957F4F8F4F9F4FE9 -:107110002F3F49F482E290E090930E1980930D196D -:107120006FEF7FEFCB01DF91CF911F910F91FF9018 -:10713000EF90DF90CF90BF90AF909F908F907F9017 -:107140006F905F904F903F90089501FFD8CF2297A6 -:10715000D3CF10E3E114F10409F4BCCF3AE0E31615 -:10716000F104E9F080E1E816F10409F466CFE8E003 -:10717000EE16F10409F4B1CF6FEF7FEFCB01970169 -:107180000F2C000C440B550B0F94A43D49015A01E0 -:107190005DCF103309F449CF9AE0E92EF12C89E94B -:1071A000882E982CA82C89E1B82E50CF91110D94DF -:1071B000863C803219F089508550C8F70895FB014C -:1071C000DC0102C005900D9241505040D8F708955F -:1071D000FB01DC010D900020E9F7119705900D925D -:1071E0000020E1F70895FC010590061621F000202B -:1071F000D9F7C00108953197CF010895FC0105909A -:107200000020E9F7809590958E0F9F1F0895FB0150 -:10721000DC014150504088F08D9181341CF08B3559 -:107220000CF4805E659161341CF06B350CF4605E8B -:10723000861B611171F3990B0895881BFCCFFB012C -:10724000DC014150504048F005900D920020C9F7F4 -:1072500001C01D9241505040E0F70895FB01559147 -:107260005523A9F0BF01DC014D9145174111E1F70C -:1072700059F4CD010590002049F04D914015411180 -:10728000C9F3FB014111EFCF81E090E00197089530 -:107290000F931F93CF93DF93CDB7DEB72E970FB623 -:1072A000F894DEBF0FBECDBF0E891F898EE08C83A0 -:1072B0001A8309838FEF9FE79E838D83AE01465E1D -:1072C0005F4F688D798DCE0101960F94843A2F819E -:1072D0003885020F131FF80110822E960FB6F8940E -:1072E000DEBF0FBECDBFDF91CF911F910F910895EB -:1072F0000F931F93CF93DF93CDB7DEB72E970FB6C3 -:10730000F894DEBF0FBECDBF8C01FA018EE08C83F6 -:107310001A83098377FF02C060E070E86150710949 -:107320007E836D83A901BF01CE0101960F94843A3B -:107330004D815E8157FD0AC02F8138854217530762 -:107340000CF49A01020F131FF80110822E960FB64B -:10735000F894DEBF0FBECDBFDF91CF911F910F918B -:1073600008950F94F33908F481E00895E89409C072 -:1073700097FB3EF490958095709561957F4F8F4F68 -:107380009F4F9923A9F0F92F96E9BB279395F6957E -:10739000879577956795B795F111F8CFFAF4BB0FFC -:1073A00011F460FF1BC06F5F7F4F8F4F9F4F16C060 -:1073B000882311F096E911C0772321F09EE8872FEA -:1073C000762F05C0662371F096E8862F70E060E0A6 -:1073D0002AF09A95660F771F881FDAF7880F96951F -:1073E000879597F90895990F0008550FAA0BE0E8C3 -:1073F000FEEF16161706E807F907C0F01216130677 -:10740000E407F50798F0621B730B840B950B39F4B6 -:107410000A2661F0232B242B252B21F408950A261C -:1074200009F4A140A6958FEF811D811D08950F9449 -:107430002A3A0D94443D0F94363D38F00F943D3D6B -:1074400020F0952311F00D942D3D0D94333D112422 -:107450000D94783D0F94553D70F3959FC1F3950FB2 -:1074600050E0551F629FF001729FBB27F00DB11DC8 -:10747000639FAA27F00DB11DAA1F649F6627B00D58 -:10748000A11D661F829F2227B00DA11D621F739F41 -:10749000B00DA11D621F839FA00D611D221F749F4F -:1074A0003327A00D611D231F849F600D211D822F96 -:1074B000762F6A2F11249F5750409AF0F1F08823BD -:1074C0004AF0EE0FFF1FBB1F661F771F881F9150EA -:1074D0005040A9F79E3F510580F00D942D3D0D942D -:1074E000783D5F3FE4F3983ED4F3869577956795B2 -:1074F000B795F795E7959F5FC1F7FE2B880F911D14 -:107500009695879597F908952F923F924F925F92A3 -:107510006F927F928F929F92AF92BF92CF92DF92A3 -:10752000EF92FF920F931F93CF93DF9300D000D081 -:1075300000D01F921F92CDB7DEB77C013B018A01BC -:10754000FC0117821682838181FFDDC1CE01019685 -:107550005C01F7019381F30193FD859193FF819184 -:107560003F01882309F453C1853239F493FD859195 -:1075700093FF81913F01853229F4B70190E00F9488 -:107580009F3CE7CF912C212C312CFFE1F31538F0F3 -:107590008B3211F190F4803209F1833229F137FCFA -:1075A0003CC020ED280F2A3050F536FE20C08AE07E -:1075B000989E200D1124922E06C08D3291F08033BA -:1075C00071F7689430F8F30193FD859193FF8191F1 -:1075D0003F018111DACF21C0689431F8689432F804 -:1075E000F2CF689433F8EFCF689434F8ECCFEAE048 -:1075F0002E9E200D1124222E689435F8E4CF8E3271 -:1076000029F436FC04C1689436F8DDCF8C3619F4C1 -:10761000689437F8D8CF8836B1F2982F9F7D95546B -:107620009330E0F08336A1F18337C1F1833509F05F -:1076300063C02801F2E04F0E511CF801C080D180D8 -:10764000692D70E036FC02C06FEF7FEFC6010F942A -:10765000893C4C01689437F882010AC00C5F1F4FC7 -:10766000FFE3F98388248394912C6501E89437F82B -:1076700033FE2DC0522C8114910471F5552009F46C -:1076800068CFB70180E290E00F949F3C5A94F6CF08 -:10769000F801808189830E5F1F4FE4CF2801F2E05B -:1076A0004F0E511CF801C080D180692D70E036FC6E -:1076B00002C06FEF7FEFC6010F94943C4C01820132 -:1076C000D5CFB70180E290E00F949F3C2A94281414 -:1076D000190409F0B0F7CECFF60137FC859137FEDB -:1076E00081916F01B70190E00F949F3C51105A9423 -:1076F000F1E08F1A9108BFCF843619F0893609F06E -:1077000077C0F80137FE6BC06081718182819381FF -:107710000C5F1F4FF32DFF763F2E97FF09C090950A -:107720008095709561957F4F8F4F9F4F689437F884 -:107730002AE030E0A5010F94CF3CC82ECA188C2C4B -:10774000432C36FE0CC0E89440F8C91440F434FED3 -:1077500005C032FC03C0F32DFE7E4F2E892C44FE63 -:10776000AAC0FE01EC0DF11D8081803309F09CC0A0 -:10777000242D297E422E842D8870582E43FCAAC0C9 -:1077800040FEA4C09C2C821418F42C0C922C981847 -:1077900044FEA6C0B70180E390E00F949F3C42FEF8 -:1077A00009C088E790E041FE02C088E590E0B7019B -:1077B0000F949F3CC91408F49FC0CA94D12C9FEF2A -:1077C000C91AD90ACA0CDB1CF60182916F01B701F4 -:1077D00090E00F949F3CAC14BD04B1F74FCF608193 -:1077E0007181072E000C880B990B0E5F1F4F92CFF3 -:1077F000D32CE894D4F82AE030E08537E1F1232D4A -:10780000297FD22E8F36A9F1F0F4883551F1F70196 -:10781000868197812B960FB6F894DEBF0FBECDBF41 -:10782000DF91CF911F910F91FF90EF90DF90CF905C -:10783000BF90AF909F908F907F906F905F904F9090 -:107840003F902F900895803749F0883701F7D4FE94 -:1078500002C06894D2F820E130E00DC06894D4F8FA -:10786000F6CF34FE03C0822F8660D82E20E132E0AE -:1078700002C028E030E0F801D7FE0FC060817181BE -:10788000828193810C5F1F4FA5010F94CF3CC82EBE -:10789000CA183D2CE89437F852CF6081718190E08E -:1078A00080E00E5F1F4FF0CF42FC02C0839463CF95 -:1078B0008394839460CF842D867809F45CCFF6CFCF -:1078C000B70180E290E00F949F3C83948214C0F350 -:1078D000512C5ECF522C5818821408F459CFF8CF8F -:1078E000842D867809F466CF8BE241FE80E247FC66 -:1078F0008DE2B70190E05CCFB70180E390E00F9498 -:107900009F3C9A9457CF8FEF9FEF84CF992788277A -:107910000895FC010590615070400110D8F78095E2 -:1079200090958E0F9F1F0895FC016150704001904B -:107930000110D8F7809590958E0F9F1F08950F9393 -:107940001F93CF93DF93182F092FEB018B8181FDBC -:1079500009C01FEF0FEF812F902FDF91CF911F9163 -:107960000F91089582FF14C02E813F818C819D81EB -:10797000281739073CF4E881F981CF0101969983F2 -:10798000888310838E819F8101969F838E83E3CFAE -:10799000E885F985812F1995892BA1F3DACFFA01B2 -:1079A000AA27283051F1203181F1E8946F936E7F3E -:1079B0006E5F7F4F8F4F9F4FAF4FB1E03ED0B4E02F -:1079C0003CD0670F781F891F9A1FA11D680F791F70 -:1079D0008A1F911DA11D6A0F711D811D911DA11D81 -:1079E00020D009F468943F912AE0269F1124301991 -:1079F000305D3193DEF6CF010895462F4770405D2C -:107A00004193B3E00FD0C9F7F6CF462F4F70405DDA -:107A10004A3318F0495D31FD4052419302D0A9F735 -:107A2000EACFB4E0A6959795879577956795BA952F -:107A3000C9F700976105710508959B01AC010A2EF5 -:107A400006945795479537952795BA95C9F7620FCC -:107A5000731F841F951FA01D089597F99F6780E8E5 -:107A600070E060E008959FEF80EC089500240A9490 -:107A70001616170618060906089500240A94121609 -:107A80001306140605060895092E0394000C11F43C -:107A9000882352F0BB0F40F4BF2B11F460FF04C0E9 -:107AA0006F5F7F4F8F4F9F4F089557FD9058440F42 -:107AB000551F59F05F3F71F04795880F97FB991F4D -:107AC00061F09F3F79F0879508951216130614060A -:107AD000551FF2CF4695F1DF08C016161706180697 -:107AE000991FF1CF86957105610508940895E89472 -:107AF000BB2766277727CB0197F90895F999FECF21 -:107B000092BD81BDF89A992780B50895262FF999DD -:107B1000FECF1FBA92BD81BD20BD0FB6F894FA9A70 -:107B2000F99A0FBE01960895DB018F939F930F94EE -:107B3000E53DBF91AF91A29F800D911DA39F900D38 -:107B4000B29F900D11240895A1E21A2EAA1BBB1B0F -:107B5000FD010DC0AA1FBB1FEE1FFF1FA217B30719 -:107B6000E407F50720F0A21BB30BE40BF50B661F2F -:107B7000771F881F991F1A9469F7609570958095F3 -:107B800090959B01AC01BD01CF010895052E97FB97 -:107B90001EF400940F94DD3D57FD07D00F94A43DD3 -:107BA00007FC03D04EF40D94DD3D50954095309583 -:107BB00021953F4F4F4F5F4F089590958095709559 -:107BC00061957F4F8F4F9F4F08950F94F83DA59F6C -:107BD000900DB49F900DA49F800D911D11240895C8 -:107BE000B7FF0D94E53D0F94E53D821B930B08957F -:107BF000A29FB001B39FC001A39F700D811D1124EE -:107C0000911DB29F700D811D1124911D0895505832 -:107C1000BB27AA270F941F3E0D94443D0F94363D79 -:107C200038F00F943D3D20F039F49F3F19F426F4CD -:107C30000D94333D0EF4E095E7FB0D942D3DE92FB7 -:107C40000F94553D58F3BA176207730784079507D9 -:107C500020F079F4A6F50D94773D0EF4E0950B2E07 -:107C6000BA2FA02D0B01B90190010C01CA01A0018E -:107C70001124FF27591B99F0593F50F4503E68F1E9 -:107C80001A16F040A22F232F342F4427585FF3CF2A -:107C9000469537952795A795F0405395C9F77EF4FB -:107CA0001F16BA0B620B730B840BBAF09150A1F044 -:107CB000FF0FBB1F661F771F881FC2F70EC0BA0FCA -:107CC000621F731F841F48F4879577956795B79552 -:107CD000F7959E3F08F0B0CF9395880F08F099274D -:107CE000EE0F9795879508950F94363D60F080E8E4 -:107CF00091E009F49EEF0F943D3D28F040E851E0FB -:107D000071F45EEF0CC00D94333D0D94773DE92F77 -:107D1000E0780F94553D40F3092E052AB1F326175C -:107D200037074807590738F00E2E07F8E02569F0A5 -:107D3000E025E0640AC0EF6307F8009407FADB016E -:107D4000B9019D01DC01CA01AD01EF930F94193F08 -:107D50000F94443D0F94B73E5F91552339F02BEDBE -:107D60003FE049E450FD49EC0D94083E0895DF934F -:107D7000DD27B92FBF7740E85FE3161617064807DF -:107D80005B0718F4D92F0F946D409F938F937F93C7 -:107D90006F930F94F640E4EEF0E00F94EA3F0F94F7 -:107DA000443D2F913F914F915F910F942A3ADD23EB -:107DB00051F09058A2EA2AED3FE049EC5FE3D07819 -:107DC0005D270F941F3EDF910D94443D0F9450406A -:107DD00090F09F3748F4911116F40D94783D60E0CF -:107DE00070E080E89FE3089526F01B16611D711D69 -:107DF000811D0D94C13F0D94DC3F0F941340E3951A -:107E00000D943C400F94163F0D94443D0F943D3D1E -:107E100058F00F94363D40F029F45F3F29F00D945F -:107E20002D3D51110D94783D0D94333D0F94553DEA -:107E300068F39923B1F3552391F3951B550BBB2799 -:107E4000AA2762177307840738F09F5F5F4F220FDE -:107E5000331F441FAA1FA9F335D00E2E3AF0E0E8D5 -:107E600032D091505040E695001CCAF72BD0FE2F1F -:107E700029D0660F771F881FBB1F261737074807B3 -:107E8000AB07B0E809F0BB0B802DBF01FF2793586B -:107E90005F4F3AF09E3F510578F00D942D3D0D94C3 -:107EA000783D5F3FE4F3983ED4F3869577956795E8 -:107EB000B795F7959F5FC9F7880F911D96958795A0 -:107EC00097F90895E1E0660F771F881FBB1F6217BF -:107ED00073078407BA0720F0621B730B840BBA0B7D -:107EE000EE1F88F7E09508950F947B3F6894B111D9 -:107EF0000D94783D08950F945D3D88F09F5798F05C -:107F0000B92F9927B751B0F0E1F0660F771F881F9E -:107F1000991F1AF0BA95C9F714C0B13091F00F94B7 -:107F2000773DB1E008950D94773D672F782F88272E -:107F3000B85F39F0B93FCCF3869577956795B395DF -:107F4000D9F73EF490958095709561957F4F8F4F4E -:107F50009F4F08950F94504090F09F3748F491112F -:107F600016F00D94783D60E070E080E89FEB089596 -:107F700026F41B16611D711D811D0D94C13F0D94CA -:107F8000DC3F882371F4772321F09850872B762FDC -:107F900007C0662311F499270DC09051862B70E01D -:107FA00060E02AF09A95660F771F881FDAF7880F2E -:107FB0009695879597F908959F3F31F0915020F459 -:107FC000879577956795B795880F911D96958795B5 -:107FD00097F90895DF93CF931F930F93FF92EF923A -:107FE000DF927B018C01689406C0DA2EEF010F94BA -:107FF0002A3AFE01E894A591259135914591559134 -:10800000A6F3EF010F941F3EFE019701A801DA9439 -:1080100069F7DF90EF90FF900F911F91CF91DF9163 -:1080200008950D94333D0F945D3DD8F3E894E0E05E -:10803000BB279F57F0F02AED3FE049EC06C0EE0F5A -:10804000BB0F661F771F881F28F0B23A62077307BD -:10805000840728F0B25A620B730B840BE3959A9550 -:1080600072F7803830F49A95BB0F661F771F881F10 -:10807000D2F790480D94DE3FEF93E0FF07C0A2EAED -:108080002AED3FE049EC5FEB0F941F3E0F94443D17 -:108090000F90039401FC9058E1E1F1E00D9406414A -:1080A0000F945D3DA0F0BEE7B91788F4BB279F3859 -:1080B00060F41616B11D672F782F8827985FF7CFC9 -:1080C000869577956795B11D93959639C8F3089570 -:1080D0000F94F33908F48FEF08959B01AC0160E031 -:1080E00070E080E89FE30D94023F0F945D3D58F1EE -:1080F0009E5760F19851A0F0E9F0983020F5092ED4 -:108100009927660F771F881F991F0A94D1F712C00D -:10811000062E672F782F8827985F11F4000C07C070 -:10812000993FB4F38695779567959395D9F7611D37 -:10813000711D811D3EF490958095709561957F4FDE -:108140008F4F9F4F089568940D94783D0D94773D1F -:108150009F930F9413400F9007FCEE5F0D943C40EB -:1081600019F416F40D94333D0D94DC3F0F945D3DEE -:10817000B8F39923C9F3B6F39F57550B87FF0F94B4 -:10818000FF400024A0E640EA90018058569597955C -:1081900028F4805C660F771F881F20F026173707AA -:1081A000480730F4621B730B840B202931294A2BBA -:1081B000A69517940794202531254A2758F7660F6E -:1081C000771F881F20F026173707480730F4620B07 -:1081D000730B840B200D311D411DA09581F7B90152 -:1081E000842F9158880F9695879508959B01AC012F -:1081F0000D94173A0F94F339880B990B0895915009 -:108200005040660F771F881FD2F708959F938F9372 -:108210007F936F93FF93EF939B01AC010F94173AF9 -:10822000EF91FF910F94EA3F2F913F914F915F9112 -:108230000D94173A991B79E004C0991F961708F01E -:10824000961B881F7A95C9F78095089587FB082E9D -:10825000062687FD819567FD61950F941A410EF4FE -:10826000919507FC81950895AA1BBB1B51E107C09E -:10827000AA1FBB1FA617B70710F0A61BB70B881FB6 -:10828000991F5A95A9F780959095BC01CD01089545 -:1082900097FB072E16F4009407D077FD09D00F94B2 -:1082A000344107FC05D03EF4909581959F4F089589 -:1082B000709561957F4F0895EE0FFF1F881F8BBF4C -:1082C0000790F691E02D1994AA27992329F4A85F25 -:1082D000982B11F480E10895903118F4AD5F9295D8 -:1082E000A395990FE8F78A2F99270895002E083053 -:1082F00090F0982F872F762F652F542F432F322FF2 -:1083000022270850F4CF220F331F441F551F661F2A -:10831000771F881F991F0A95B2F7002D089597FDC2 -:108320001094002E083098F00850232F342F452F3A -:10833000562F672F782F892F912DF4CF159497956D -:1083400087957795679557954795379527950A951A -:10835000AAF71124002D089581E090E0F8940D947F -:108360001C429111089581548A5108F4805E855A07 -:108370000895FB01DC0104C08D910190801921F466 -:1083800041505040C8F7881B990B0895FB01DC0150 -:1083900002C001900D9241505040D8F70895FB0162 -:1083A000DC018D9181341CF08B350CF4805E619181 -:1083B00061341CF06B350CF4605E861B611189F32F -:1083C000990B0895FC018191861721F08823D9F734 -:1083D000992708953197CF010895FB01DC010190A1 -:1083E0000D920020E1F70895FB01DC01415050405F -:1083F00030F08D910190801919F40020B9F7881B95 -:10840000990B0895FB01DC014150504048F0019068 -:108410000D920020C9F701C01D9241505040E0F775 -:108420000895FC0181E090E00190061609F4CF0167 -:108430000020D1F7019708951EE1C7E4DEE100E0D6 -:1084400006C0802FFE010F945C412196011DC834A7 -:0C845000D10780E00807A9F7F894FFCFDF -:10845C00104000000080020430290002AC00FFFF35 -:10846C00FF01CDCCCC3DFA00D20001010000803FD1 -:10847C006400640064000000803F0000803FFFFF48 -:10848C00FFFFFFFFFF080101000000E6C20000A88B -:10849C00C2000000000000184300009A42000016C1 -:1084AC00430000C841010D0D0202C0D4010064005C -:1084BC00AA00FF3FFF3F00000000FF3FFF3F00000E -:1084CC000000FF3F0103000018430000A8C2000099 -:1084DC00164300000000000010198000003C1C46F0 -:1084EC00003C1C46003C1C46003C1C4658595A4556 -:1084FC00000100FF0100FF000202000048420000E2 -:10850C0048420000804000000040D505C705B70573 -:10851C00040104010000204100002041CDCCCC3EE0 -:10852C00000000400000C07F0000C07F0000C07F42 -:10853C00FF003C00010000404000003442000000FD -:10854C00000000000000000000000050410000008E -:10855C000000000041640000006400000003000003 -:10856C000064000000640000000300000003000031 -:10857C0000030000001E0000001E0000000000169A -:10858C0043000096420000A04156383600FFFF40E1 -:10859C0040CF38CF384400000000004700480000AE -:1085AC00000000000101010000164300009642008B -:1085BC0000A04100001643000096420000A0410AB2 -:1085CC0005062E010008002000400080000001007C -:1085DC0004000000000000F201DE00B5240401409C -:1085EC000220023001000000008C02B000B524040F -:1085FC0001DA01CE0034010000000095756E76ADF5 -:10860C00743D759274A5732D7488734F754E74C731 -:10861C006F4A704970000000007C01DC01E6019C8F -:10862C0000E200E0018401280200011001BE008676 -:10863C00011602000000000929DE00B5244970452E -:0A864C005252005A00590058000075 -:00000001FF diff --git a/Marlin.ino.with_bootloader.mega.hex b/Marlin.ino.with_bootloader.mega.hex deleted file mode 100644 index 74a3d5e..0000000 --- a/Marlin.ino.with_bootloader.mega.hex +++ /dev/null @@ -1,10813 +0,0 @@ -:020000040000FA -:100000000C94481E0C94881E0C94881E0C94881E18 -:100010000C94881E0C94881E0C94881E0C94881EC8 -:100020000C94881E0D944B200D944B200D944B2066 -:100030000C94881E0C94881E0C94881E0C94881EA8 -:100040000C94881E0C941A880C94881E0C94881E9C -:100050000C94881E0C947C850C94881E0D94DD1ED7 -:100060000C94881E0C9499DD0C948FDD0C94881EE2 -:100070000C94881E0C94881E0C94881E0C94881E68 -:100080000C94881E0C94881E0C94881E0C94881E58 -:100090000C94881E0C94881E0C94881E0D94271FA7 -:1000A0000C94881E0C94881E0C94881E0C94881E38 -:1000B0000C94881E0C94881E0C94881E0C94881E28 -:1000C0000C94881E0C94881E0C94881E0C94881E18 -:1000D0000C94881E0C94881E0C94881E0C94881E08 -:1000E0000C94881E084AD73B3BCE016E84BCBFFDF2 -:1000F000C12F3D6C74319ABD56833DDA3D00C77FF8 -:1001000011BED9E4BB4C3E916BAAAABE0000008090 -:100110003F05A84CCDB2D44EB93836A9020C50B91F -:10012000918688083CA6AAAA2ABE000000803F004B -:100130000C942C440C941F4E0D94C8090C94BE963C -:100140000C945E270C941C440C942D740C9418444D -:100150000D94B0180C9433CE0D940A1C0C9473605B -:100160000D9475070C94DA220C94EE340C94A230A2 -:100170000C94462E0C946E260C9413CE0D94C30949 -:100180000C9439470C94DE470C946E280C94879697 -:100190000C942A250D94A8180C94AB960D945B072B -:1001A0000C943A2E0C9496260C94FC470C946A25D9 -:1001B0000C94012E0D94251C0C94662D0D94D206E2 -:1001C0000C940C440D9426090C9485270C940E482D -:1001D0000C94D7200C9428230C94C3960C94EFCD48 -:1001E0000C9457CE0C941A480D94671C0C94092952 -:1001F0000C94EB270C9424510C9406560C947628FE -:100200000D94E0090C94CD640D944B070C947E265C -:100210000C94FA480C9401320C9421240C94D32CA5 -:100220000D942E090C946E760C94A7280C944A70A9 -:100230000C943F960C943D750C94D92B0C94CC2BBC -:100240000C94BF270C94F5CB0C94C8260C94F1CBDE -:100250000C94432E0D94F0090C94F6470C94F32063 -:100260000D94D1070C944D2E0D944C070C94583BD3 -:100270000C94F21E0C9432280D948D180C94EF23DC -:100280000C9428440D94C3180C9459CE0C94BE5869 -:100290000C9456260C944B2E0C94A5730C94C920E8 -:1002A0000C9466260C9436470C94372E0D94BF2779 -:1002B0000C94C76F0C9444270C94FA340D94CB180B -:1002C0000C94B0200C9435CE0C944D700D94D9182C -:1002D0000D94831C0C94145F0C942E270C948F2582 -:1002E0000C944F750C9402480C94C6220C94A622D0 -:1002F0000D94731C0C94A8530D94C41C0D940834D5 -:100300000C94312E0C94F4340D94D6090D945C09A0 -:100310000C94B2530C940B370C9486260C94501FFB -:100320000C9419390C9424440D94D1060C948E3BF2 -:100330000C94FC220D94791C0C9408440C94062314 -:100340000D9492180C9422C60C94EF570C940C5CEC -:100350000C94DD2B0C947A280C94532E0C94E126EB -:100360000C94E4470C945E260D94D1180C947228DA -:100370000C94EA470C94C8230C94AC270C94497055 -:100380000C9492740C943F260C94502E0C94742868 -:100390000C9433470C9493960C9492220C94D84767 -:1003A0000C94111F0C948B250C944F450C94AD5359 -:1003B0000C944D3E0D946E070D944C1D0C940CCC7A -:1003C0000D947F090D94A4180C94CFCD0D9446097B -:1003D0000C943A240C9408CC0C9408240C941448E3 -:1003E0000D94B9180D94E9070C947C280D94AC1861 -:1003F0000C9416350C940F350C9495750C9437CEDF -:100400000C944C450C940FCE0C9464630C94E8222D -:100410000D94D5180C9430290C9452450C94F36D1E -:100420000C9420440D94F1090C94F0470D94CD09DF -:100430000C94A1240C94AD740C9499270C94C3CD06 -:100440000D945D080D94621C0D94BD180C945150D0 -:100450000D94A1090C945BCE0C94BE1E0C94A69630 -:100460000C944B270C9428280C948A1E0C949C25E1 -:100470000C942DC50C94342E0C94B7530C9408484E -:100480000D9445080C9411CE0C94635A0C94E771AA -:100490000C9488730C948D2E0D94B3180C94AF2685 -:1004A0000C9476260C94B0220C94142F0C94E52016 -:1004B0000C94444B0C9410440C944E740C94A4244F -:1004C0000C9463250D948E1C0C94402E0C94924C2D -:1004D0000D94E3180C9471270C9478280C94013532 -:1004E0000C942F960C94B5240D94DF180C947E2850 -:1004F0000C9408350C94061F0C943D2E0C94EDCDF5 -:100500000C9414230C94DF2C0D94D0060D94C71872 -:100510000C94262E0C9414440D94A2074E414E497F -:100520004E495459494E46CDCCCC3D0AD7233C17B1 -:10053000B7D13877CC2B329595E6241FB14F0A00FE -:100540000020410000C84200401C4620BCBE4CCAEE -:100550001B0E5AAEC59D741FE0201023102490106E -:10056000A011202210241037B00840048003001F7F -:10057000E02010211023101520112021102110310E -:10058000300840048003001FE03FF03CF03B701F48 -:10059000601EE03DF03BF038700FC0078003001F85 -:1005A000E03FF03EF03CF01AE01EE03EF03EF03E50 -:1005B000F00FC007800300554E4C4F414420464980 -:1005C0004C414D454E54004C4F41442046494C410E -:1005D0004D454E540046494C414D454E54204348EC -:1005E000414E47450041425300504C410045727214 -:1005F0003A207574663820666F6E74206E6F7420B2 -:10060000696E697469616C697A65642E00FFE0FF48 -:10061000D140A0C8A6A22FF80023AC00AF10FFFE67 -:10062000FF05FFD0FFE0FFC1FFD1E240A0C8A6A2B6 -:100630002FF800238127AC00AFFFD0FF64FFD1A5C6 -:10064000FFD0FF64FF64FFD1A4FFD0FF16FFFE427E -:10065000656400456E636C6F73757265002568751F -:100660003A25303268750025303268753A253032C7 -:100670006875002530326875272530326875002589 -:100680006875642025303268753A25303268750007 -:1006900020202020202020002020202000657272B1 -:1006A000006F0557059F0587053FFFF03800703044 -:1006B000FC3020FC102078102030102C00D02E317F -:1006C000D02F7BD02F7BD02E31D02C00D0203010DB -:1006D00020781020FC1030FC303800703FFFF03FD5 -:1006E000FFF03800703186302387102787902F87DE -:1006F000D02F03D020301020781020781020301018 -:100700002F03D02F87D0278790238710318630384A -:1007100000703FFFF01FFFF81FFFF80410400208B1 -:1007200020020820041040082080104100104100E1 -:100730000820800410400000001FFFF81FFFF85041 -:1007400072696E742041626F72746564004D323557 -:1007500020500A4D32340050617573696E672E2E39 -:100760002E004D3234004C6F6164202A004C6F61C2 -:1007700064206D6D00556E6C6F6164202A00556EAB -:100780006C6F6164206D6D0046696C2E2044696158 -:100790002E202A0046696C2E204469612E004520D7 -:1007A000696E206D6D5E3300200820466163740021 -:1007B0002008204D6178002008204D696E004F66AA -:1007C00066004F6E004175746F74656D70004D6901 -:1007D0006E2054726176656C205370656564004DBF -:1007E000696E2056656C6F63697479004D6178207D -:1007F00040205370656564004D6178204520416359 -:1008000063656C004D6178204020416363656C0036 -:1008100054726176656C20416363656C0052657447 -:100820007261637420416363656C00416363656C4E -:1008300000402073746570732F6D6D0041647661A4 -:100840006E6365642053657474696E6773003F005E -:1008500043616E63656C00496E6974004D343238D3 -:1008600000496E697469616C697A6520454550522A -:100870004F4D0046696C616D656E740054656D7016 -:100880006572617475726500544D432044726976D7 -:100890006572730053746570732F6D6D004A756EC9 -:1008A0006374696F6E2044657600416363656C65AF -:1008B000726174696F6E004D617820537065656474 -:1008C00020286D6D2F73290053657420486F6D6566 -:1008D000204F66667365747300436F6E6669677553 -:1008E000726174696F6E005A2052616973650032DB -:1008F0006E64204E6F7A7A6C652040004265640019 -:100900004E6F7A7A6C650046616E2053706565643F -:1009100000436F6E66696775726174696F6E00522D -:100920006573746F72652044656661756C747300DD -:100930004C6F61642053657474696E6773005374FF -:100940006F72652053657474696E677300507265C9 -:1009500068656174202420436F6E6600546F6F6C6D -:10096000204368616E676500546F6F6C204F666648 -:100970007365747300416476616E636564205365CA -:100980007474696E6773004D61696E004D37303263 -:1009900020542564004D36303020423020542564E8 -:1009A000004D373032203B2564004D373031205424 -:1009B0002564004368616E67652046696C616D65FA -:1009C0006E7400556E6C6F61642046696C616D6574 -:1009D0006E74004C6F61642046696C616D656E7465 -:1009E000005072656865617420437573746F6D00A3 -:1009F000507265686561742024004261636B005524 -:100A00006E6C6F6164202A004C6F6164202A004381 -:100A100068616E67652046696C616D656E74202A39 -:100A2000004D61696E00436F6E74696E75650050AC -:100A300075726765206D6F726500524553554D455F -:100A4000204F5054494F4E533A005052494E542073 -:100A50005041555345440020204E6F7A7A6C653AD8 -:100A600020005061726B696E672E2E2E00000057B9 -:100A700061697420666F720066696C616D656E7481 -:100A8000206368616E676500746F207374617274AF -:100A9000005761697420666F720066696C616D65EC -:100AA0006E7420756E6C6F616400004E6F7A7A6CA4 -:100AB000652068656174696E6700506C6561736577 -:100AC00020776169742E2E2E00005072657373209A -:100AD000627574746F6E00746F2068656174206E47 -:100AE0006F7A7A6C650000496E736572742066696E -:100AF0006C616D656E7400616E64207072657373F5 -:100B000020627574746F6E00746F20636F6E746909 -:100B10006E7565005761697420666F720066696C56 -:100B2000616D656E74206C6F616400005072657356 -:100B30007320427574746F6E00746F2072657375E4 -:100B40006D65207072696E7400005761697420666B -:100B50006F72207072696E7400746F2072657375A5 -:100B60006D652E2E2E00005761697420666F72002D -:100B700066696C616D656E742070757267650000E2 -:100B80004D36303020423020542569004D37303109 -:100B900020542569004D37303220542569005669AC -:100BA0006F6C657400496E6469676F00426C7565AF -:100BB00000477265656E0059656C6C6F77004F7207 -:100BC000616E67650052656400576869746500422C -:100BD0006C756520496E74656E736974790047722F -:100BE00065656E20496E74656E736974790052652F -:100BF0006420496E74656E73697479004C454420B5 -:100C0000436F6E74726F6C00437573746F6D204C1C -:100C10006967687473004C69676874205072657303 -:100C20006574730044656661756C74004F66660098 -:100C30004F6E004C6967687473004D61696E003FC8 -:100C4000004261636B0053746F70004E6F204D65FE -:100C5000646961005072696E742066726F6D204D18 -:100C600065646961004368616E6765204D6564690C -:100C700061004D3231004C696768747300436861EC -:100C80006E67652046696C616D656E7400436F6EBA -:100C900066696775726174696F6E0054656D706521 -:100CA000726174757265004D6F74696F6E00526584 -:100CB00073756D65205072696E740054756E6500B1 -:100CC00053746F70205072696E7400506175736553 -:100CD000205072696E7400496E666F2053637265AE -:100CE000656E003F005374617274205072696E74B7 -:100CF0000043616E63656C005072696E74004361FD -:100D00006E6E6F7420656E746572207375626469AF -:100D1000723A200002202E2E004D61696E004D6F48 -:100D2000766520246D6D00302E303235004D6F76A3 -:100D30006520302E316D6D004D6F766520316D6D03 -:100D4000004D6F76652031306D6D002100486F7465 -:100D5000656E6420746F6F20636F6C640042616322 -:100D60006B0050726F63656564004D6F7665202A75 -:100D7000004D6F7665204578747275646572004D1C -:100D80006F76652040004D6F74696F6E0044697323 -:100D900061626C65205374657070657273004D38C4 -:100DA00034004732385A004732385900486F6D6571 -:100DB00020400047323858004175746F20486F6DED -:100DC0006500473238004D6F7665204178697300C1 -:100DD0004D61696E0050726568656174202420421F -:100DE00065640050726568656174202420416C6CF4 -:100DF0000050726568656174202420456E64207E11 -:100E000000507265686561742024207E0054656D11 -:100E1000706572617475726500E905E505436F6F71 -:100E20006C646F776E005072656865617420240091 -:100E300046616E205370656564207E0042656400E3 -:100E40004E6F7A7A6C65207E004D61696E00453286 -:100E5000004531005A005900580045320045310024 -:100E60005A0059004F6666004F6E005800544D43BB -:100E7000204472697665727300537465616C74689E -:100E800043686F7020456E61626C656400537465E1 -:100E90007070696E67204D6F646500447269766595 -:100EA000722043757272656E7400416476616E6380 -:100EB00065642053657474696E677300466C6F7760 -:100EC000207E00466C6F770046616E20537065652A -:100ED00064207E00426564004E6F7A7A6C65207EE5 -:100EE000005370656564004D61696E00000C0F0071 -:100EF000FE07022503BB017FFE08FE08FE05080869 -:100F000006000040F0C88888987810050808060098 -:100F100000C0F88888888888F80505050600012043 -:100F200030F830200508080600002070F820202046 -:100F300020E00509090600FF2070A8A8B88888707D -:100F400020070505070001D86C366CD8050909068D -:100F500000FFF8A88888888888A8F8050A0A06008B -:100F6000FE205050505088A8A88870030303060044 -:100F70000340A040FFFFFFFFFFFFFFFFFFFFFFFF5A -:100F8000FFFFFFFFFFFFFFFFFFFF0000000605FF61 -:100F90000107070602008080808080008003030331 -:100FA000060105A0A0A005060606000050F8505056 -:100FB000F8500509090600FF2070A8A07028A87045 -:100FC00020050707060000C8C810204098980507AC -:100FD0000706000040A0A040A89068010303060295 -:100FE000058080800309090601FF20404080808041 -:100FF0004040200309090601FF8040402020204096 -:10100000408005070706000020A8702070A8200572 -:1010100005050600012020F820200203030601FF39 -:10102000C04080050101060003F80202020601002B -:10103000C0C00507070600000810102040408005CA -:101040000707060000708898A8C88870030707067D -:10105000010040C040404040E00507070600007026 -:101060008808102040F8050707060000F80810302F -:1010700008887005070706000010305090F810101F -:10108000050707060000F880F008088870050707C4 -:10109000060000304080F0888870050707060000D1 -:1010A000F808101020202005070706000070888827 -:1010B0007088887005070706000070888878081017 -:1010C00060020505060100C0C000C0C00206060699 -:1010D00001FFC0C000C0408003050506010120409B -:1010E000804020050303060002F800F8030505060A -:1010F000010180402040800507070600007088102D -:10110000202000200507070600007088B8A8B880D6 -:1011100070050707060000708888F888888805072A -:1011200007060000F04848704848F0050707060029 -:101130000070888080808870050707060000F048EE -:1011400048484848F0050707060000F88080F0800E -:1011500080F8050707060000F88080F08080800591 -:1011600007070600007088808098887005070706CA -:101170000000888888F8888888030707060100E04F -:101180004040404040E005070706000038101010BE -:101190001090600507070600008890A0C0A0908806 -:1011A000050707060000808080808080F80507071B -:1011B00006000088D8A888888888050707060000E8 -:1011C0008888C8A89888880507070600007088885E -:1011D00088888870050707060000F08888F08080FE -:1011E0008005070706000070888888A890680507B2 -:1011F00007060000F08888F0A09088050707060021 -:101200000070888070088870050707060000F820C5 -:10121000202020202005070706000088888888886D -:1012200088700507070600008888888850502005C8 -:10123000070706000088888888A8A85005070706C1 -:10124000000088885020508888050707060000881D -:10125000885020202020050707060000F8081020ED -:101260004080F80309090601FFE0808080808080CB -:1012700080E00507070600008040402010100803AA -:1012800009090601FFE020202020202020E005039E -:10129000030600052050880501010600FEF803033F -:1012A000030601058040200505050600007008784A -:1012B00088780507070600008080F0888888F00598 -:1012C000050506000070808088700507070600008D -:1012D000080878888888780505050600007088F079 -:1012E0008070050707060000304840E04040400598 -:1012F00007070600FE7088888878087005070706CB -:1013000000008080F0888888880307070601004075 -:1013100000C0404040E00409090601FE1000301002 -:10132000101010906005070706000080808890E08C -:101330009088030707060100C04040404040E00598 -:101340000505060000D0A8A8A8A805050506000008 -:10135000B0C88888880505050600007088888870F0 -:101360000507070600FEF0888888F08080050707DB -:101370000600FE78888888780808050505060000BC -:10138000B0C880808005050506000078807008F0F0 -:101390000507070600002020F82020201805050575 -:1013A000060000888888986805050506000088887A -:1013B0008850200505050600008888A8A850050566 -:1013C0000506000088502050880507070600FE88A3 -:1013D000888850204080050505060000F810204050 -:1013E000F80309090601FF204040408040404020AA -:1013F0000109090602FF8080808080808080800350 -:1014000009090601FF80404040204040408005031C -:101410000306000248A890FF486F6D696E6720467A -:1014200061696C6564006F70656E0054524947478E -:1014300045524544003A20007A5F6D696E00795F3D -:101440006D696E00785F6D6178005265706F7274BF -:10145000696E6720656E6473746F70207374617455 -:1014600075730A000000184300009A4200001643FA -:101470000000E6C20000A8C20000000020746F6FE8 -:10148000206C6F6E6720657874727573696F6E205B -:1014900070726576656E7465640A0020636F6C64B3 -:1014A00020657874727573696F6E207072657665E9 -:1014B0006E7465640A00000018430000A8C20000B2 -:1014C00000005761726E696E673A20486F6D696EF1 -:1014D000672042756D702044697669736F72203C95 -:1014E00020310A00020204008085430000214300ED -:1014F0000016430000A0400000A040000000400093 -:10150000000001000000010000800055555500005A -:1015100000400033333300AAAA2A00499224000075 -:10152000002000C7711C0099991900D1451700557A -:101530005515003BB1130024491200111111000090 -:101540000010000F0F0F00E3380E0043790D00CCA0 -:10155000CC0C00C3300C00E8A20B0064210B00AAE5 -:10156000AA0A00703D0A009DD80900427B0900923A -:10157000240900DCD3080088880800104208000015 -:10158000000800F0C1070087870700755007007149 -:101590001C07003EEB0600A1BC0600699006006631 -:1015A000660600703E06006118060017F405007418 -:1015B000D105005BB00500B29005006272050055D0 -:1015C00055050078390500B81E0500050505004ED3 -:1015D000EC040087D40400A1BD040090A7040049D6 -:1015E000920400C17D0400EE690400C75604004463 -:1015F0004404005C3204000821040041100400008F -:101600000004003FF00300F8E0030026D20300C30B -:10161000C30300CCB503003AA803000A9B030038BB -:101620008E0300C08103009F750300D06903005042 -:101630005E03001D53030034480300913D03003353 -:1016400033030016290300381F03009715030030E9 -:101650000C0300030303000BFA020049F10200BA75 -:10166000E802005CE002002DD802002DD0020059F3 -:10167000C80200B0C0020031B90200DAB10200AA0B -:10168000AA0200A0A30200BC9C0200FA9502005C22 -:101690008F0200DF88020082820200457C02002760 -:1016A00076020027700200436A02007C640200D0C8 -:1016B0005E02003F590200C8530200FFFDFCFAF829 -:1016C000F6F4F2F0EEECEAE9E7E5E3E1E0DEDCDA9D -:1016D000D9D7D5D4D2D0CFCDCBCAC8C7C5C3C2C045 -:1016E000BFBDBCBAB9B7B6B4B3B2B0AFADACAAA9BE -:1016F000A8A6A5A4A2A1A09E9D9C9A99989795940E -:101700009392908F8E8D8B8A89888786848382813D -:10171000807F7E7D7B7A797877767574737271704D -:101720006F6E6D6C6B6A6968676665646362616041 -:101730005F5E5D5C5B5A5958585756555453525129 -:1017400050504F4E4D4C4B4A4A49484746464544F7 -:1017500043424241403F3E3E3D3C3B3B3A393838B4 -:1017600037363535343332323130302F2E2E2D2C62 -:101770002B2B2A2929282727262525242323222104 -:101780002120201F1E1E1D1C1C1B1B1A1919181896 -:10179000171616151514131312121111100F0F0E20 -:1017A0000E0D0D0C0C0B0A0A09090808070706069E -:1017B0000505040403030202010000DB0FC93F45D5 -:1017C000BCDA3F8FB30240FCF0274056946140FEE4 -:1017D0004B9B4084A5D840E0231841346A5641E829 -:1017E00059974164DBD5416E271742B4B75542CEB5 -:1017F0001A9742C8AED542B5885A43D40684BFA6CC -:101800005FA7BF7443E0BF10B11AC01C2C58C0E8DA -:10181000F697C0B849D6C04E4E17C124D355C180E3 -:101820002497C1A0B5D5C1121A17C244AE55C278CB -:101830001797C26CACD5C267885AC320746F6F20EB -:101840006C6F6E6720657874727573696F6E207047 -:10185000726576656E7465640A0020636F6C64203F -:10186000657874727573696F6E2070726576656ED7 -:101870007465640A0053657474696E6773205374E9 -:101880006F72656400290A002062797465733B20D9 -:10189000637263200053657474696E6773205374B8 -:1018A0006F726564202800454550524F4D20496EA7 -:1018B000697469616C697A65640A0048617264637D -:1018C0006F6465642044656661756C74205365744B -:1018D00074696E6773204C6F616465640020286DC5 -:1018E0006D290020460020420020480020204D3174 -:1018F00034352053004D6174657269616C206865F0 -:101900006174757020706172616D657465727300C9 -:1019100020204D39303600205431204500205430ED -:101920002045005374657070657220647269766535 -:10193000722063757272656E740020204D353639E1 -:1019400020533100543120450054302045002058A8 -:1019500000447269766572207374657070696E6791 -:10196000206D6F64650020204D3134392043203BC9 -:1019700020556E69747320696E2043656C736975B8 -:10198000730A0054656D70657261747572652055D7 -:101990006E697473002020473231203B004C696E21 -:1019A00065617220556E69747300454550524F4D04 -:1019B000206461746173697A65206572726F722E3A -:1019C0000A00290A002062797465733B2063726300 -:1019D00020002073746F7265642073657474696E7F -:1019E00067732072657472696576656420280020CB -:1019F0002863616C63756C6174656429210A002039 -:101A0000213D2000454550524F4D20435243206D0B -:101A100069736D61746368202D202873746F72651B -:101A2000642920002053697A653A2000496E646574 -:101A3000783A200000007A4300007A430000A04179 -:101A40000000C8428747BC428747BC420000C843E9 -:101A5000E78CC042E8030000E803000064000000D7 -:101A600088130000204D61726C696E3D563836292E -:101A70000A00454550524F4D2076657273696F6E6E -:101A8000206D69736D617463682028454550524F1D -:101A90004D3D0024F4D43050C38E20C2A2401782A2 -:101AA0008B7011127A910D816CD90AA861E108C777 -:101AB000586607615143061E4B5D05C145A7041AD0 -:101AC000411104093D9803713931034036DB026549 -:101AD000339102D4305402802E1D02632CEE017526 -:101AE0002AC501B028A001102781018F2564012B90 -:101AF000244B01E0223401AC211F018D200D018017 -:101B00001FFC00841EED00971DDF00B81CD200E60C -:101B10001BC600201BBC00641AB200B219A8000A40 -:101B200019A0006A189900D117910040178B00B5D1 -:101B300016840031167E00B31579003A157300C77C -:101B4000146F0058146A00EE1366008813630025B2 -:101B5000135E00C7125B006C12570015125400C1CF -:101B600011510070114F0021114B00D61049008D0A -:101B70001047004610440002104200C00F40008091 -:101B80000F3E00420F3C00060F3B00CB0E38009387 -:101B90000E37005C0E3500270E3400F30D3200C105 -:101BA0000D3100900D3000600D2E00320D2D00051E -:101BB0000D2C00D90C2B00AE0C2900850C29005CE3 -:101BC0000C2700350C27000E0C2600E80B2400C45F -:101BD0000B2400A00B23007D0B23005A0B2100399E -:101BE0000B2100180B2000F80A1F00D90A1E00BBA9 -:101BF0000A1E009D0A1D00800A1D00630A1C004782 -:101C00000A1B002C0A1B00110A1A00F7091A00DD32 -:101C1000091900C4091900AB091900920917007BC2 -:101C2000091800630917004C091600360916002030 -:101C30000916000A091500F5081500E0081400CC83 -:101C4000081400B8081400A4081400900813007DBC -:101C50000812006B081300580812004608120034DE -:101C6000081100230811001208110001081100F0EA -:101C7000071000E0071000D0071000C0071000B0E8 -:101C8000070F00A107100091070E0083070F0074D3 -:101C9000070F0065070E0057070E0049070E003BAF -:101CA000070D002E070E0020070D0013070D00067C -:101CB000070D00F9060C00ED060D00E0060C00D43F -:101CC000060C00C8060C00BC060C00B0060C00A4F4 -:101CD000060B0099060C008D060B0082060B0077A0 -:101CE000060B006C060B0061060A0057060B004C41 -:101CF000060A0042060A0038060A002E060A0024D8 -:101D0000060A001A060A001006090007060A00FD66 -:101D1000050900F4050900EB050900E2050900D9F1 -:101D2000050900D0050900C7050900BE050900B571 -:101D3000050800AD050800A50509009C05080094EC -:101D40000508008C050800840508007C050800745F -:101D50000508006C050700650508005D05070056CD -:101D60000508004E05070047050700400508003834 -:101D7000050700310507002A050700230507001C99 -:101D8000050600160507000F0507000805060002F6 -:101D9000050700FB040600F5040700EE040600E852 -:101DA000040600E2040700DB040600D5040600CFA9 -:101DB000040600C9040600C3040600BD040600B7FB -:101DC000040600B1040500AC040600A6040600A049 -:101DD0000405009B04060095040500900406008A93 -:101DE00004050085040500800406007A04050075DA -:101DF000040500700405006B04050066040500611D -:101E00000405005C04050057040500520405004D5C -:101E100004050048040500430405003E0404003A9C -:101E200004050035040500300404002C04050027D7 -:101E3000040400230405001E0404001A0404001610 -:101E4000040500110404000D040400090405000445 -:101E500004040000040400FC030400F8030400F47C -:101E6000030400F0030400EC030400E8030400E4AE -:101E7000030400E0030400DC030400D8030400D4DE -:101E8000030400D0030400CC030400C8030300C50E -:101E900003030024F404D9201BC40C5C0E9804C472 -:101EA000095F0265077101F405F900FB04B30048FE -:101EB000048700C10369005803550003034500BEB1 -:101EC000023A008402310053022A0029022500044C -:101ED000022000E4011C00C8011900AF011700989E -:101EE0000114008401130071011000610110005100 -:101EF000010E0043010D0036010B002B010B0020E9 -:101F0000010B00150109000C01090003010800FB89 -:101F1000000800F3000800EB000700E4000600DE04 -:101F2000000600D8000600D2000600CC000500C75D -:101F3000000500C2000500BD000400B9000400B5A2 -:101F4000000400B1000400AD000400A9000400A5D5 -:101F5000000300A20003009F0004009B0003009800 -:101F60000003009500020093000300900003008D21 -:101F70000002008B0003008800020086000200843B -:101F8000000300810002007F0002007D0002007B50 -:101F90000002007900020077000100760002007460 -:101FA00000020072000100710002006F0002006D6B -:101FB0000001006C0002006A000100690002006775 -:101FC000000100660001006500010064000200627B -:101FD00000010061000100600001005F0002005D7F -:101FE0000001005C0001005B0001005A0001005983 -:101FF0000001005800010057000100560001005583 -:102000000001005400010053000000530001005281 -:1020100000010051000100500001004F0001004E7E -:102020000000004E0001004D0001004C0001004B7B -:102030000000004B0001004A000100490001004877 -:102040000000004800010047000100460000004673 -:10205000000100450000004500010044000100436C -:102060000000004300010042000000420001004166 -:1020700000000041000100400001003F0000003F5F -:102080000001003E0000003E0001003D0000003D58 -:102090000001003C0000003C0000003C0001003B4F -:1020A0000000003B0001003A0000003A0001003946 -:1020B000000000390001003800000038000000383E -:1020C0000001003700000037000100360000003634 -:1020D000000000360001003500000035000000352A -:1020E000000100340000003400000034000100331F -:1020F0000000003300000033000100320000003215 -:102100000000003200010031000000310000003109 -:102110000001003000000030000000300001002FFE -:102120000000002F0000002F0000002F0001002EF3 -:102130000000002E0000002E0001002D0000002DE8 -:102140000000002D0000002D0001002C0000002CDC -:102150000000002C0000002C0001002B0000002BD0 -:102160000000002B0000002B0001002A0000002AC4 -:102170000000002A0000002A0001002900000029B8 -:1021800000000029000000290000002900010028AB -:10219000000000280000002800000028000000289F -:1021A0000001002700000027000000270000002792 -:1021B0000000002700010026000000260000002685 -:1021C0000000002600000026000100250000002578 -:1021D000000000250000002500000025000000256B -:1021E000000100240000002400000024000000245E -:1021F0000000002400010023000000230000002351 -:102200000000002300000023000000230000002342 -:102210000001002200000022000000220000002235 -:102220000000002200000022000100210000002127 -:10223000000000210000002100000021000000211A -:10224000000000210001002000000020000000200C -:1022500000000020000000200000002000000020FE -:10226000000000200001001F0000001F0000001FF0 -:102270000000001F0000001F0000001F0000001FE2 -:102280000001001E0000001E0000001E0000001ED5 -:10229000000000393000003325000087190000B02D -:1022A0000F0000DB080000BD040000740200003FC6 -:1022B00001000020436F756E7420583A00453200CB -:1022C000426564004531004500626564002C20735E -:1022D000797374656D2073746F7070656421204824 -:1022E00065617465725F49443A20004572723A2014 -:1022F0004D415854454D50004D415854454D502086 -:102300007472696767657265640048656174696EB7 -:1023100067204661696C65640048656174696E6731 -:10232000206661696C6564004572723A204D494EC1 -:1023300054454D50004D494E54454D5020747269DE -:1023400067676572656400544845524D414C2052A0 -:10235000554E4157415900546865726D616C205269 -:10236000756E6177617900202F0020400020424087 -:102370003A0020403A00496E76616C6964206578C5 -:102380007472756465720A004163746976652045EC -:10239000787472756465723A20000009121B242D4E -:1023A000363F48415A536C657E7719100B023D3415 -:1023B0002F265158434A757C676E323B2029161FE1 -:1023C000040D7A7368615E574C452B2239300F0635 -:1023D0001D14636A7178474E555C646D767F404981 -:1023E000525B2C253E3708011A137D746F665950D5 -:1023F0004B42353C272E1118030A565F444D727B21 -:1024000060691E170C053A3328214F465D546B62F4 -:102410007970070E151C232A31384148535A656CD0 -:10242000777E09001B122D243F3658514A437C7594 -:102430006E671019020B343D262F737A6168575E60 -:10244000454C3B3229201F160D046A6378714E47B4 -:102450005C55222B3039060F141D252C373E010800 -:10246000131A6D647F7649405B523C352E27181154 -:102470000A03747D666F5059424B171E050C333AA0 -:1024800021285F564D447B7269600E071C152A2374 -:102490003831464F545D626B707900002110422044 -:1024A00063308440A550C660E770088129914AA135 -:1024B0006BB18CC1ADD1CEE1EFF1311210027332AC -:1024C0005222B5529442F772D662399318837BB385 -:1024D0005AA3BDD39CC3FFF3DEE36224433420043C -:1024E0000114E664C774A44485546AA54BB52885D5 -:1024F0000995EEE5CFF5ACC58DD55336722611168C -:102500003006D776F6669556B4465BB77AA7199724 -:102510003887DFF7FEE79DD7BCC7C448E558866813 -:10252000A7784008611802282338CCC9EDD98EE974 -:10253000AFF9488969990AA92BB9F55AD44AB77AEB -:10254000966A711A500A333A122AFDDBDCCBBFFBC4 -:102550009EEB799B588B3BBB1AABA66C877CE44CFB -:10256000C55C222C033C600C411CAEED8FFDECCD14 -:10257000CDDD2AAD0BBD688D499D977EB66ED55ECB -:10258000F44E133E322E511E700E9FFFBEEFDDDF64 -:10259000FCCF1BBF3AAF599F788F8891A981CAB1F0 -:1025A000EBA10CD12DC14EF16FE18010A100C23022 -:1025B000E3200450254046706760B9839893FBA3DD -:1025C000DAB33DC31CD37FE35EF3B1029012F32272 -:1025D000D2323542145277625672EAB5CBA5A8952D -:1025E00089856EF54FE52CD50DC5E234C324A014C2 -:1025F00081046674476424540544DBA7FAB79987BD -:10260000B8975FE77EF71DC73CD7D326F236910611 -:10261000B01657667676154634564CD96DC90EF904 -:102620002FE9C899E9898AB9ABA944586548067861 -:102630002768C018E1088238A3287DCB5CDB3FEB1C -:102640001EFBF98BD89BBBAB9ABB754A545A376AB1 -:10265000167AF10AD01AB32A923A2EFD0FED6CDDEC -:102660004DCDAABD8BADE89DC98D267C076C645C01 -:10267000454CA23C832CE01CC10C1FEF3EFF5DCFFC -:102680007CDF9BAFBABFD98FF89F176E367E554E51 -:10269000745E932EB23ED10EF01E7C3C3E5E2B3D0E -:1026A0003F2F5B5D3B2C2A225C0043616E6E6F7492 -:1026B000206F70656E2073756264697220004D65CD -:1026C00064696120496E6974204661696C005344F5 -:1026D0002063617264206F6B0A006F70656E526FC9 -:1026E0006F74206661696C65640A00766F6C756D45 -:1026F000652E696E6974206661696C65640A004EB6 -:102700006F20534420636172640A000A4D32340022 -:102710004D3233202573002E0A006F70656E2066DF -:1027200061696C65642C2046696C653A20004669D5 -:102730006C652073656C65637465640A0020536979 -:102740007A653A200046696C65206F70656E656435 -:102750003A2000454E4420535542524F5554494E5D -:10276000450A002220706F73002220706172656E2E -:10277000743A2200535542524F5554494E45204316 -:10278000414C4C207461726765743A220053756243 -:1027900063616C6C204F766572666C6F770045786C -:1027A000636565646564206D617820535542524FBE -:1027B0005554494E452064657074683A00577269F3 -:1027C00074696E6720746F2066696C653A200043F7 -:1027D0004F4D4D554E49434154494F4E0044525977 -:1027E00052554E004552524F525300494E464F00EB -:1027F0004543484F004572726F7220777269746961 -:102800006E6720746F20454550524F4D210A00538A -:10281000544F505045442E20005072696E746572BA -:102820002073746F707065642064756520746F2008 -:102830006572726F72732E20466978207468652005 -:102840006572726F7220616E6420757365204D39F8 -:10285000393920746F20726573746172742E202868 -:1028600054656D706572617475726520697320724C -:10287000657365742E2053657420697420616674D5 -:1028800065722072657374617274696E67290A00DB -:102890004E6F20436865636B73756D20776974684C -:1028A000206C696E65206E756D6265722C204C61BE -:1028B0007374204C696E653A20004E6F2043686542 -:1028C000636B73756D2077697468206C696E652021 -:1028D0006E756D6265722C204C617374204C696E4C -:1028E000653A2000636865636B73756D206D69736D -:1028F0006D617463682C204C617374204C696E6543 -:102900003A20004C696E65204E756D6265722069D3 -:1029100073206E6F74204C617374204C696E652057 -:102920004E756D6265722B312C204C617374204C96 -:10293000696E653A20004D3131300053657269612E -:102940006C20737461747573206D69736D61746349 -:10295000680A0053442072656164206572726F7268 -:102960000A004B494C4C20627574746F6E2F70696D -:102970006E0A002121204B494C4C20636175736520 -:10298000642062792000746F6F206D756368206920 -:102990006E6163746976652074696D65202D2063AE -:1029A000757272656E7420636F6D6D616E643A202E -:1029B000002121204B494C4C2063617573656420D4 -:1029C00062792000627573793A207061757365646D -:1029D00020666F7220696E7075740A006275737973 -:1029E0003A2070617573656420666F722075736537 -:1029F000720A00627573793A2070726F636573733F -:102A0000696E670A004D656469612052656D6F7675 -:102A10006564004D6564696120496E736572746513 -:102A20006400506C65617365205265736574005075 -:102A300052494E5445522048414C54454400255378 -:102A40003A202553004B494C4C45442E20005072EF -:102A5000696E7465722068616C7465642E206B69A0 -:102A60006C6C28292063616C6C6564210A00006528 -:102A700063686F3A004572726F723A00486F74650E -:102A80006E6420746F6F20636F6C640A005072650F -:102A9000737320627574746F6E20746F2072657327 -:102AA000756D650A00496E736572742066696C61A4 -:102AB0006D656E7420616E64207072657373206240 -:102AC0007574746F6E0A005072657373206275744A -:102AD000746F6E20746F2068656174206E6F7A7AEF -:102AE0006C650A004C4F570048494748004F4B005F -:102AF0004572726F723A20416C6C200020636F6ED9 -:102B00006E656374696F6E2E2E2E2000546573748B -:102B1000696E6720004C4F570048494748004F4BAB -:102B2000004572726F723A20416C6C200020636F16 -:102B30006E6E656374696F6E2E2E2E200054657361 -:102B400074696E6720004C4F570048494748004F52 -:102B50004B004572726F723A20416C6C200020630A -:102B60006F6E6E656374696F6E2E2E2E2000546535 -:102B70007374696E6720004C4F57004849474800FE -:102B80004F4B004572726F723A20416C6C200020EE -:102B9000636F6E6E656374696F6E2E2E2E20005407 -:102BA000657374696E6720004C4F57004849474869 -:102BB000004F4B004572726F723A20416C6C2000DE -:102BC00020636F6E6E656374696F6E2E2E2E20000B -:102BD00054657374696E672000544D4320434F4E13 -:102BE0004E454354494F4E204552524F52002044C7 -:102BF0000020204D32303020540020204D32303023 -:102C0000205300202844697361626C6564293A008E -:102C100046696C616D656E742073657474696E6766 -:102C2000730020204D3230312058004D6178204112 -:102C30006363656C65726174696F6E2028756E6977 -:102C400074732F7332290020204D32303320580006 -:102C50004D617820666565647261746573202875BE -:102C60006E6974732F73290020520020204D32307A -:102C700034205000416363656C65726174696F6EE6 -:102C80002028756E6974732F7332292028503C7088 -:102C900072696E742D616363656C3E20523C72658F -:102CA00074726163742D616363656C3E20543C747F -:102CB000726176656C2D616363656C3E2900204A04 -:102CC0000020540020530020204D32303520420097 -:102CD000416476616E6365642028423C6D696E5F75 -:102CE0007365676D656E745F74696D655F75733E5E -:102CF00020533C6D696E5F66656564726174653E04 -:102D000020543C6D696E5F74726176656C5F6665B8 -:102D10006564726174653E204A3C6A756E635F64E7 -:102D200065763E290020204D32313700546F6F6C9C -:102D30002D6368616E67696E670020204D323138FF -:102D4000205400486F74656E64206F666673657406 -:102D5000730020440020490020204D3330312050A2 -:102D600000486F74656E6420504944004F46460029 -:102D70004F4E0020204D61783A2000200020204D49 -:102D8000696E3A2000203B200020204D3231312056 -:102D90005300536F667420656E6473746F707300B4 -:102DA000203B00205500204C0020204D36303320A1 -:102DB000540046696C616D656E74206C6F61642FA0 -:102DC000756E6C6F616400737072656164437963E2 -:102DD0006C6500737465616C746843686F70002083 -:102DE000647269766572206D6F64653A090073706C -:102DF000726561644379636C6500737465616C74BA -:102E00006843686F700020647269766572206D6F28 -:102E100064653A09007370726561644379636C6537 -:102E200000737465616C746843686F70002064722D -:102E300069766572206D6F64653A0900737072651A -:102E400061644379636C6500737465616C74684395 -:102E5000686F700020647269766572206D6F6465BA -:102E60003A09007370726561644379636C6500733D -:102E70007465616C746843686F7000206472697671 -:102E80006572206D6F64653A0900202E6873747254 -:102E9000743A2000202E68656E643A200020636832 -:102EA0006F70706572202E746F66663A2000202E57 -:102EB00068737472743A2000202E68656E643A203C -:102EC000002063686F70706572202E746F66663ABA -:102ED0002000202E68737472743A2000202E6865DA -:102EE0006E643A20002063686F70706572202E74E3 -:102EF0006F66663A2000202E68737472743A200060 -:102F0000202E68656E643A20002063686F707065DB -:102F100072202E746F66663A2000202E68737472D9 -:102F2000743A2000202E68656E643A2000206368A1 -:102F30006F70706572202E746F66663A20003F5382 -:102F4000206F7574206F662072616E67652028316E -:102F50002E2E38290A003F50206F7574206F66208E -:102F600072616E676520282D332E2E3132290A00BA -:102F70003F4F206F7574206F662072616E67652009 -:102F800028312E2E3135290A003B200020496E764B -:102F9000616C69642065787472756465722000479D -:102FA000322F47332062616420706172616D6574F5 -:102FB0006572730A00536C6565702E2E2E00436C8B -:102FC00069636B20746F20526573756D652E2E2EAC -:102FD000004E6F204D6F76652E00456E6420666949 -:102FE0006C65206C6973740A00426567696E2066BF -:102FF000696C65206C6973740A004E6F206D65649E -:1030000069610A00286E6F2066696C652900437546 -:103010007272656E742066696C653A2000534420B4 -:103020007072696E74696E67206279746520004EF3 -:103030006F74205344207072696E74696E670A0061 -:103040002E0A0044656C6574696F6E206661696C58 -:1030500065642C2046696C653A200046696C6520E1 -:1030600064656C657465643A005072696E742074AE -:10307000696D653A20000A53746174733A20466999 -:103080006C616D656E7420757365643A20002C2048 -:103090004C6F6E67657374206A6F623A2000546FDC -:1030A00074616C2074696D653A20005374617473A7 -:1030B0003A20002C204661696C65643A20002C207F -:1030C00046696E69736865643A20005072696E746F -:1030D000733A200053746174733A20006F6B006F71 -:1030E000666600F027EB27E427DD27CF274445421B -:1030F00055473A004D3131322053687574646F770B -:103100006E004D3131332053004D616B6572626F3B -:1031100074205265706C696361746F72204F46460B -:103120002E002F2F004D31343520533C696E6465DD -:10313000783E206F7574206F662072616E6765201F -:1031400028302D31290A003F4A206F7574206F66A0 -:103150002072616E67652028302E303120746F2018 -:10316000302E33290A0046523A0020466C6F773AD7 -:103170002000496E76616C696420657874727564AC -:1031800065720A0064697300656E0043290A006174 -:10319000626C656420286D696E2074656D70200016 -:1031A000436F6C6420657874727564657320617216 -:1031B0006520004F666673657473204170706C699A -:1031C0006564004572723A20546F6F206661722107 -:1031D00000546F6F206661722066726F6D20726599 -:1031E000666572656E636520706F696E740A00456E -:1031F0004550524F4D204F4B0A002064726976654E -:10320000722063757272656E743A20002064726970 -:103210007665722063757272656E743A2000206460 -:1032200072697665722063757272656E743A2000F9 -:10323000206472697665722063757272656E743A85 -:103240002000206472697665722063757272656E03 -:10325000743A200020204D323036205800486F6DDF -:1032600065206F6666736574004361703A00434F72 -:103270004E4649475F4558504F5254004D454154C2 -:103280005041434B00434F4F4C45525F54454D50C6 -:1032900045524154555245004348414D4245525FC5 -:1032A00054454D50455241545552450042414259B2 -:1032B0005354455050494E470041524353004D4FDF -:1032C00054494F4E5F4D4F44455300544845524D6D -:1032D000414C5F50524F54454354494F4E0045585E -:1032E00054454E4445445F4D323000435553544F8E -:1032F0004D5F4649524D574152455F55504C4F41E5 -:1033000044004C464E5F5752495445004C4F4E477F -:103310005F46494C454E414D45004155544F52453D -:10332000504F52545F53445F5354415455530053CC -:10333000445F575249544500524550454154004D51 -:10334000554C54495F564F4C554D450053444341ED -:1033500052440050524F4D50545F535550504F52AD -:103360005400484F53545F414354494F4E5F434FBD -:103370004D4D414E445300454D455247454E4359EE -:103380005F50415253455200434153455F4C4947BA -:1033900048545F4252494748544E45535300544F96 -:1033A00047474C455F4C494748545300534F465498 -:1033B000574152455F504F574552004255494C4482 -:1033C0005F50455243454E54004C4556454C494E7E -:1033D000475F44415441005A5F50524F42450052AA -:1033E000554E4F5554004155544F4C4556454C0091 -:1033F0005052494E545F4A4F420050524F47524537 -:103400005353004155544F5245504F52545F544509 -:103410004D50004155544F5245504F52545F504FFC -:103420005300564F4C554D45545249430045455065 -:10343000524F4D0042494E4152595F46494C455FFB -:103440005452414E534645520053455249414C5FF8 -:10345000584F4E5F584F4646004649524D574152CD -:10346000455F4E414D453A4D61726C696E20322E7A -:10347000302E392E352028417072203131203230E3 -:1034800032342031373A30343A31392920534F55CC -:103490005243455F434F44455F55524C3A67697408 -:1034A0006875622E636F6D2F4D61726C696E46692F -:1034B000726D776172652F4D61726C696E2050522A -:1034C0004F544F434F4C5F56455253494F4E3A313C -:1034D0002E30204D414348494E455F545950453A9E -:1034E0004D616B6572626F74205265706C696361C7 -:1034F000746F722045585452554445525F434F559E -:103500004E543A3220555549443A636564653261F8 -:1035100032662D343161322D343734382D396231F1 -:10352000322D6335356336326633363766660A00C8 -:1035300020204D3235302043004C434420436F6EF1 -:103540007472617374004D383400446F6E6520707E -:1035500072696E74696E672066696C650A004D3722 -:1035600037004D3331002569730025696D202569C9 -:1035700073002569682025696D2025697300256918 -:1035800064202569682025696D20256973002569F7 -:103590007920256964202569682025696D202569C1 -:1035A0007300436F6F6C696E672E2E2E0045256386 -:1035B0002025530042656420436F6F6C696E672E4F -:1035C0002E2E004265642048656174696E672E2E58 -:1035D0002E00206661696C65642120426164206868 -:1035E00065617465722069640A0050494420417520 -:1035F000746F74756E650023646566696E6520443A -:10360000454641554C545F004B6420004B692000F7 -:103610004B7020002066696E6973686564212050D4 -:10362000757420746865206C617374204B702C2055 -:103630004B6920616E64204B6420636F6E7374610C -:103640006E74732066726F6D2062656C6F7720698F -:103650006E746F20436F6E66696775726174696F0F -:103660006E2E680A00504944204175746F74756E5F -:103670006500206661696C6564212074696D656F01 -:1036800075740A00504944204175746F74756E65F5 -:1036900000206661696C6564212054656D706572F7 -:1036A000617475726520746F6F20686967680A00BD -:1036B000504944204175746F74756E6500504944DB -:1036C000204379636C65730025532025692F256994 -:1036D00000204B643A2000204B693A2000204B70B8 -:1036E0003A200020436C6173736963205049442081 -:1036F0000A002054753A2000204B753A2000206DB6 -:1037000061783A2000206D696E3A200020643A20EA -:103710000020626961733A200048656174696E67D0 -:103720002E2E2E002073746172740A0050494420BA -:103730004175746F74756E6500206661696C6564AF -:10374000212054656D706572617475726520746FA7 -:103750006F20686967680A00504944204175746F9A -:1037600074756E6500504944204175746F74756EB0 -:1037700065004572723A207574663820666F6E7403 -:10378000206E6F7420696E697469616C697A656412 -:103790002E004572723A207574663820666F6E741A -:1037A000206E6F7420696E697469616C697A6564F2 -:1037B0002E00667265736800646F696E670020662C -:1037C000696C653A20004E6F7720002F6175746F29 -:1037D00025632E670000002100240027002A002D09 -:1037E000003000330001010000040107010A01005C -:1037F000000A0B02090C0D0E08070304010000006B -:1038000000000000000000000000000000000000B8 -:103810000000000000000000000000121110000075 -:103820000000000000000000000000000000000098 -:1038300000000000006D61726C696E66772E6F7219 -:103840006700322E302E392E35001FFFFFFFFFFF9D -:10385000FF600000000001FF400000000000FF804A -:1038600000000000007F83CF00000C303F87FF8006 -:10387000000C301F867980000C000F8C30C7838CC1 -:1038800030E78C30CFC7CC31F38C30DCECEC33B983 -:103890008C30D86C6C33198C30D06C0C33198C3064 -:1038A000D86C0C33198C30DC6C0E3B198C30CF7C0F -:1038B000079F198C30C77C038F194000000000005F -:1038C00002600000000000061FFFFFFFFFFFF8700E -:1038D000012C0190012701B0012201C0011D01F05E -:1038E0000118011002130130020E0160020901905B -:1038F000020401C002FF000003FA004003F500804B -:1039000003F000D003EB002004E6007004E100E0C7 -:1039100004DC004005D700C005D2004006CD00D031 -:1039200006C8008007C3003008BE00F008B900C018 -:1039300009B400B00AAF00B00BAA00D00CA500007B -:103940000EA000500F9B00C0109600501291000076 -:10395000148C00C0158700B0178200B0197D00D00C -:103960001B7800001E730040206E0090226900F05A -:1039700024640040275F0090295A00E02B55001076 -:103980002E500020304B0010324600E033410090B2 -:10399000353C001037370070383200A0392D00B0A8 -:1039A0003A2800A03B2300603C1E00103D19009007 -:1039B0003D1400103E0F00703E0A00C03E0500009E -:1039C0003F0000403FFBFF803FF6FFC03FF1FF207C -:1039D00020506C616E6E65724275666665724279E2 -:1039E0007465733A20002046726565204D656D6FE1 -:1039F00072793A200020436F6D70696C65643A20DB -:103A000041707220313120323032340A00204C6152 -:103A1000737420557064617465643A2032303232B8 -:103A20002D30372D3239207C20417574686F723A01 -:103A3000204D2E2042616B65720A004D61726C69E7 -:103A40006E20322E302E392E350A0020536F6674C8 -:103A5000776172652052657365740A00205761743E -:103A60006368646F672052657365740A0020427250 -:103A70006F776E206F75742052657365740A00202D -:103A800045787465726E616C2052657365740A00C6 -:103A9000506F77657255700A0073746172740A0012 -:103AA000473237004D31303031006F6B0065727234 -:103AB0006F722077726974696E6720746F2066690F -:103AC0006C650A00446F6E6520736176696E6720CD -:103AD00066696C652E0A004D323900456E64737458 -:103AE0006F707300255320256320256320256320F4 -:103AF000256300205A3A0020593A0020583A0065C0 -:103B00006E6473746F7073206869743A20000000EB -:103B100020002300260029002C002F003200000185 -:103B20000000030106010901000022002500280011 -:103B30002B002E00310034000201000005010801B5 -:103B40000B01050505050705080808080202020221 -:103B50000A0A080804040404010101010101010129 -:103B60000303030303030303040707070C0C0C0CF4 -:103B70000C0C0C0C020202020606060606060606DD -:103B80000B0B0B0B0B0B0B0B01021020200808106A -:103B900020401020408002010201080402010102BD -:103BA0000408102040808040201008040201800496 -:103BB00002018040201008040201080402010102F1 -:103BC000040810204080010204081020408001FFFA -:103BD000FF496E736572742066696C616D656E7401 -:103BE00020616E6420707265737320627574746FE7 -:103BF0006E0A00220A00556E6B6E6F776E20636F3F -:103C00006D6D616E643A202200204500205A00202C -:103C1000590020204D3932205800537465707320AC -:103C200070657220756E697400486F6D652025732C -:103C3000257325732046697273740020453A00206D -:103C40005A3A0020593A00583A004D616B65726249 -:103C50006F74205265706C696361746F7220526575 -:103C60006164792E005072696E74696E672E2E2E13 -:103C7000005072696E7420506175736564006F6BDB -:103C80000A00526573656E643A20000056017E0199 -:103C900011241FBECFEFD1E2DEBFCDBF00E00CBFCD -:103CA00084B780930F1914BE0FB6F894A89580912D -:103CB0006000886180936000109260000FBE13E086 -:103CC000A0E0B2E0ECE5F4E802E00BBF02C0079030 -:103CD0000D92AA3FB107D9F729E1AAEFB3E001C0DD -:103CE0001D92AF30B207E1F71EE1C7E4DEE100E06C -:103CF00006C021970109802FFE010F945C41C63454 -:103D0000D10780E00807A9F70F943E2A0D941C42C2 -:103D10000C9400000F931F93CF93DF93809147097A -:103D200090E0EC01CC0FDD1FCC0FDD1F8E010A5D92 -:103D30001D4F880F991FFC01EE5DFD4F6081718161 -:103D4000072E000C880B990B0F94B8392AE037ED39 -:103D500043E25CE30F94173ACA54DA4F2881398161 -:103D60004A815B810F94173AF801608371838283E3 -:103D70009383DF91CF911F910F9108950F931F931C -:103D8000CF93DF938091510990E0EC01CC0FDD1FC0 -:103D9000CC0FDD1F8E010A5D1D4F880F991FFC019E -:103DA000EE5DFD4F60817181072E000C880B990B31 -:103DB0000F94B8392AE037ED43E25CE30F94173AE9 -:103DC000CA54DA4F288139814A815B810F94173AAE -:103DD000F8016083718382839383DF91CF911F9178 -:103DE0000F910895CF93DF93EC01CB01BA010F94AB -:103DF000B8392DEC3CEC4CEC5DE30F94023F0F9492 -:103E00007B3F79836883DF91CF910895E0914709E3 -:103E1000E23030F4F0E0EE52FA4F809136098083C0 -:103E20000895809197178823C1F081508093971748 -:103E3000E4EAF4E1882351F08150990B2BE1289FAB -:103E4000F001299FF00D1124E757F94E8BE1A9E805 -:103E5000B4E101900D928A95E1F720919717211115 -:103E600005C08091A21780648093A21781E090E042 -:103E7000A0E0B0E0211103C080E090E0DC0180937D -:103E80003B0990933C09A0933D09B0933E091092E1 -:103E9000A10581E080939F0583E0809375020895DA -:103EA000CF93DF93EC01CB01BA010F94B8390F9493 -:103EB0007B3F6883DF91CF91089581E080934E0925 -:103EC000089582E080934E0908958F929F92AF9259 -:103ED000BF92CF92DF92EF92FF92CF936B017C0162 -:103EE00020E030E0A9010F94B13987FFA3C06DEB4A -:103EF00077E386E095EBA70196010F94083E6B01EE -:103F00007C0120E030E040E251E40F94173A20E0D9 -:103F100030E048EC52E40F94173A4B015C0120E08A -:103F200030E040E251ECC701B6010F94B1391816E8 -:103F300054F420E030E048EC52E4C701B6010F949D -:103F4000684087FD8BC020E030E0A901C701B601C1 -:103F50000F94B13987FF73C060E070E080EA90ECA5 -:103F6000A50194010F94083E20E030E040E251E4C6 -:103F70000F94023F0F94743F6B017C01F7FC64C007 -:103F800020E137E240E050E00F94C63DCA01B9019C -:103F90002AE030E040E050E00F94C63D605D609361 -:103FA000A305C701B60128EE33E040E050E00F94CE -:103FB000C63D9AE0892E912CA12CB12CCA01B901E1 -:103FC000A50194010F94C63D605D6093A405C701EF -:103FD000B60124E630E040E050E00F94C63DCA014F -:103FE000B901A50194010F94C63D605D6093A505DC -:103FF0008EE28093A605C701B601A50194010F9436 -:10400000C63DC62FCA01B901A50194010F94C63D52 -:10401000605D6093A705C05DC093A80583EA95E045 -:10402000CF91FF90EF90DF90CF90BF90AF909F9097 -:104030008F9008956DEB77E386E095E35CCF60E0C9 -:1040400070E080EA90E48CCFF094E094D094C09437 -:10405000C11CD11CE11CF11C6DE2A1CF20E030E0BD -:10406000A901C701B6010F94B13987FF6AC060E0AA -:1040700070E080EA90ECA50194010F94083E20E0E6 -:1040800030E040E251E40F94023F0F94743F4B0143 -:104090005C0120E030E0A901C701B6010F9468403F -:1040A00087FD0BC020E030E040E251E4C701B601DB -:1040B0000F94B13960E287FD13C0B7FC47C0C5015A -:1040C000B40128EE33E040E050E00F94C63DCA0151 -:1040D000B9012AE030E040E050E00F94C63D605D59 -:1040E0006093A405C501B40124E630E040E050E04F -:1040F0000F94C63D8AE0C82ED12CE12CF12CCA01C8 -:10410000B901A70196010F94C63D605D6093A505B6 -:104110008EE28093A605C501B401A70196010F9414 -:10412000C63DC62FCA01B901A70196010F94C63D2D -:10413000605D6093A705C05DC093A80584EA95E023 -:104140006FCF60E070E080EA90E495CFB094A094E7 -:1041500090948094811C911CA11CB11C6DE2C0CF75 -:10416000CF93DF93EC01CB01BA010F94B83929EC5E -:1041700038EC48EC5EE30F94023F20E030E040E092 -:104180005FE30F94083E0F947B3F6883DF91CF91EC -:104190000895CF93DF93EC01CB01BA010F94B839A6 -:1041A000688379838A839B83DF91CF910895CF932E -:1041B000DF93EC01CB01BA010F94B839688379839E -:1041C0008A839B83DF91CF910895E091470986E030 -:1041D000E802F0011124EE50FA4F8091360990E088 -:1041E00095838483089580915109882369F0809193 -:1041F000E4088770873041F482EC9DE09093F308E7 -:104200008093F2081092510908958F929F92AF9275 -:10421000BF92CF92DF92EF92FF92CF936B017C011E -:1042200020E030E0A9010F94B13987FDC3C06DEBE8 -:1042300077E386E095E3A70196010F94083E6B01B2 -:104240007C0120E030E0A9010F94B13987FFB7C0AD -:10425000C701B601905820E030E040E251E40F94ED -:10426000173A20E030E040E251E40F94173A20E0A2 -:1042700030E040EA50E40F94083E20E030E040E2B5 -:1042800051E40F94023F0F94743F6B017C0160E294 -:1042900080EAC81686E8D80681E0E806F1048CF0CA -:1042A000C701B60120EA36E841E050E00F94C63D70 -:1042B000CA01B9012AE030E040E050E00F94C63D69 -:1042C000605D6093A20560E280E1C81687E2D806CF -:1042D000E104F1048CF0C701B60120E137E240E0CF -:1042E00050E00F94C63DCA01B9012AE030E040E039 -:1042F00050E00F94C63D605D6093A30560E288EED8 -:10430000C81683E0D806E104F1048CF0C701B601B9 -:1043100028EE33E040E050E00F94C63DCA01B901F9 -:104320002AE030E040E050E00F94C63D605D6093CD -:10433000A40560E284E6C816D104E104F1048CF01F -:10434000C701B60124E630E040E050E00F94C63DDE -:10435000CA01B9012AE030E040E050E00F94C63DC8 -:10436000605D6093A5058AE0882E912CA12CB12C6C -:10437000C701B601A50194010F94C63DC62FCA011D -:10438000B901A50194010F94C63D605D6093A60537 -:104390008EE28093A705C05DC093A80582EA95E0F0 -:1043A000CF91FF90EF90DF90CF90BF90AF909F9014 -:1043B0008F9008956DEB77E386E095EB3CCF20E09E -:1043C00030E040E251E4C701B60149CF8F929F929D -:1043D000AF92BF92CF92DF92EF92FF92CF936B0199 -:1043E0007C0120E030E0A9010F94B13987FD93C032 -:1043F0006DEB77E386E095E3A70196010F94083E05 -:104400006B017C0120E030E040E251E40F94173A68 -:1044100020E030E04AE754E40F94173A4B015C0186 -:1044200020E030E0A901C701B6010F94B13920E0C6 -:1044300030E040EA50E487FF04C020E030E040EA8A -:1044400050ECC501B4010F94083E20E030E040E29A -:1044500051E40F94023F0F94743F6B017C01C1142F -:10446000D104E104F10409F45BC0F7FE59C0F094F3 -:10447000E094D094C094C11CD11CE11CF11C8DE2CD -:104480008093A305C701B60128EE33E040E050E079 -:104490000F94C63D8AE0882E912CA12CB12CCA0124 -:1044A000B901A50194010F94C63D605D6093A40518 -:1044B0008EE28093A505C701B60124E630E040E016 -:1044C00050E00F94C63DCA01B901A50194010F94B3 -:1044D000C63D605D6093A605C701B601A5019401C4 -:1044E0000F94C63DC62FCA01B901A50194010F94CE -:1044F000C63D605D6093A705C05DC093A80583EAD3 -:1045000095E0CF91FF90EF90DF90CF90BF90AF906C -:104510009F908F9008956DEB77E386E095EB6CCFDD -:1045200080E2AECFCF93DF93EC01CB01BA010F94C1 -:10453000B83920E030E040E251E40F94023F688354 -:1045400079838A839B83DF91CF9108950F94B83943 -:1045500020E030E040E251E40F94023F0C9405214A -:10456000CF93DF93EC01CB01BA010F94B8392AE065 -:1045700037ED43E25DE30F94023F0F947B3F688386 -:1045800079838A839B83DF91CF910895CF93DF93C3 -:10459000EC01CB01BA010F94B8392AE037ED43E2C0 -:1045A0005DE30F94023F688379838A839B83DF9165 -:1045B000CF910895CF93DF93EC01CB01BA010F9413 -:1045C000B839688379838A839B83DF91CF9108957B -:1045D000CF93DF93EC01CB01BA010F94B83920E0FF -:1045E00030E048EC52E40F94023F688379838A8379 -:1045F0009B83DF91CF9108950F94B83920E030E08C -:1046000048EC52E40F94023F0C94651FCF93DF9364 -:10461000EC01CB01BA010F94B8390F94743F798340 -:104620006883DF91CF910895CF93DF93EC01CB01A5 -:10463000BA010F94B83920E030E04AE754E40F940F -:10464000023F688379838A839B83DF91CF910895AA -:104650000F94B83920E030E04AE754E40F94023F69 -:104660000C94E621282F8FEF80931B0210924509AE -:1046700080913B0990913C09A0913D09B0913E0980 -:10468000B7FF08C010923B0910923C0910923D09F7 -:1046900010923E0980919705882331F080913B0963 -:1046A0008093A00510929F0580919E051816FCF43A -:1046B000082E000C990B821B91092091A005022E57 -:1046C000000C330B2817390794F097FF02C090E0D5 -:1046D00080E08093A005092E000CAA0BBB0B8093F1 -:1046E0003B0990933C09A0933D09B0933E0980910A -:1046F000A0056623A9F09091A105891714F4809371 -:10470000A1052091A105022E000C330B2C5F3F4F19 -:10471000482F082E000C550B241735071CF4845025 -:104720008093A10508950F931F93522F2091431654 -:10473000309144162817390741F1109201049093E3 -:104740004416809343168B0130E020E000933B0930 -:1047500010933C0920933D0930933E094093A105F5 -:1047600050939E058D5C944621F41092400910925E -:104770008F0582E08093750281E080939F051092FF -:10478000940580931B0210923A091F910F9108958E -:1047900020E040E070E060E08FE095E30C9493232C -:1047A000CF93C1E0C0934009FC0180819181A28137 -:1047B000B38180931C0290931D02A0931E02B093BC -:1047C0001F0220E040E070E060E080919C05909145 -:1047D0009D050E949323C0930104CF910895CF9328 -:1047E000DF9300D01F92CDB7DEB78DEC9CECACEC24 -:1047F000BCE389839A83AB83BC83CE0101960E947C -:10480000D0230F900F900F900F90DF91CF910895CC -:10481000CF93DF9300D01F92CDB7DEB78DEC9CEC29 -:10482000ACECBDE389839A83AB83BC83CE01019654 -:104830000E94D0230F900F900F900F90DF91CF9197 -:104840000895CF93DF9300D01F92CDB7DEB780E0FD -:1048500090E0A0E8BFE389839A83AB83BC83CE0159 -:1048600001960E94D0230F900F900F900F90DF9130 -:10487000CF910895CF93DF9300D01F92CDB7DEB7CD -:1048800080E090E0A0E2B1E489839A83AB83BC83AB -:10489000CE0101960E94D0230F900F900F900F90A1 -:1048A000DF91CF910895E0918F05E63028F581E002 -:1048B0008E0F80938F0540913B0950913C09609188 -:1048C0003D0970913E092091A10590919E0580912E -:1048D000400939E0E39FF0011124E65BFA4FA09113 -:1048E0004316B0914416B183A083428353836483FB -:1048F00075832683978380870895CF93DF93EC0198 -:104900000E94532420E040E070E060E0CE01DF919F -:10491000CF910C949323FC01A081B1811C92A281C0 -:10492000B3818C918F5F8C930280F381E02D908115 -:104930008CE0989F800D1124E5E4F6E113AE84AF7E -:104940000895FC0184910895FC01808108950097E9 -:1049500051F0FC0180E09191992331F0907C9038E6 -:10496000D1F38F5FF8CF80E0089590E080E0089564 -:10497000CF92DF92EF92FF92CF93C82F833011F442 -:1049800060932F050F941E1D6B017C0124EA30E714 -:104990004DE75FE360911C0270911D0280911E0241 -:1049A00090911F020F94B13987FD18C08AEF90E0F3 -:1049B000A0E0B0E08C0D9D1DAE1DBF1D80933005A5 -:1049C00090933105A0933205B0933305C093100244 -:1049D000CF91FF90EF90DF90CF90089580E090E02E -:1049E000DC01E8CFCF92DF92EF92FF920F931F93FB -:1049F0000F941E1D009106051091070520910805D2 -:104A0000309109056B017C01C01AD10AE20AF30A50 -:104A10009701860137FD11C020910505209520934F -:104A200005056A547C4F8F4F9F4F60930605709326 -:104A30000705809308059093090581E0909105058D -:104A4000911101C080E01F910F91FF90EF90DF90D6 -:104A5000CF900895CF92DF92EF92FF920F94B839E2 -:104A60006B017C0120E030E0A9010F94B1392DEBFE -:104A700037E346E055E387FF04C02DEB37E346E01C -:104A800055EBC701B6010F94083E6B017C0120E095 -:104A900030E0A9010F94B13920E030E040E05FE35D -:104AA00087FF04C020E030E040E05FEBC701B601C3 -:104AB0000F94083E0F94743FCB01FF90EF90DF906E -:104AC000CF900C9492BD0F94B8390F94743FCB01E2 -:104AD0000C9492BD0F94B83929EC38EC48EC5EE3A5 -:104AE0000F94023F20E030E040E05FE30F94083E87 -:104AF0000F947B3F862F0C942ABECF93DF93CDB7C4 -:104B0000DEB720E2488559856F818E810F941E158E -:104B1000DF91CF910895809147090C949ACC0F941E -:104B2000B8392DEC3CEC4CEC5DE30F94023F0F9454 -:104B30007B3FCB010C94C7BDAF92BF92CF92DF9267 -:104B4000EF92FF920F931F93CF93DF9361E081E089 -:104B50000E943223C091A10505E00C0FD1E086E24E -:104B6000E82E8AE0F82E12E01C1B9FE2C92E9AE084 -:104B7000D92EBD2EBC1AAC2EA194C1112EC0DD239E -:104B8000D9F08091A0051816BCF040913B095091D6 -:104B90003C0960913D0970913E094F5F5F4F6F4F37 -:104BA0007F4F40933B0950933C0960933D097093BC -:104BB0003E098F5F8093A00580917502882331F0B4 -:104BC00041E06AE37AE08A2D0F949314CF5F0C13CF -:104BD000D4CF83E080939E051FC0C13041F59091F2 -:104BE000A005913069F0809175028823C9F11F9268 -:104BF000DF92CF92BF9281E0913051F180E028C0E6 -:104C000080913F0910923F09882369F3C0934E09B0 -:104C100080919F05882339F3DF91CF911F910F91E8 -:104C2000FF90EF90DF90CF90BF90AF900895C2308B -:104C300069F69091A0059230A9F0809175028823C1 -:104C400079F01F92FF92EF921F9381E09230B1F6BC -:104C50008F930E947D250F900F900F900F900F90D3 -:104C6000D0E0B4CF80913F0910923F09882329F307 -:104C7000C0934E0980919F058823F9F2CDCF809192 -:104C80007502882341F0609190057091910541E093 -:104C900081E00D94931408950D9421120D9419122E -:104CA0000D9411120D9409120D9401126091F814D3 -:104CB0007091F9148FEB94E10D940F2160913415EC -:104CC000709135158BEF94E10D940F216091701563 -:104CD0007091711587E395E10D940F216091AC15EA -:104CE0007091AD1583E795E10D940F216091E81562 -:104CF0007091E9158FEA95E10D940F2160914709B4 -:104D000080913609909137090C94DCCC809151093F -:104D10000E940CCD882341F020E040E070E060E08C -:104D200086E996E20C9493230C94C823EF92FF92A9 -:104D30000F931F938BE4E82E8DE0F82E10E000E037 -:104D40002DE43DE048EC53E26DE57DE082E69DE038 -:104D50000F941D241F910F91FF90EF900895EF92F3 -:104D6000FF920F931F938FE3E82E8CE0F82E10E054 -:104D700000E020EC3CE04DE45EE361E47CE086E4AE -:104D80009CE00F941D241F910F91FF90EF900895C8 -:104D9000EF92FF920F931F938EE4E82E88E0F82E97 -:104DA00010E000E021E638E043E55EE260E578E00F -:104DB00087E598E00F941D241F910F91FF90EF90CD -:104DC0000895CF92DF92EF92FF920F931F93CF93AC -:104DD000DF93CDB7DEB7CDB6DEB68091FC1169E7C3 -:104DE0007FE0882311F06CEF71E1FB01019000205E -:104DF000E9F7CF01861B970B01962DB73EB7281B0D -:104E0000390B0FB6F8943EBF0FBE2DBF0DB71EB7BE -:104E10000F5F1F4F80E2EDB7FEB78183C801019697 -:104E20000F94ED4183EEE82E8CE0F82E25EE3CE069 -:104E300041E05EE261EF7CE088EF9CE00F941D248E -:104E40000FB6F894DEBE0FBECDBEDF91CF911F919D -:104E50000F91FF90EF90DF90CF9008950F948E10F8 -:104E600010924F09109274020E9473CD882351F062 -:104E70008091A21782FD06C082E697E09093F30826 -:104E80008093F2080C94A6BB0F94B8390F947B3F23 -:104E9000862F0C9408BECF93DF9300D0CDB7DEB73A -:104EA0008FEF89838A838B83CE0101960E94F6CA95 -:104EB0000F900F900F90DF91CF910895CF93DF93D4 -:104EC00000D0CDB7DEB78FEF89831A821B82CE0167 -:104ED00001960E94F6CA0F900F900F90DF91CF912C -:104EE0000895CF93DF9300D0CDB7DEB78FEF8983DE -:104EF00089E18A831B82CE0101960E94F6CA0F9037 -:104F00000F900F90DF91CF910895CF93DF9300D052 -:104F1000CDB7DEB78FEF89838BE48A831B82CE0106 -:104F200001960E94F6CA0F900F900F90DF91CF91DB -:104F30000895CF93DF9300D0CDB7DEB719821A82E0 -:104F40008FEF8B83CE0101960E94F6CA0F900F90CF -:104F50000F90DF91CF910895CF93DF9300D0CDB71D -:104F6000DEB719828FEF8A838B83CE0101960E9470 -:104F7000F6CA0F900F900F90DF91CF910895CF93C5 -:104F8000DF9300D0CDB7DEB78FEF89831A828B8392 -:104F9000CE0101960E94F6CA0F900F900F90DF91FC -:104FA000CF910895CF93DF9300D01F92CDB7DEB796 -:104FB0000F947B3F0F94B63969837A838B839C83EC -:104FC000CE0101960E9414BC0F900F900F900F908D -:104FD000DF91CF9108950F94B8392AE037ED43E27D -:104FE0005DE30F94023F0C94D227CF92DF92EF92B1 -:104FF000FF92CF93DF9300D01F92CDB7DEB76B0146 -:105000007C0120E030E0A9010F94B13987FD1BC07D -:105010006DEB77E386E095E3A70196010F94083ED8 -:1050200069837A838B839C83CE0101960E9414BC92 -:105030000F900F900F900F90DF91CF91FF90EF9016 -:10504000DF90CF9008956DEB77E386E095EBE4CFAA -:105050000F94B8392AE037ED43E25DE30F94023F45 -:105060000C94F5270F94B8390C94F527CF92DF9262 -:10507000EF92FF926B017C0120E030E0A9010F94D8 -:10508000B13987FD26C06DEB77E386E095E3A70194 -:1050900096010F94083E6B017C0120E030E0A901ED -:1050A0000F94B13920E030E040E05FE387FF04C0B7 -:1050B00020E030E040E05FEBC701B6010F94083E0E -:1050C0000F94743FCB01FF90EF90DF90CF900C9442 -:1050D00013BD6DEB77E386E095EBD9CF0F94B8392C -:1050E0000C9436280C945B8F0C945B8F0C940D8F72 -:1050F0000C940D8F0C940D8F0C940D8FEF92FF92EA -:105100000F931F93CF93DF93EC018B017A018A8574 -:105110009B858617970731F0888199810F9419250F -:105120001B870A87B701888199810F948B152E817F -:105130003F81820F932F911D9F838E8390E080E0AB -:10514000DF91CF911F910F91FF90EF9008959F9263 -:10515000AF92BF92CF92DF92EF92FF920F931F9385 -:10516000CF93DF93EC018B01942EA52E8A859B852E -:105170008617970731F0888199810F9419251B872D -:105180000A8788859985019649F5BC800A818E81B8 -:10519000080FC880D980D6015596ED91FC91C601C3 -:1051A0001995B80EE92CFA2C10E0F70121917F0136 -:1051B000211127C08E819F81810F911D9F838E8336 -:1051C00090E080E0DF91CF911F910F91FF90EF90E1 -:1051D000DF90CF90BF90AF909F9008950E811F8178 -:1051E000692D7A2D888199810F948B15800F912FCD -:1051F000911D288539852817390738F681E090E018 -:10520000E1CF4B2D602FC6010F947125080F180FA9 -:10521000CCCFDF92EF92FF920F931F93CF93DF9348 -:10522000EC01D62E1CAD0BAD7C0184E0E80EF11C28 -:10523000E98DFA8DC7011995412F480F2D2D602F4B -:10524000C7010F9471259BAD890F8BAF81E090E072 -:10525000DF91CF911F910F91FF90EF90DF90089514 -:10526000AF92BF92DF92EF92FF920F931F93CF9373 -:10527000DF938C01EB01D42E79018FE0481709F4FC -:1052800088C0A5E14A17C1F1BAE04B130EC0EC810A -:10529000FD8130E020E042E061E0C801199542E282 -:1052A00056E0BE01C8010F941C260A80DB81C02D88 -:1052B000F2E3DF1609F4E4C0FD1508F493C085E1BC -:1052C000D81609F4E2C0A7E1DA1609F4FCC0B4E18B -:1052D000DB127DC0EE81FF818D8190E0880F991FE8 -:1052E0008E0F9F1F11928E179F07E1F71A828881F8 -:1052F00081508B831C826BC0AA80BB804DE056E03E -:10530000C8010F941C26F5014481440F406BBE0177 -:10531000C8010F94042641E0BE01C8010F940C2679 -:10532000D50116962D913C911797EC81FD8115962C -:105330004C9166E0C801199540E0BE01C8010F9488 -:1053400014264DE056E0BE01C8010F941C26F5015D -:105350004481440F4F5F406BBE01C8010F94042687 -:1053600041E0BE01C8010F940C26D50115964C9161 -:10537000159716962D913C91240F311DEC81FD81DE -:1053800066E0C801199540E0BE01C8010F941426DB -:105390008CCF41E0C8010F94142640E0BE01C80143 -:1053A0000F940C2641E8BE01C8010F940426F701B2 -:1053B000408150E05595479555954795BE01C801E8 -:1053C0000F94042640E0BE01C8010F94142681E02A -:1053D000DF91CF911F910F91FF90EF90DF90BF90E1 -:1053E000AF900895E6E4DE1609F47CC0F7E4DF161A -:1053F00009F47CC08BE3D812EACFD70111969C91B7 -:10540000119713968C9138E0390F813031F0833049 -:1054100011F0392F02C0392F985021E04B814917E4 -:1054200008F420E041E0391708F040E091E05A81AB -:10543000351708F490E0322F342B932311F42423F2 -:1054400031F2F701128100E0D12C843048F490E071 -:10545000FC01EC55FD4FD08080569D4FDC010C9136 -:1054600017FF04C0B701CE010F941222F70180810B -:105470008D0D80838181800F8183110F89F7A7CFE4 -:10548000B701CE010F941222A2CF88819A81980F82 -:105490009A832981921770F59C819F5F9C839B81E1 -:1054A000890F821710F08FEF820F8B83EE81FF81BF -:1054B0008D8190E0880F991F8E0F9F1F11928E177C -:1054C0009F07E1F784CFD7011C928A8111968C93B4 -:1054D00011978D81815012968C9312978B81139620 -:1054E0008C9375CF8D81F701808371CF8981D7012E -:1054F0008C936DCF80E06CCF8F929F92AF92BF92D2 -:10550000CF92DF92EF92FF920F931F93CF93DF938F -:10551000CDB7DEB760970FB6F894DEBF0FBECDBF34 -:105520008B0140E050E068EC72E449875A876B8752 -:105530007C8740E050E060EA70E44D875E876F87CB -:10554000788B8130B9F1823009F462C020E030E01C -:1055500040E050E460917E0270917F028091800271 -:10556000909181020F94083E4B017C0120E030E0D5 -:1055700046E153E40F946840181634F4812C912CC2 -:1055800086E1E82E93E4F92EF801A084B184C28468 -:10559000D3849401A701B501C6010F946840181681 -:1055A00014F054016701C501D60189839A83AB8346 -:1055B000BC8351C0BE01635F7F4FC80108960E9443 -:1055C000C4B488E0F801DE01119601900D928A952D -:1055D000E1F7AE01475F5F4FBE016B5F7F4FCE01CA -:1055E00001960E94A2B40E94BBB860960FB6F894D0 -:1055F000DEBF0FBECDBFDF91CF911F910F91FF9006 -:10560000EF90DF90CF90BF90AF909F908F900895D4 -:10561000F801208531854285538560917E02709125 -:105620007F0280918002909181020F94083E6B016D -:105630007C0120E030E046E153E40F94B13987FD6E -:1056400006C0C12CD12C26E1E22E23E4F22EC98221 -:10565000DA82EB82FC82BE01635F7F4FCE0101964E -:10566000AECF0F931F930F941E1D0091CB08109186 -:10567000CC082091CD083091CE08011511052105E7 -:105680003105D9F5209131162223A1F1E0912F1691 -:1056900021502093311621E02E0F20932F163091A8 -:1056A0003216231302C010922F1624E0E29FF0015D -:1056B0001124ED5CF94E0081118122813381009328 -:1056C000C7081093C8082093C9083093CA08600F10 -:1056D000711F811D911D6093CB087093CC0880933E -:1056E000CD089093CE088091C9089091CA08892B63 -:1056F00009F0409A1F910F910895601B710B820B66 -:10570000930B97FDF7CF40981092CB081092CC08DE -:105710001092CD081092CE08EDCF0F931F93CF9328 -:10572000DF938C01EB019091311620913216921388 -:1057300005C00E94312B0E94A591F5CF80913016B3 -:1057400034E0839FF0011124ED5CF94E1183008356 -:10575000D383C2839F5F909331168F5F281739F0F0 -:1057600080933016DF91CF911F910F910895109281 -:105770003016F8CF63E972E084E690E00E948D2B4A -:1057800070E060E08AE090E00E948D2B6AEB72E0AE -:1057900084E690E00C948D2B0E947CB90C94BA2B7B -:1057A00081110C94BA2B68E270E080E991E00C94CE -:1057B0008D2B0E94648B0C94D02B0E940FC50C94EF -:1057C000D02B4FE350E0BC0184EF98E00D940242EF -:1057D0000F931F93CF93DF93CDB7DEB72C970FB600 -:1057E000F894DEBF0FBECDBF80914709282F082E49 -:1057F000000C330B3F938F9385E99BE09F938F932E -:105800008E010F5F1F4F1F930F930F944839C801EC -:105810000E94E12B0F900F900F900F900F900F9020 -:105820002C960FB6F894DEBF0FBECDBFDF91CF919F -:105830001F910F9108950C94E82B0F931F93CF9312 -:10584000DF93CDB7DEB72C970FB6F894DEBF0FBE4F -:10585000CDBF80914709282F082E000C330B3F93B2 -:105860008F938CE89BE09F938F938E010F5F1F4F68 -:105870001F930F930F944839C8010E94E12B0F909A -:105880000F900F900F900F900F902C960FB6F894EA -:10589000DEBF0FBECDBFDF91CF911F910F91089555 -:1058A0000C941D2C0F931F93CF93DF93CDB7DEB7CE -:1058B0002F970FB6F894DEBF0FBECDBF809147097A -:1058C000282F082E000C330B3F938F9380E89BE02A -:1058D0009F938F938E010F5F1F4F1F930F930F9412 -:1058E0004839C8010E94E12B0F900F900F900F9044 -:1058F0000F900F902F960FB6F894DEBF0FBECDBF5E -:10590000DF91CF911F910F9108950C94522CEF923B -:10591000FF920F931F93CF93DF9300D000D000D05E -:105920001F921F92CDB7DEB77C0120919205422FC6 -:10593000022E000C550B80919305833089F1843041 -:1059400041F185E999E05F932F939F938F938E01A7 -:105950000F5F1F4F1F930F930F944839609192056B -:10596000C7010E94DCCCC8010E94E12B0F900F9070 -:105970000F900F900F900F902B960FB6F894DEBFFC -:105980000FBECDBFDF91CF911F910F91FF90EF9090 -:10599000089581EA99E027FDD6CF8CE899E0D3CF2E -:1059A0008AEA99E0D0CFE091470986E0E802F00169 -:1059B0001124EE50FA4F808191810C94872CE09154 -:1059C000470987E1E89FF0011124E15CF94F8085E8 -:1059D00091850C94872C2F923F924F925F926F92F9 -:1059E0007F928F929F92AF92BF92CF92DF92EF926F -:1059F000FF920F931F93CF93DF9300D000D0CDB7CA -:105A0000DEB71C017A8369832B833C834D835E83DD -:105A10002701380181E080939F050E94532483E091 -:105A20008093750230928E0520928D0589819A812E -:105A300090938C0580938B058B819C81AD81BE8179 -:105A40008093870590938805A0938905B0938A0574 -:105A50004092830550928405609285057092860578 -:105A6000F12CE12CC0923B09D0923C09E0923D0917 -:105A7000F0923E09B0924416A0924316909282058D -:105A8000809281058C8D8093800526960FB6F894C0 -:105A9000DEBF0FBECDBFDF91CF911F910F91FF9061 -:105AA000EF90DF90CF90BF90AF909F908F907F90BE -:105AB0006F905F904F903F902F90089520E040E0CE -:105AC00070E060E08DEC94E60C9493230E9497CDF7 -:105AD0000E94B4850C945E2DCF93DF93782FC62F50 -:105AE000D42F67FD36C086E06802F0011124EE5025 -:105AF000FA4F408151811416150684F4E72FF0E027 -:105B0000EE0FFF1FE054FD4F808191810F974817E2 -:105B100059070CF4CA01672F0E94DCCCD7FF1BC0C9 -:105B2000E0915109E23008F0E0E0F0E0EE52FA4F87 -:105B300086E0C802D0011124AE50BA4F14968D9160 -:105B40009C918F3F910519F010F08FEF90E08083CA -:105B50001AC047FD18C086E0D802F0011124EE50AB -:105B6000FA4F82819381181619065CF484369105E8 -:105B700014F084E690E090933706809336060E94F6 -:105B800022C6C7FFCDCFDF91CF910C945E2D0F932E -:105B90001F93CF93DF93C6E3D9E0E88186E0E80264 -:105BA000F0011124EE50FA4F0081118160E0C8012C -:105BB0000E94DCCC61E0C8010E94DCCC48816FEF20 -:105BC00080E0DF91CF911F910F910C946C2D0C947C -:105BD000C72D60913609462F809147090C946C2D92 -:105BE0000C94E92D4FEF60913609809147090C9490 -:105BF0006C2D0C94F22D409136096FEF80E00C94DF -:105C00006C2D89E79FE00E949B790E945E2D0D9488 -:105C10008E10611160931A02409300048C3008F0DA -:105C20003AC0E82F880FFF0B8827E65EF14D8F4FB3 -:105C30000D945C414D2E262E312E502E342E372EB3 -:105C40003A2E462E3D2E4B2E402E432E8CE094E4D1 -:105C500021E02093400920E040E070E060E00C94F7 -:105C6000932384E194E4F4CF88E194E4F1CF8CE1D0 -:105C700094E4EECF80E294E4EBCF84E294E4E8CFC6 -:105C800088E294E4E5CF8CE294E4E2CF10924E09EE -:105C90008CE995E2DDCF0C945E2D88E094E4D8CFBA -:105CA00080E194E4D5CFCF930E947CB90E94648BAD -:105CB000C82F882319F080E00E942E8A8C2F0E9422 -:105CC000D02BCF910C945E2D8CE598E09093F30847 -:105CD0008093F2080C945E2DCF93DF93C0918F05D3 -:105CE000CC23B9F0C150C0938F0589E0C89FE00173 -:105CF0001124C65BDA4F6A817B812F814E818881B6 -:105D000099810E949323888580934009DF91CF91E8 -:105D10000895DF91CF910C945E2DEF92FF920F9337 -:105D20001F93CF93DF9361E081E00E943223C09103 -:105D3000A10585E0F82EFC0ED2E0DC1B11E01C1B57 -:105D4000EC2EE194C1112BC00091A0050023A1F01D -:105D500080917502882349F081E0011180E024E000 -:105D60004AEA5EE06E2D0F941E15CF5FFC12EACF5B -:105D700083E080939E050CC080913F0910923F09FB -:105D8000882331F30E946C2E80919F05882301F3B4 -:105D9000DF91CF911F910F91FF90EF900895C13047 -:105DA00001F50091A005013069F08091750288230A -:105DB000E1F281E0013009F080E023E04BE95EE0B0 -:105DC000612FD1CF80913F0910923F09882369F359 -:105DD00084E49BE40E947D2480919F05882329F31D -:105DE000D7CFC23011F60091A005023071F080913A -:105DF0007502882309F4B9CF81E0023009F080E010 -:105E000023E04DE85EE06D2FAECF80913F09109208 -:105E10003F09882361F382E99CE40E947D248091FC -:105E20009F05882321F3B4CF2F923F924F925F9228 -:105E30006F927F928F929F92AF92BF92CF92DF929A -:105E4000EF92FF920F931F93CF93DF9300D01F9297 -:105E5000CDB7DEB70091360961E081E00E943223C0 -:105E60002091A1052B8310E0000F111F075E114F39 -:105E7000422E2B5F2983842D81958A8341E0E42E75 -:105E80004EE0F42E51EFC52E5DE0D52E63EEA62E2A -:105E90006DE0B62E85E0582E541875ED872E7DE006 -:105EA000972E2B81211114C08091A0058C8388230B -:105EB00009F4E3C080917502882351F081E09C8150 -:105EC000911180E024E04DE05EE06A810F941E15A0 -:105ED000612C21E02C833B8034188B819C818913B9 -:105EE0002DC0E0913609F0E0EE0FFF1FE75EF14FA5 -:105EF000859194916092470990934B0980934A0948 -:105F000010924909109248097090A0052B817216D1 -:105F100009F4D8C080917502882381F01F92FF9206 -:105F2000EF923F9281E09C81791280E08F930E94F2 -:105F30007D250F900F900F900F900F907C80872DF4 -:105F40008F5F2B8182132CC0E0913609F0E0EE0FB9 -:105F5000FF1FE75EF14F85919491609247099093FE -:105F60004B0980934A0910924909109248092090E0 -:105F7000A005221609F4B5C080917502882381F02E -:105F80001F92DF92CF923F9281E09B81291280E0A5 -:105F90008F930E947D250F900F900F900F900F9080 -:105FA00063942C812E5F2C83253009F096CF8B8152 -:105FB000853041F5F80185919491109247099093AD -:105FC0004B0980934A09109249091092480990910F -:105FD000A0059C83953009F493C0809175028823B5 -:105FE00089F01F92BF92AF925F9281E02C812530A1 -:105FF00009F080E08F930E947D250F900F900F9005 -:106000000F900F9083E0870D9B8189132BC0F801BF -:10601000859194911092470990934B0980934A0976 -:1060200010924909109248092091A0052C838B8178 -:10603000281709F474C080917502882399F01F9283 -:106040009F928F928B8184198F9381E09C812B8109 -:10605000921380E08F930E947D250F900F900F90F8 -:106060000F900F908B818F5F8B839981891319CF4C -:1060700084E0870D80939E050EC080913F091092A9 -:106080003F09882309F416CF0E946C2E80919F054A -:10609000882309F40FCF0F900F900F900F90DF918E -:1060A000CF911F910F91FF90EF90DF90CF90BF9015 -:1060B000AF909F908F907F906F905F904F903F90A8 -:1060C0002F90089580913F0910923F09882309F489 -:1060D00021CF0E94E92D80919F05882309F41ACFD2 -:1060E000DACF80913F0910923F09882309F444CF09 -:1060F0000E94F22D80919F05882309F43DCFCBCFDC -:1061000080913F0910923F09882309F466CF0E94CD -:10611000C72D80919F05882309F45FCFBCCF809164 -:106120003F0910923F09882309F485CF4091360931 -:106130006FEF80E00E946C2D80919F05882309F409 -:106140007ACFA9CF6F927F928F929F92AF92BF9298 -:10615000CF92DF92EF92FF920F931F93CF93DF9333 -:1061600061E081E00E943223C091A1059C2E85E070 -:10617000C82ECC0E9EE9A92E9DE0B92ED6E0DC1BE0 -:10618000EE24E39422E0D22E15E01C1B04E00C1B4D -:1061900083E0F82EFC1A8D2C8C1A7E2C7C1AC111EF -:1061A00034C06090A0056620A9F080917502882314 -:1061B00051F0692D619581E0611080E024E040EDAF -:1061C0005DE00F941E15CF5FCC11E9CF87E080937F -:1061D0009E050CC080913F0910923F09882329F346 -:1061E0000E946C2E80919F058823F9F2DF91CF9158 -:1061F0001F910F91FF90EF90DF90CF90BF90AF90E5 -:106200009F908F907F906F900895C13001F56090BE -:10621000A00581E0681661F080917502882399F2EB -:1062200081E0681280E023E046EC5DE0672DC9CF95 -:1062300080913F0910923F09882371F381E092E336 -:106240000E947D2480919F05882331F3CFCFC230F7 -:1062500009F0B9C09091A005923071F0809175025B -:10626000882309F4B0CF81E0923009F080E020E289 -:1062700048EB5DE0682DA5CF80913F0910923F0962 -:10628000882361F322EC3DE03093F3082093F20879 -:1062900080919F05882311F3A9CF1092470910928E -:1062A0004B0910924A09109249091092480990919D -:1062B000A005933071F080917502882309F483CF93 -:1062C00081E0933009F080E020E24CEA5DE06F2D40 -:1062D00078CF80913F0910923F09882361F323EB27 -:1062E0003DE03093F3082093F20880919F058823C6 -:1062F00011F37CCFE092470910924B0910924A09A2 -:1063000010924909109248099091A005943071F0BB -:1063100080917502882309F456CF81E0943009F00A -:1063200080E020E24CEA5DE0602F4BCF80913F0996 -:1063300010923F09882361F327EA3DE03093F30888 -:106340002093F20880919F05882311F34FCFD092BC -:10635000470910924B0910924A091092490910926C -:1063600048099091A005953071F0809175028823BD -:1063700009F429CF81E0953009F080E020E24CEA71 -:106380005DE0612F1ECF80913F0910923F09882365 -:1063900061F322EA3DE03093F3082093F208809104 -:1063A0009F05882311F322CF80913F0910923F0966 -:1063B0008823C9F0B092F308A092F20880919F055B -:1063C000882389F013CFC33009F467CFC43009F4B0 -:1063D00091CFC53009F4BBCFC63009F0F4CE90910F -:1063E000A005963009F380917502882309F4EBCE5D -:1063F00081E0963009F080E020E24DE85DE06D2F0D -:10640000E0CE8F929F92AF92BF92CF92DF92EF92A7 -:10641000FF920F931F93CF93DF9361E081E00E947F -:106420003223C091A10585E0B82EBC0ED1E016E064 -:106430001C1B05E00C1B84E0F82EFC1A92E0D92E00 -:1064400083E0E82EEC1AAD2CAC1A9D2E9C1A8C2EF3 -:106450008194C11131C0C090A005CC20A1F08091E1 -:106460007502882349F081E0C11080E024E046E80D -:106470005DE0682D0F941E15CF5FCB11EACF87E04A -:1064800080939E050CC080913F0910923F0988239C -:1064900031F30E946C2E80919F05882301F3DF91D8 -:1064A000CF911F910F91FF90EF90DF90CF90BF9011 -:1064B000AF909F908F900895C13051F51092470989 -:1064C00010924B0910924A091092490910924809FA -:1064D000C090A00581E0C81661F080917502882304 -:1064E00059F281E0C81280E023E04FE75DE0692DBA -:1064F000C1CF80913F0910923F09882371F388E052 -:1065000095E30E947D2480919F05882331F3C7CFB6 -:10651000C23009F0B5C0D093470910924B091092D0 -:106520004A091092490910924809C090A00592E0CA -:10653000C91671F080917502882309F49DCF81E01E -:1065400092E0C91280E023E04FE75DE06A2D92CF30 -:1065500080913F0910923F09882361F381E095E320 -:106560000E947D2480919F05882321F398CFD092AB -:10657000470910924B0910924A091092490910924A -:106580004809C090A00583E0C81671F0809175029B -:10659000882309F471CF81E093E0C91280E023E001 -:1065A0004FE75DE06E2D66CF80913F0910923F0965 -:1065B000882361F38AEF94E30E947D2480919F05F4 -:1065C000882321F36CCFC090A00584E0C81671F039 -:1065D00080917502882309F44FCF81E094E0C912BD -:1065E00080E023E041E75DE06F2D44CF80913F09DB -:1065F00010923F09882361F386E896E20E947D2489 -:1066000080919F05882321F34ACF10924709109269 -:106610004B0910924A091092490910924809C090FA -:10662000A00585E0C81671F080917502882309F4F1 -:1066300023CF81E095E0C91280E023E04AE65DE0E7 -:10664000602F18CF80913F0910923F09882361F392 -:1066500084EF94E30E947D2480919F05882321F399 -:106660001ECF80913F0910923F09882321F18EEEC1 -:1066700094E30E947D2480919F058823E1F00FCF51 -:10668000C33009F474CFC43009F49DCFC53009F488 -:10669000BCCFC63009F0F0CED093470910924B0919 -:1066A00010924A091092490910924809C090A00519 -:1066B00086E0C816B1F280917502882309F4DCCE19 -:1066C00081E096E0C91280E023E04AE65DE0612FB8 -:1066D000D1CE7F928F929F92AF92BF92CF92DF9254 -:1066E000EF92FF920F931F93CF93DF93F82E842E98 -:1066F00070939D0560939C0561E081E00E943223C8 -:10670000C091A10585E0982E9C0ED1E007E21DE026 -:1067100085E0E82EEC1A84E0D82EDC1A83E0C82E3F -:10672000CC1A82E0B82EBC1A7D2E7C1AAC2EA19415 -:1067300083E0F81609F44EC0C11196C0F0924709E3 -:1067400010924B0910924A09109249091092480977 -:10675000DD23D9F08091A0051816BCF040913B09CB -:1067600050913C0960913D0970913E094F5F5F4F28 -:106770006F4F7F4F40933B0950933C0960933D0915 -:1067800070933E098F5F8093A005809175028823E6 -:1067900031F043E06FE77DE08A2D0F94931482E09F -:1067A000F8125BC0C530A1F41092470910934B0951 -:1067B00000934A091092490910924809D091A00506 -:1067C000D53009F4D9C0809175028111E6C0D0E0BE -:1067D00086E044C08091820290918302A09184025D -:1067E000B09185028093980590939905A0939A059E -:1067F000B0939B05C11138C08092470910924B0994 -:1068000010924A091092490910924809DD23D9F0E3 -:106810008091A0051816BCF040913B0950913C09AD -:1068200060913D0970913E094F5F5F4F6F4F7F4F01 -:1068300040933B0950933C0960933D0970933E0996 -:106840008F5F8093A00580917502882331F043E02B -:106850006AE67DE08A2D0F94931485E0CF5F9C1249 -:1068600067CF80939E0522C0C13071F5D091A005FD -:10687000D13081F080917502882351F081E0D130D0 -:1068800009F080E024E046EC5DE0672D0F941E15D2 -:10689000D0E085CF80913F0910923F09882351F3C2 -:1068A0000E946C2E80919F05882321F3DF91CF9168 -:1068B0001F910F91FF90EF90DF90CF90BF90AF901E -:1068C0009F908F907F900895C23009F071C0D09151 -:1068D000A005D23069F0809175028823C9F281E069 -:1068E000D23009F080E023E041E45DE06B2DCECFB3 -:1068F00080913F0910923F09882369F38AE394E26B -:106900000E947D2480919F05882329F3CFCF809119 -:106910003F0910923F09882309F452C081E294E2B2 -:106920000E947D2480919F05882309F449C0BECF31 -:10693000C43009F034CFD091A005D43071F08091EB -:106940007502882309F4A4CF81E0D43009F080E0F7 -:1069500023E04DE25DE06D2D99CF80913F091092CB -:106960003F09882361F388E094E20E947D248091AE -:106970009F05882321F39ACF80913F0910923F0908 -:10698000882309F420CF8FEE93E20E947D2480912A -:106990009F05882309F417CF89CF81E0D53009F00E -:1069A00080E023E04EE15DE06E2D0F941E150FCFC9 -:1069B000C33009F0BDCFD091A005D33009F4A7CFE3 -:1069C00080917502882309F463CF81E0D33009F008 -:1069D00080E023E048E35DE06C2D58CF41E06CE4BB -:1069E00075E483E00C94693340E06FE475E483E080 -:1069F0000C9469334091510963E377E482E00C948D -:106A000069334091510966E377E481E00C9469337E -:106A10004091510969E377E480E00C946933409137 -:106A2000510962E575E483E00C9469332F923F923B -:106A30004F925F926F927F928F929F92AF92BF928E -:106A4000CF92DF92EF92FF920F931F93CF93DF933A -:106A500000D000D01F92CDB7DEB70E9462CD482E85 -:106A600061E081E00E9432237090A105572C25E05F -:106A7000270D298382E087198A8381E087198B8318 -:106A8000872D81958C8309ED1BE29EE3E92E99E029 -:106A9000F92E2CECC22E2BE2D22E3FE1A32E39E0B0 -:106AA000B32E4DED842E4BE2942E711000C19091C7 -:106AB000A0059D83992309F4D3C080917502882392 -:106AC00009F4A3C181E02D81211180E024E047E891 -:106AD00059E06C810F941E1582E041103AC183E0A9 -:106AE0008D838D81871115C09091A0059E83981785 -:106AF00009F437C180917502882359F0672D651913 -:106B000081E02E81271180E023E04CE559E00F94CD -:106B10001E156D8063941F821E82272C2518761007 -:106B200025C0EE81FF81EE0FFF1FE75EF14F8591DB -:106B300094912E812093470990934B0980934A09A1 -:106B400010924909109248093090A005371409F4B1 -:106B50001EC180917502882349F081E0361080E0E3 -:106B600023E04DE459E0622D0F941E15362C662467 -:106B70006394630C8E819F81019709F003C16710B4 -:106B80001EC08091A005871509F412C1809175027D -:106B90008823A9F01F930F93FF92EF92872D8519F9 -:106BA0008F9381E09091A005971180E08F930E94D0 -:106BB0007D250F900F900F900F900F900F9082E017 -:106BC000830D411046C0871120C08091A005871514 -:106BD00009F4FDC0809175028823B9F09F928F92CD -:106BE00080E399E09F938F93872D85198F9381E0A0 -:106BF0009091A005971180E08F930E947D250F90C2 -:106C00000F900F900F900F900F9083E0830D8711DE -:106C10001EC08091A005871509F4E8C08091750217 -:106C20008823A9F0DF92CF92BF92AF92872D85196A -:106C30008F9381E09091A005971180E08F930E943F -:106C40007D250F900F900F900F900F900F9084E084 -:106C5000830D73949981971128CF80939E050EC060 -:106C600080913F0910923F09882309F426CF0E94A2 -:106C70006C2E80919F05882309F41FCF27960FB6AD -:106C8000F894DEBF0FBECDBFDF91CF911F910F9162 -:106C9000FF90EF90DF90CF90BF90AF909F908F903C -:106CA0007F906F905F904F903F902F90089591E06C -:106CB000791214C02091A0052D83213001F180911B -:106CC0007502882359F081E09D81913009F080E0C0 -:106CD00023E045E759E06B810F941E1541103BC03E -:106CE00022E072123BC08091A0058D838230B1F00A -:106CF00080917502811121C093E09D830ACF80911C -:106D00003F0910923F098823D1F287EB93E50E9457 -:106D10007D2480919F05882391F2B0CF80913F0917 -:106D200010923F09882321F386E096E50E947D2496 -:106D300080919F058823E1F2A1CF81E02D8122304F -:106D400009F080E023E048E659E06A810F941E15BF -:106D500083E08D83DECE92E09D83C3CE23E02D833E -:106D6000C0CE80913F0910923F09882309F4C2CE1A -:106D70008FEE97E50E947D2480919F05882309F47A -:106D8000B9CE7CCF81E090E09F838E83C8CE809186 -:106D90003F0910923F09882309F4DBCE8EEB98E57A -:106DA0000E947D2480919F05882309F4D2CE66CF6E -:106DB00080913F0910923F09882309F4E7CE0E9491 -:106DC000D92B80919F05882309F4E0CE57CF80917D -:106DD0003F0910923F09882309F4FCCE0E94DD2B65 -:106DE00080919F05882309F4F5CE48CF80913F0913 -:106DF00010923F09882309F411CF0E94CC2B809177 -:106E00009F05882309F40ACF39CF442009F474CFB1 -:106E100022E02D837ECE2F923F924F925F926F920F -:106E20007F928F929F92AF92BF92CF92DF92EF921A -:106E3000FF920F931F93CF93DF9300D0CDB7DEB7B0 -:106E40000E9481CD8111EEC082E0809336090E94BC -:106E500062CD682E61E081E00E9432232091A1057D -:106E60002A83722E2B5F2983572C51949FE0C92EC1 -:106E70009AE0D92E28E0A22E2AE0B22E3FEF832EF0 -:106E800039E0932E8A81811114C09091A0059B83D3 -:106E9000992309F4C9C080917502882351F081E0DB -:106EA000EB81E11180E024E041E25AE0652D0F948E -:106EB0001E150FE316E07801F1E0FB834A804A9447 -:106EC0003A803718F701808591850E94F7CC882396 -:106ED00009F4E2C0FA812B81F2131DC040924709E8 -:106EE00010924B0910924A091092490910924809D0 -:106EF0002090A0052F1609F4BEC08091750288234A -:106F000051F081E09A81291280E023E04FE05AE0BD -:106F1000632D0F941E158B818F5F97E1E90EF11C95 -:106F2000EB81E23009F0A4C0611073C08B838FE362 -:106F3000E82E86E0F82E412C3A803718F70180853C -:106F400091850E94F7CC882309F4F1C0FA812B8146 -:106F5000F2131DC04092470910924B0910924A0942 -:106F600010924909109248092090A0052F1609F4A3 -:106F7000CDC080917502882351F081E09A81291259 -:106F800080E023E048E05AE0632D0F941E158B81CA -:106F90008F5F97E1E90EF11CEB81EF5FEB83F1E08E -:106FA0004F12B1C08B83F12CEA80E718F80180857D -:106FB00091850E94F7CC882309F404C1FA812B81C2 -:106FC000F2131DC0F092470910924B0910924A0922 -:106FD00010924909109248094090A0054F1609F4F3 -:106FE000E0C080917502882351F081E09A814912B6 -:106FF00080E023E04FEF59E06E2D0F941E158B813A -:107000008F5F095E1F4F9B819F5F9B83E1E0FE12B4 -:10701000C5C0FA81FF5FFA8329812F1333CF809394 -:107020009E0510C081E011CF80913F0910923F0969 -:10703000882309F430CF0E946C2E80919F0588230D -:1070400009F429CF0F900F900F90DF91CF911F91EE -:107050000F91FF90EF90DF90CF90BF90AF909F90F7 -:107060008F907F906F905F904F903F902F900895FA -:1070700022E02B8327CF80913F0910923F0988237C -:1070800009F43BCF82EB93E50E947D2480919F051C -:10709000882309F432CFD6CFEA81FB81EF133BCFAF -:1070A0004092470910924B0910924A0910924909DF -:1070B000109248098091A0058E17C1F08091750249 -:1070C000882309F428CF1F92DF92CF923F9281E06C -:1070D0009091A0052A81921380E08F930E947D25D4 -:1070E0000F900F900F900F900F9015CF80913F0948 -:1070F00010923F09882311F30E94522C80919F0522 -:107100008823E1F29FCF4424439418CF80913F0914 -:1071100010923F09882309F42CCF8DEA93E50E9451 -:107120007D2480919F05882309F423CF8BCFEA81AA -:10713000FB81EF132CCF4092470910924B0910921C -:107140004A0910924909109248098091A0058E17AA -:10715000C1F080917502882309F419CF1F92BF9264 -:10716000AF923F9281E09091A0052A81921380E036 -:107170008F930E947D250F900F900F900F900F908E -:1071800006CF80913F0910923F09882311F30E9496 -:107190001D2C80919F058823E1F254CFFF24F394A6 -:1071A00005CF80913F0910923F09882309F419CF38 -:1071B00088EA93E50E947D2480919F05882309F445 -:1071C00010CF40CFEA81FB81EF1319CFF09247092E -:1071D00010924B0910924A091092490910924809DD -:1071E0008091A0058E17C1F080917502882309F463 -:1071F00006CF1F929F928F92EF9281E09091A0050F -:107200002A81921380E08F930E947D250F900F902A -:107210000F900F900F90F3CE80913F0910923F098D -:10722000882311F30E94E82B80919F058823E1F2C7 -:1072300009CF8F929F92AF92BF92CF92DF92EF923F -:10724000FF920F931F93CF93DF9361E081E00E9441 -:107250003223C091A1051C2F85E0882E8C0ED1E031 -:107260009FEBC92E97E2D92E09E00C1B88E0F82E7F -:10727000FC1A87E0E82EEC1A86E0B82EBC1A85E0EE -:10728000A82EAC1A84E0982E9C1AC1112FC0DD23C1 -:10729000D9F08091A0051816BCF040913B0950919F -:1072A0003C0960913D0970913E094F5F5F4F6F4F00 -:1072B0007F4F40933B0950933C0960933D09709385 -:1072C0003E098F5F8093A00580917502882339F075 -:1072D00043E066E17CE0812F81950F949314CF5FAA -:1072E0008C12D3CF8AE080939E0523C0C13071F504 -:1072F000D091A005D13089F080917502882359F092 -:1073000061E0611B81E0D13009F080E024E04CEFC6 -:107310005BE00F941E15D0E0E2CF80913F09109200 -:107320003F09882349F30E946C2E80919F05882392 -:1073300019F3DF91CF911F910F91FF90EF90DF90A4 -:10734000CF90BF90AF909F908F900895C23009F07A -:1073500029C18091A0058230B9F0809175028823FF -:10736000D1F28BE497E29F938F9389EC9BE09F93FC -:107370008F9382E0811B8F9381E09091A0059230E2 -:1073800009F42EC180E02CC180913F0910923F0981 -:10739000882319F30E944B2780919F058823E9F2E7 -:1073A000C8CF80913F0910923F09882309F402C198 -:1073B0000E945E2780919F05882309F4FBC0B9CF06 -:1073C000C43029F58091A0058430A1F08091750228 -:1073D000882309F4A0CF81E797E29F938F938EEBE8 -:1073E0009BE09F938F939F9281E09091A0059430B2 -:1073F00049F6F6C080913F0910923F09882331F386 -:107400000E94712780919F05882301F392CFC53098 -:1074100031F58091A0058530A9F08091750288230F -:1074200009F479CF85E897E29F938F9387EB9BE0F0 -:107430009F938F93AF9281E09091A005953009F0D2 -:10744000A1CFCEC080913F0910923F09882329F334 -:107450000E94852780919F058823F9F26ACFC63064 -:1074600051F58091A0058630A9F08091750288239E -:1074700009F451CF85EF9BEC9F938F9381EB9BE0B9 -:107480009F938F93BF9281E09091A005963009F071 -:1074900079CFA6C080913F0910923F09882329F334 -:1074A00085EF9BEC892B11F00E94F5CB80919F0515 -:1074B0008823D9F23ECFC73031F58091A0058730BF -:1074C000A9F080917502882309F425CF89E997E214 -:1074D0009F938F938CEA9BE09F938F93EF9281E031 -:1074E0009091A005973009F04DCF7AC080913F0967 -:1074F00010923F09882329F30E94992780919F05C4 -:107500008823F9F216CFC83031F58091A005883074 -:10751000A9F080917502882309F4FDCE8CEA97E2E8 -:107520009F938F9385EA9BE09F938F93FF9281E0D7 -:107530009091A005983009F025CF52C080913F0965 -:1075400010923F09882329F30E94AC2780919F0560 -:107550008823F9F2EECEC93009F0C1CE8091A005A2 -:10756000893099F080917502882309F4D4CEDF9296 -:10757000CF928EE99BE09F938F930F9381E0909140 -:10758000A005993009F0FECE2BC080913F091092E2 -:107590003F09882339F30E94BF2780919F058823E4 -:1075A00009F3C7CEC33009F00BCF8091A00583301B -:1075B00009F4F7CE80917502882309F4ACCE8EE5EC -:1075C00097E29F938F9385EC9BE09F938F9383E04B -:1075D000811B8F9381E09091A005933009F0D2CE6A -:1075E0008F930E947D250F900F900F900F900F901A -:1075F0000F9091CECF93DF93CDB7DEB78E81282F3A -:10760000082E000C330B909144129217130609F0C8 -:107610008CF4809344129E01275F3F4F4F81588521 -:107620006AE270E089E192E10F94783910921812C1 -:1076300010921712DF91CF9108950F931F93CF935C -:10764000DF938C016F3F19F41092441260E0209197 -:107650004412862F062E000C990B2817190609F0E4 -:1076600014F560934412C8010F94FE38800F911FE7 -:10767000EC01C01BD10BCB32D1053CF00197FC01D2 -:107680002491207C2038D1F3F3CFDD27AE01B8015F -:1076900089E192E10F941F39C75EDD4E1882109286 -:1076A000181210921712DF91CF911F910F91089528 -:1076B000CF9380914205811109C087E597E09093AF -:1076C00091058093900581E0809342050E945324A8 -:1076D00020E040E070E060E08FE396E20E949323B8 -:1076E000C1E0C09340090E947F8F109240090E9420 -:1076F0006C2EC093400960E081E79CE30E941D3B33 -:107700004091510961E080E00E94092E8DE497E0EC -:107710009093F3088093F208CF9108952F923F92AF -:107720004F925F926F927F928F929F92AF92BF9291 -:10773000CF92DF92EF92FF920F931F93CF93DF933D -:1077400000D000D01F92CDB7DEB780919A06412CB1 -:10775000811103C00E944FCD482E8091A21784FB57 -:10776000222720F92983312C84FF03C00E9473CD86 -:10777000382E61E081E00E9432238091A1058E8342 -:10778000582E8B5F8A8380E00EEA1CE091E0792E10 -:107790007518952D91959B8398E5E92E9BE3F92E1D -:1077A0002BECC22E2CE0D22E92E095199C8393E014 -:1077B00095199D833BE4A32E3CE0B32E42E7842E33 -:1077C0004CE0942E9A812E81921709F463C22223F1 -:1077D00039F1411079C00E9481CD882309F4B2C1EA -:1077E0008E81813009F47DC192E09F832E818F814B -:1077F000281398C12090A005221609F4A5C18091F4 -:107800007502882309F48EC16E81651981E09E811D -:10781000291280E023E047EA5CE00F941E1582C144 -:107820006090A005662059F180917502882389F245 -:1078300081E0611080E024E047ED5CE06B810F9413 -:107840001E15442041F224E02F838F819E818913ED -:107850005EC02090A005281609F487C180917502AA -:10786000882309F454C06E81651981E02E812212AB -:1078700080E023E04BE95CE00F941E1548C0809146 -:107880003F0910923F09882379F20E946C2E809163 -:107890009F05882349F227960FB6F894DEBF0FBEE6 -:1078A000CDBFDF91CF911F910F91FF90EF90DF90AF -:1078B000CF90BF90AF909F908F907F906F905F9090 -:1078C0004F903F902F9008958E81813009F4A8C089 -:1078D000823009F4D0C09E81933009F0B4CF8091FA -:1078E000A0058F83833009F4EBC080917502882353 -:1078F00009F4A9CF81E09F81933009F080E023E073 -:107900004BEB5CE06D810F941E1524E02F838F817B -:107910008F5F9E81891314C02090A005291609F459 -:1079200035C180917502882359F06E81651981E017 -:107930002E81221280E023E04DE85CE00F941E15BA -:107940008F818E5F9E81891314C02090A005291617 -:1079500009F42DC180917502882359F06E81651953 -:1079600081E02E81221280E023E04DE75CE00F945D -:107970001E158F818D5F9E81891314C02090A005F4 -:10798000291609F425C180917502882359F06E816A -:10799000651981E02E81221280E023E046E75CE059 -:1079A0000F941E158F818C5F9981992309F444C12E -:1079B000311032C02E81821314C09091A00592170D -:1079C00009F417C180917502882359F06E816519F9 -:1079D00081E02E81921380E020E245E65CE00F9486 -:1079E0001E158F818B5F9E81891314C02090A00586 -:1079F000291609F410C180917502882359F06E810F -:107A0000651981E02E81221280E023E044E55CE0EC -:107A10000F941E158F818A5F9E819F5F9E83D2CEB9 -:107A20008091A0058130D1F080917502882309F4FE -:107A30000ACFFF92EF92DF92CF927F9281E09091F6 -:107A4000A005913009F080E08F930E947D250F9072 -:107A50000F900F900F900F900F90F5CE80913F09EF -:107A600010923F09882301F30E94583B80919F05A3 -:107A70008823D1F210CF2091A0052F83223089F0E6 -:107A800080917502882309F4DECE81E09F819230D7 -:107A900009F080E023E040EC5CE06C810F941E155F -:107AA000D2CE80913F0910923F09882349F38FEA93 -:107AB00096E20E947D2480919F05882309F3EBCEF6 -:107AC00080913F0910923F09882309F40ECF8AEF75 -:107AD00098E40E947D2480919F05882309F405CFB6 -:107AE000DACE8091A005813001F180917502882362 -:107AF00009F47ACE8EE297E29F938F931F930F93B0 -:107B00007F9281E09091A005913009F080E08F9301 -:107B10000E947D250F900F900F900F900F900F9067 -:107B200082E08F832F812F5F8FCE80913F0910924B -:107B30003F098823D1F20E942E2780919F05882338 -:107B4000A1F2A9CE91E051CE80913F0910923F0958 -:107B5000882309F454CE82EA90E30E947D24809128 -:107B60009F05882309F44BCE96CE80913F09109251 -:107B70003F09882309F472CE8FE19EE40E947D24A0 -:107B800080919F05882309F469CE85CE80913F09B5 -:107B900010923F09882309F4C4CE86E195E30E9440 -:107BA0007D2480919F05882309F4BBCE74CE8091FB -:107BB0003F0910923F09882309F4CCCE8BE097E36C -:107BC0000E947D2480919F05882309F4C3CE63CE53 -:107BD00080913F0910923F09882309F4D4CE84E2B2 -:107BE00091E50E947D2480919F05882309F4CBCEE6 -:107BF00052CE80913F0910923F09882309F4E2CECA -:107C00009092F3088092F20880919F05882309F4EE -:107C1000D9CE8E8101CF80913F0910923F098823F0 -:107C200009F4E9CE83EF9DE60E947D2480919F05B3 -:107C3000882309F4E0CEEDCF9E8189131DC0909179 -:107C4000A0052E819217D9F0809175028823A1F0AA -:107C50001F921F92BF92AF928E8185198F9381E000 -:107C60002E81921380E08F930E947D250F900F90BC -:107C70000F900F900F900F908F818B5FCDCE8091E2 -:107C80003F0910923F098823F9F280919F058823CC -:107C9000D9F2BFCF80939E05FECD10924F0910926E -:107CA00074020E9473CD9091A21780FB97F9909374 -:107CB000A21760E08FE397E00E941D3B0C945E2DBD -:107CC0000F931F930F941E1D00913E0510913F05C9 -:107CD0002091400530914105601B710B820B930B85 -:107CE00097FD0BC086B18295817091E08927369B04 -:107CF0008260329B84608093FF038091FF038170D8 -:107D00009091FF0391FD826090913D05981749F095 -:107D1000813029F148F0823089F08330A1F08093DE -:107D20003D051F910F910895913089F09230B9F778 -:107D300090913C0520911B02921B0EC0992339F0B3 -:107D40009330B1F3ECCF913099F3923041F79091A9 -:107D50003C0520911B02920F90933C05E0CF9923A4 -:107D600039F39330E1F6F3CFFC0180E0309749F02E -:107D70009491992331F0907C903809F08F5F31967F -:107D8000F7CF0895AF92BF92CF92DF92EF92FF921A -:107D90000F931F93CF93DF93EC015B018A01FB01EB -:107DA000199587FD16C0C82ED12CF12CE12C2196F7 -:107DB000F801C082D182E282F382CE01DF91CF91BD -:107DC0001F910F91FF90EF90DF90CF90BF90AF90F9 -:107DD0000895982F907E903CA9F48F7190E0B0E0C8 -:107DE000A0E06C017D0156E0CC0CDD1CEE1CFF1CFC -:107DF0005A95D1F7CE010196F50119958F73C82ACE -:107E00002296D6CF982F907F903E11F58F7090E0FC -:107E1000B0E0A0E06C017D0136E0CC0CDD1CEE1C76 -:107E2000FF1C3A95D1F7CE010196F50119958F7394 -:107E3000C82A46E0CC0CDD1CEE1CFF1C4A95D1F78D -:107E4000CE010296F50119958F73C82A2396B0CFFB -:107E5000982F987F903F79F5877090E0B0E0A0E090 -:107E60006C017D0186E0CC0CDD1CEE1CFF1C8A95AC -:107E7000D1F7CE010196F50119958F73C82A96E0C6 -:107E8000CC0CDD1CEE1CFF1C9A95D1F7CE0102969E -:107E9000F50119958F73C82A26E0CC0CDD1CEE1C69 -:107EA000FF1C2A95D1F7CE010396F50119958F7322 -:107EB000C82A24967DCF982F907C903841F4807CFE -:107EC000803869F42196CE01F5011995F8CF8E7F9F -:107ED0008D3F28F02196CE01F5011995F8CFC12CE0 -:107EE000D12C760165CF9CE0899F802D112491E0F3 -:107EF000980F909304052CE0280F2093460930E05A -:107F00002E5F3F4F40917D164217130619F014F073 -:107F100080E0089520917F169217D0F7662341F0F4 -:107F20008E5F0F947423809146098E5F0F947423A3 -:107F30008091460990917D16891750F320917F1604 -:107F400090910405291720F31092801680938116D2 -:107F500081E0089520910205022E000C330B821758 -:107F6000130641F0809302056CEE7EE089E496E111 -:107F70000D94192508951F93CF93DF931F92CDB7CA -:107F8000DEB710912E0280918216811105C081E02A -:107F9000809382160F94492260914B1670914C1673 -:107FA00019839E012F5F3F4F4FE089E496E10F94C4 -:107FB00045220F90DF91CF911F910895CF9380912B -:107FC000030581114FC010928016109281161092F5 -:107FD000821610924E1610924D1610925016109254 -:107FE0004F161092521681E08093511682E28093D0 -:107FF00053161092581610925716ECE6F6E12AE73F -:1080000036E18FEF81932E173F07E1F7C1E0C09370 -:10801000691622E132E030935F1620935E16C0931A -:108020006016109261161092621690E49093631697 -:10803000109264162AE231E030937B1620937A1670 -:1080400028E032E030934C1620934B1691E1909348 -:108050006E1690E190936D1680936C160F944922E2 -:10806000C0930305099A11988FE19EE40197F1F7F7 -:1080700000C00000119A8FE19EE40197F1F700C063 -:108080000000C1E0C09382160F9449228FEF8093C5 -:108090002E020E94BB3FC093FA038DE096E09093BE -:1080A000880F8093870F10928A0F1092890FCF91BB -:1080B00008950E94DE3F3C98449A3E98469A3A982A -:1080C000429A0E94603E10923C050D948E10EF92F1 -:1080D000FF920F931F93CF93DF93CDB7DEB72C970B -:1080E0000FB6F894DEBF0FBECDBFFC016081718179 -:1080F000828193816F3F71058105910509F0C0F47C -:1081000085E496E10E940929E0914D16F0914E1602 -:108110003196849190E02C960FB6F894DEBF0FBE96 -:10812000CDBFDF91CF911F910F91FF90EF900895F8 -:1081300010918016009181162091FA0321110FC031 -:108140004DEE55E0602F812F0F94DD2590E080E00B -:10815000180F10938016009381169927DCCFE090BA -:108160004D16F0904E1629E436E13A832983212FEB -:1081700030E03C832B83202F30E03E832D83188614 -:108180001F822FEF3FEF3A8729871C861B8627EA3D -:1081900038E2AE014F5F5F4FBF01C7010F948B0FF5 -:1081A000B70189E496E10F9419258F819885D0CF86 -:1081B0004F925F926F927F928F929F92BF92CF92D7 -:1081C000DF92EF92FF920F931F93CF93DF9300D034 -:1081D00000D01F921F92CDB7DEB77C016A01490122 -:1081E000FB0190818CE0989F800D1124982FF7015E -:1081F0002081822F880F820F880F809380169093A2 -:1082000081164115510579F1FA82E9827C836B83ED -:10821000011122C0AE014B5F5F4FB401C6010E9445 -:10822000C23E6C018D819E81AF81B885892B8A2BDE -:108230008B2BC9F0CE0105960E946740F701808123 -:108240008F5F8083853130F3CE0101960E948B24AD -:10825000E1CFB12C860129C08A01B12C26C0452866 -:1082600046284728B1F728960FB6F894DEBF0FBE10 -:10827000CDBFDF91CF911F910F91FF90EF90DF90D5 -:10828000CF90BF909F908F907F906F905F904F9016 -:108290000895B39407C0B1102EC001151105C9F29D -:1082A0000F5F1F4F01151105A9F2AE014B5F5F4F24 -:1082B000B401C6010E94C23E6C014D805E806F8099 -:1082C00078844114510461047104A9F0F0E24F165E -:1082D000510461047104F9F2D301C2018D97A1091F -:1082E000B1090297A105B10530F04BE244165104E3 -:1082F0006104710471F6F7018081482F4B0D5527F9 -:10830000551F4631510534F0853020F0CE010196DD -:108310000E948B2481E0411451046104710409F42A -:1083200080E0B80EF70180818B0D8083BB2009F4BB -:1083300096CFBA94AE014B5F5F4FB401C8010E9463 -:10834000C23E8C01CE0105960E946740EFCF6F922E -:108350007F928F929F92AF92BF92CF92DF92EF92D5 -:10836000FF920F931F93CF93DF9300D000D01F9203 -:108370001F92CDB7DEB77C01162F5A014901862F17 -:10838000660F990B9C0124563D4F690186E0682ECB -:10839000712C10160CF046C0AE014B5F5F4F61EAC6 -:1083A00074E2C7010E94C23E7C018D819E81AF8133 -:1083B000B8850097A105B105A9F18D339105A105F7 -:1083C000B10509F480C08E379105A105B10509F406 -:1083D0007AC08A329105A105B105D1F517FF12C007 -:1083E00083E596E01E3F11F08FE496E036E003024D -:1083F000B00111240E947FC766E070E00F944841ED -:10840000061B9BC085E490E0A0E0B0E089839A83DE -:10841000AB83BC83CE0101960E946740015009F0F6 -:1084200054C000E0802F28960FB6F894DEBF0FBE30 -:10843000CDBFDF91CF911F910F91FF90EF90DF9013 -:10844000CF90BF90AF909F908F907F906F90089546 -:1084500084329105A105B105D1F48114910461F034 -:10846000E6E00E02B0011124C4010E947FC7B301EF -:108470000F944841061B8DCFA114B104F1F0F6E032 -:108480000F02B0011124C5010E94DDC7F0CF803476 -:108490009105A105B10589F40150F6018081082EEE -:1084A000000C990BAA0BBB0B89839A83AB83BC830B -:1084B000CE0101960E9467406CCFCE0105960E94C6 -:1084C0006740015066CF17FD8BCF81E04D815E8103 -:1084D0006F8178854D3351056105710509F480E0A0 -:1084E000810F8A30CCF001506AE00F942641D92EDA -:1084F000082E000C990BC096092E000CAA0BBB0B82 -:1085000089839A83AB83BC83CE0101960E94674026 -:10851000002309F486CF8D2D082E000C990BC096F0 -:10852000092E000CAA0BBB0B89839A83AB83BC83F7 -:10853000CE0101960E9467400150002309F471CFDB -:1085400086E00802B0011124C7010E947FC766E0DF -:1085500070E00F944841061B65CF6FEF7FEF0C94DE -:10856000DDC72F923F924F925F926F927F928F92D0 -:108570009F92AF92BF92CF92DF92EF92FF920F93B2 -:108580001F93CF93DF9300D000D01F92CDB7DEB7FB -:108590004C010F94FE3801966401C80ED91EC60125 -:1085A0000F94FE3801961601280E391ED601EC9064 -:1085B00001E0E11001C000E0F101408077247394F4 -:1085C000411001C0712C11E0E11010E060E085E085 -:1085D0000E9432235090A105F52C9EE0A92EB12CCB -:1085E000F52DF195FF83812F90E00196080F192F4B -:1085F000111D9801270D311D3E832D83F1101BC0E5 -:1086000080917502882391F0E0911A02E2506AE4A9 -:108610007AE0E33038F4F0E0EE0FFF1FE654FD4F50 -:108620006081718143E08F810F94931401E0E11028 -:1086300011C002E00FC002E0E11001E00F110AC01A -:1086400080917502882331F041E0B401802F8519B3 -:108650000F94931411E0100F7F2C7518EE2069F021 -:108660001F1109C080917502882329F041E0B601ED -:10867000872D0F94931412E0100F442061F01F1106 -:1086800009C080917502882329F041E0B101872D4E -:108690000F9493141F5F4D815E81433051050CF49C -:1086A0001F5F1F1190C080917502882309F488C054 -:1086B00042E067E57AE0872D0F9493149EEF9A0DC0 -:1086C00080917D168A151B0411F00CF079C0209161 -:1086D0007F1683EF8A0D821708F072C000910004A4 -:1086E00025E430E040E050E029833A834B835C830B -:1086F0003EE33093801690938116CE0101960E943E -:10870000674081E3800F082E000C990BAA0BBB0B6E -:1087100089839A83AB83BC83CE0101960E94674014 -:1087200080E290E0A0E0B0E089839A83AB83BC83D1 -:10873000CE0101960E946740602E712C97E1969DB4 -:10874000F001979DF00D1124E15CF94F20E030E03D -:1087500040E05FE364817581868197810F94083ED4 -:108760000F94743FCB010E9492BD0E94AD422FE254 -:1087700030E040E050E029833A834B835C83CE01B4 -:1087800001960E9467400E94F22481110BC035E0DF -:10879000369DF001379DF00D1124E25EF94F848182 -:1087A00081110EC047E1469DF001479DF00D112457 -:1087B000E15CF94F808591850E9492BD0E94AD4297 -:1087C00052E0509375028CE0A80EB11CF3949AE429 -:1087D000A916B10409F012CF1F5F10939E052796CA -:1087E0000FB6F894DEBF0FBECDBFDF91CF911F91C2 -:1087F0000F91FF90EF90DF90CF90BF90AF909F9040 -:108800008F907F906F905F904F903F902F90089542 -:1088100082E69AE00C94B1428FE69AE00C94B14261 -:1088200081E99AE00C94B1428CE29BE00C94B14255 -:1088300087EE9AE00C94B14284E19BE00C94B14243 -:1088400087E69BE00C94B1428AE49BE00C94B14231 -:108850008AEC9AE00C94B1428BEA9AE00C94B14213 -:108860008F929F92AF92BF92CF92DF92EF92FF9240 -:108870000F931F93CF93DF9300D01F92CDB7DEB736 -:108880004C016B0181E080931B02C4010E94B43E45 -:10889000A82EC6010E94A724B12C23E130E0790163 -:1088A000E81AF10815E2EA14FB040CF41FE1812F29 -:1088B00090E09C012E5F3F4F40917D1642171306BA -:1088C00011F00CF04AC0099720917F16281719065D -:1088D0000CF443C020914A0930914B09409148095A -:1088E00050914909609147091092801610938116A2 -:1088F00005E1C4010E94A74101E0C114D104E1F0E7 -:108900008AE390E0A0E0B0E089839A83AB83BC83E4 -:10891000CE0101960E946740EA14FB0404F5145F3F -:1089200080917D16181740F020917F16412F4950F5 -:10893000550B24171506ACF40F900F900F900F9065 -:10894000DF91CF911F910F91FF90EF90DF90CF902B -:10895000BF90AF909F908F90089500E0CECF0023FE -:1089600059F380E290E0A0E0B0E089839A83AB8382 -:10897000BC838E2D880FE80EEE0CE09280161093CB -:108980008116CE0101960E946740C6010E94AD4249 -:10899000D3CF1F93CF93DF9300D01F92CDB7DEB715 -:1089A000182F80913F0910923F09882361F010929F -:1089B00040090E946C2E0F900F900F900F90DF9146 -:1089C000CF911F91089560913B0970913C0980916E -:1089D0003D0990913E09611571058105910569F187 -:1089E0000F94B83920911C0230911D0240911E0253 -:1089F00050911F020F94173A209182023091830206 -:108A000040918402509185020F94083E6093820247 -:108A1000709383028093840290938502612F83E098 -:108A20000E94B82481E08093750210923B09109255 -:108A30003C0910923D0910923E09809175028823ED -:108A400009F4B9CF1093470910924B0910924A09C3 -:108A50001092490910924809209198053091990582 -:108A600040919A0550919B0560918202709183021A -:108A700080918402909185020F94073E69837A83E6 -:108A80008B839C83CE0101960E9497BCBC018AE631 -:108A90009DE00E9430448FCF81E00C94C94480E077 -:108AA0000C94C944809151090C94C9443F924F924F -:108AB0005F926F927F928F929F92AF92BF92CF926E -:108AC000DF92EF92FF920F931F93CF93DF9300D02B -:108AD00000D000D01F92CDB7DEB7382E80913F096D -:108AE00010923F098823E1F0109240090E946C2EF9 -:108AF0002A960FB6F894DEBF0FBECDBFDF91CF919F -:108B00001F910F91FF90EF90DF90CF90BF90AF90AB -:108B10009F908F907F906F905F904F903F900895BF -:108B200060913B0970913C0980913D0990913E090B -:108B3000611571058105910509F459C0209137022D -:108B4000222309F4B9C0209138022111B5C021E0D7 -:108B5000321609F48FC0A2E03A1609F49CC0C09006 -:108B60003902D0903A02E0903B02F0903C024090F3 -:108B700045025090460260904702709048020F9460 -:108B8000B83920911C0230911D0240911E02509173 -:108B90001F020F94173A6F83788789879A87B4E00A -:108BA0003B9E80011124F801EA58FD4FFE83ED83BE -:108BB00020813181428153810F94083E4B015C0139 -:108BC000A3019201C701B6010F94B139811183C08D -:108BD000F801EA58FD4F80829182A282B3826091AF -:108BE0005109832D0E94B82481E080937502109270 -:108BF0003B0910923C0910923D0910923E09809168 -:108C00007502882309F474CF30924709F4E03F9E3F -:108C1000C0011124FC01EA58FD4F8359904FDC013B -:108C20002D913D914D915C91608171818281938103 -:108C30000F94083E6B017C01C982DA82EB82FC82D0 -:108C40002DEC3CEC4CEC5DE360911C0270911D023C -:108C500080911E0290911F020F94684087FD66C0AC -:108C6000CE0101960E9497BCBC018FE79DE00E9457 -:108C700030443ECFC0903D02D0903E02E0903F0293 -:108C8000F09040024090490250904A0260904B029E -:108C900070904C0274CFC0904102D0904202E0909C -:108CA0004302F090440240904D0250904E0260907A -:108CB0004F027090500263CF412C20E5522E23ECDE -:108CC000622E27E4722EC12C30E5D32E33ECE32E36 -:108CD00037ECF32E54CF20E030E0A9016F81788586 -:108CE00089859A850F94B13987FF10C0A701960135 -:108CF000C501B4010F94B13987FF6ACFAD81BE8140 -:108D0000CD92DD92ED92FC92139769CFA30192016F -:108D1000C501B4010F94684018160CF059CFED81CD -:108D2000FE81408251826282738259CF20E030E01E -:108D300040E251E4C701B6010F94173A20E030E059 -:108D40004AE754E40F94173A4B015C0120E030E00D -:108D5000A901C701B6010F94B13920E030E040EA23 -:108D600050E487FF04C020E030E040EA50ECC50149 -:108D7000B4010F94083E20E030E040E251E40F944B -:108D8000023F0F94743F6B017C01F7FC62C020EA44 -:108D900036E841E050E00F94C63DCA01B9012AE02F -:108DA00030E040E050E00F94C63D605D6093A20566 -:108DB000C701B60120E137E240E050E00F94C63D24 -:108DC0008AE0882E912CA12CB12CCA01B901A501F1 -:108DD00094010F94C63D605D6093A305C701B60181 -:108DE00028EE33E040E050E00F94C63DCA01B901DF -:108DF000A50194010F94C63D605D6093A4058EE2C9 -:108E00008093A505C701B60124E630E040E050E0BC -:108E10000F94C63DCA01B901A50194010F94C63D46 -:108E2000605D6093A605C701B601A50194010F948A -:108E3000C63D162FCA01B901A50194010F94C63D84 -:108E4000605D6093A705105D1093A80582EA95E028 -:108E50000BCFF094E094D094C094C11CD11CE11CC1 -:108E6000F11C6DE2A3CF82E00C94564581E00C9496 -:108E7000564580E00C9456450F931F93CF93DF9394 -:108E8000FC01EB0180913B0990913C09A0913D09C7 -:108E9000B0913E09B7FF08C010923B0910923C09FF -:108EA00010923D0910923E098091830590918405AE -:108EB000A0918505B091860540913B0950913C09F0 -:108EC00060913D0970913E0984179507A607B70781 -:108ED00044F480933B0990933C09A0933D09B093DF -:108EE0003E09809175028823E1F060913B09709101 -:108EF0003C0980913D0990913E09009187051091B0 -:108F000088052091890530918A05600F711F821FA5 -:108F1000931F1995BC0180918D0590918E050E943B -:108F2000304480913F09811108C0809180058823D9 -:108F3000D1F1809175028823B1F180918B059091D8 -:108F40008C050097B1F040913B0950913C0960912C -:108F50003D0970913E090091870510918805209187 -:108F6000890530918A05400F511F621F731FFE0152 -:108F70001995E0918105F0918205309741F080913B -:108F80008005811103C080913F098111199580915D -:108F90003F0910923F09882331F0DF91CF911F9153 -:108FA0000F910C946C2EDF91CF911F910F9108952A -:108FB00062EF7EE18FE895E20C943C4760E57FE14B -:108FC00084E497E20C943C4760EB70E28AE695E219 -:108FD0000C943C4767ED70E28AE295E20C943C47C2 -:108FE00068EE72E28CEF92E20C943C4762E972E226 -:108FF00086EA92E20C943C4760EB72E28BEE97E2D9 -:109000000C943C4766EC72E288E298E20C943C4790 -:109010006AED72E282E398E20C943C4766E073E208 -:1090200083E695E20C943C4769EC70E28EE698E2A8 -:109030000C943C4764E173E288E293E20C943C4771 -:109040004F925F926F927F928F929F92AF92BF9258 -:10905000CF92DF92EF92FF920F931F93CF93DF9304 -:10906000CDB7DEB72C970FB6F894DEBF0FBECDBFDD -:10907000982F862F5A017901D02E692F0E94733FB5 -:10908000882309F49CC01091FA03C701002309F456 -:1090900041C00E94B43EC82E80904D1690904E164E -:1090A000111155C01FEF03E10C1920914A093091AD -:1090B0004B09409148095091490960914709C50100 -:1090C0000E94A741CC2009F47AC0B6E08B9F5001E2 -:1090D00011248AE390E0A0E0B0E089839A83AB8317 -:1090E000BC83CE0101960E94674080E2482E512C3D -:1090F000612C712C57E0A516B10408F445C04982D3 -:109100005A826B827C82CE0101960E946740A81A27 -:10911000B90AF0CF0E94A724C82E80904D169090D7 -:109120004E16112309F4BECFFE0133968AE0DF010B -:109130001D928A95E9F789E496E19A8389830EE77F -:1091400018E29E012F5F3F4F44EA54E212C0FE0135 -:1091500033968AE0DF011D928A95E9F789E496E16A -:109160009A8389830EE718E29E012F5F3F4F41EA01 -:1091700054E2B701C4010F945010B40189E496E1A0 -:109180000F9419251F818FCF40914609212F30E080 -:10919000A6E0CA9EC00111242E5F3F4F2817390751 -:1091A0000CF49C0180E8821B80938016409381160A -:1091B000DD20E1F06FEF7FEFC7010E947FC72C96A3 -:1091C0000FB6F894DEBF0FBECDBFDF91CF911F91D8 -:1091D0000F91FF90EF90DF90CF90BF90AF909F9056 -:1091E0008F907F906F905F904F900895C7010E947D -:1091F000AD42E5CF6F927F928F929F92AF92BF92D6 -:10920000CF92DF92EF92FF920F931F93CF93DF9352 -:1092100061E081E00E943223C091A105DC2FF5E0DE -:10922000AF2EAC0E81E0D82EDC1A9C2E9194A7E1D3 -:10923000BA2E8824839484E0C82ECC1AC11142C16E -:109240001091A005112309F420C180917502882393 -:1092500049F081E0111180E024E047EE5EE0692DE5 -:109260000F941E15F12CE12CE2E07E2E6C2E6D1A6F -:10927000C7112BC0E092470910924B0910924A097E -:1092800010924909109248098091A0058C1709F4A1 -:1092900051C1809175028823C1F011E08091A00531 -:1092A000871110E0BE9CF001BF9CF00D1124E15C21 -:1092B000F94F808591850E9492BD00E09C0148EDA8 -:1092C0005EE0662D812F0E942048872D9FEFE91ACE -:1092D000F90A63E0762E833059F6C430E9F48091C0 -:1092E000A005843009F44DC1809175028823A1F056 -:1092F00011E08091A005843009F010E080913606DD -:10930000909137060E9492BD00E09C0144ED5EE022 -:109310006C2D812F0E9420488091D20580933609C0 -:10932000C53031F51092470910924B0910924A0945 -:1093300010924909109248098091A005853009F4DE -:109340003BC180917502882399F0FC2EFD1A11E033 -:109350008091A0058C1310E0809136090E942ABEEE -:1093600000E09C0148EC5EE06F2D812F0E942048B8 -:109370008091D30580933609C63031F58092470934 -:1093800010924B0910924A0910924909109248090B -:109390008091A005863009F424C18091750288234C -:1093A00099F0FC2EFD1A11E08091A0058C1310E0BD -:1093B000809136090E942ABE00E09C0148EC5EE0E4 -:1093C0006F2D812F0E942048C73019F58091A0058C -:1093D000873009F41BC1809175028823D1F0FC2EDF -:1093E000FD1A11E08091A0058C1310E0E091510965 -:1093F000F0E0EE0FFF1FEE5DFD4F808191810E9436 -:1094000092BD00E09C0143EC5EE06F2D812F0E9435 -:10941000204838E0732EF12CE12C6C2E6D1AC71108 -:1094200029C0E092470910924B0910924A09109204 -:109430004909109248098091A0058C1709F408C1C8 -:10944000809175028823B1F011E08091A005871109 -:1094500010E0F701EE0FFF1FEE5DFD4F808191815F -:109460000E9492BD00E09C014CEB5EE0662D812FD6 -:109470000E9420487394EA94EF2809F0E5C0CF5F7A -:10948000AC12DCCE70929E050EC080913F09109206 -:109490003F09882309F4D9CE0E946C2E80919F0544 -:1094A000882309F4D2CEDF91CF911F910F91FF90C5 -:1094B000EF90DF90CF90BF90AF909F908F907F9074 -:1094C0006F900895C13009F0CDCE8091A005813014 -:1094D000D1F080917502882309F4C4CE11E0809107 -:1094E000A005813009F010E08091200290912102C6 -:1094F0000E9492BD00E09C0141EE5EE06D2D812F47 -:109500000E942048AFCE80913F0910923F098823E6 -:1095100001F310E000E027EE33E04AE050E060E2C3 -:1095200072E081EE9EE00F94CC1680919F05882317 -:1095300081F2B9CF80913F0910923F09882309F445 -:10954000A8CE0F94BF15F701EE0FFF1FE054FD4F9B -:10955000208131812F503109BE9CB001BF9C700D1C -:109560001124695B794F0BE815E250E040E088ED8B -:109570009EE00F94CC1680919F05882309F489CE34 -:1095800092CF80913F0910923F09882309F4ACCE15 -:109590000F94BF1502E216EC24E630E050E040E004 -:1095A00066E376E084ED9EE00F94CC1680919F05F3 -:1095B000882309F499CE77CF80913F0910923F0913 -:1095C000882309F4BECE0F94BF1566E07FE188ECD6 -:1095D0009EE00F94A41780919F05882309F4B1CED3 -:1095E00062CF80913F0910923F09882309F4D5CEBC -:1095F0000F94BF1566E07FE188EC9EE00F94A417FE -:1096000080919F05882309F4C8CE4DCF80913F09F2 -:1096100010923F09882309F4DECE6091510970E071 -:10962000660F771F6E5D7D4F0EEB1EE127EE33E078 -:109630004AE050E083EC9EE00F94CC1680919F05A9 -:10964000882309F4C8CE2FCFEE24E394F12CE7CE83 -:1096500080913F0910923F09882309F4F1CEB701A8 -:10966000660F771F6E5D7D4F0AE81EE127EE33E03F -:109670004AE050E08CEB9EE00F94CC1680919F0561 -:10968000882309F4DDCE0FCFAF92BF92CF92DF9245 -:10969000EF92FF920F931F93CF93DF9361E081E0EE -:1096A0000E943223C091A10585E0B82EBC0ED5E002 -:1096B000DC1B14E01C1B83E0F82EFC1A82E0E82E71 -:1096C000EC1A81E0D82EDC1AAC2EA194C1112FC067 -:1096D000C090A005CC20A1F080917502882349F0AC -:1096E00081E0C11080E024E04DE65EE06A2D0F9439 -:1096F0001E15CF5FCB11EACF86E080939E050CC08C -:1097000080913F0910923F09882331F30E946C2E0B -:1097100080919F05882301F3DF91CF911F910F91D5 -:10972000FF90EF90DF90CF90BF90AF900895C13041 -:1097300089F58091A0058130D1F080917502882350 -:10974000C1F2CC24C3948091A005813009F0C12CD2 -:109750008091E8159091E9150E94C7BD00E09C0139 -:1097600048E55EE06D2D8C2D0E942048C2CF80918F -:109770003F0910923F09882301F346E756E268EE5D -:1097800075E188E59EE00F94141880919F05882369 -:10979000A1F2C2CFC23009F0A0C08091A0058230F2 -:1097A000C1F080917502882309F4A3CFCC24C3941F -:1097B0008091A005823009F0C12C8091AC15909168 -:1097C000AD150E94C7BD00E09C0146E55EE06E2D30 -:1097D000CACF80913F0910923F09882311F34EE6CA -:1097E00056E26CEA75E186E59EE00F9414188091CC -:1097F0009F058823B1F290CF8091A0058330C1F0FE -:1098000080917502882309F474CFCC24C39480918D -:10981000A005833009F0C12C8091701590917115CD -:109820000E94C7BD00E09C0144E55EE06F2D9BCF28 -:1098300080913F0910923F09882311F346E656E2D2 -:1098400060E775E184E59EE00F94141880919F0510 -:109850008823B1F261CF8091A0058430C1F080915E -:109860007502882309F445CFCC24C3948091A005C8 -:10987000843009F0C12C80913415909135150E94E7 -:10988000C7BD00E09C0141E55EE0612F6CCF809197 -:109890003F0910923F09882311F34EE556E264E335 -:1098A00075E181E59EE00F94141880919F0588234F -:1098B000B1F232CF80913F0910923F098823D1F055 -:1098C00046E556E268EF74E18EE49EE00F941418CA -:1098D00080919F05882371F01FCFC33009F48CCF8E -:1098E000C43009F4B8CFC53009F003CF8091A0058A -:1098F000853001F380917502882309F4FACECC24D7 -:10990000C3948091A005853009F0C12C8091F81492 -:109910009091F9140E94C7BD00E09C014EE45EE006 -:109920006D2F21CF7F928F929F92AF92BF92CF9255 -:10993000DF92EF92FF920F931F93CF93DF9361E03B -:1099400081E00E943223C091A1059C2E85E0A82EC3 -:10995000AC0ED1E011E093E0F92E86E0E82EEC1A8F -:1099600085E0D82EDC1A84E0C82ECC1A8F2C8C1AF5 -:1099700082E0B82EBC1A7D2E7C1AC1112FC0DD23C7 -:10998000D9F08091A0051816BCF040913B09509188 -:109990003C0960913D0970913E094F5F5F4F6F4FE9 -:1099A0007F4F40933B0950933C0960933D0970936E -:1099B0003E098F5F8093A00580917502882339F05E -:1099C00041E069E77EE0892D81950F949314CF5F84 -:1099D000AC12D3CF87E080939E0522C0C13071F5D1 -:1099E000D091A005D13081F080917502882351F08B -:1099F00081E0D13009F080E024E04DE65EE0672DA3 -:109A00000F941E15D0E0E3CF80913F0910923F09DB -:109A1000882351F30E946C2E80919F05882321F3A7 -:109A2000DF91CF911F910F91FF90EF90DF90CF903A -:109A3000BF90AF909F908F907F900895C23009F0B3 -:109A4000DEC08091A0058230C9F080917502882324 -:109A5000C9F281E09091A005923009F080E09091E8 -:109A6000EA1528E63EE0911102C024E63EE001E05E -:109A70004BE65EE06B2D0E942048C4CF80913F09E9 -:109A800010923F09882309F38091EA15812780937A -:109A9000EA15F09275020E94542680919F05882352 -:109AA000A1F2BECF80913F0910923F09882309F4AB -:109AB000AEC08091AE1581278093AE15C09375021C -:109AC0000E94522680919F05882309F4A0C0A8CF48 -:109AD000C43081F58091A0058430C1F08091750279 -:109AE000882309F48FCF81E09091A005943009F08C -:109AF00080E09091721528E63EE0911102C024E6C4 -:109B00003EE001E040E65EE06C2DB5CF80913F097C -:109B100010923F09882311F3809172158127809359 -:109B20007215F09275020E94502680919F0588233D -:109B3000A9F276CFC53081F58091A0058530C1F0BE -:109B400080917502882309F45DCF81E09091A00592 -:109B5000953009F080E09091361528E63EE09111AD -:109B600002C024E63EE001E04DE55EE06D2D83CFCE -:109B700080913F0910923F09882311F38091361597 -:109B8000812780933615F09275020E944E268091AF -:109B90009F058823A9F244CFC63009F018CF8091E1 -:109BA000A0058630C1F080917502882309F42ACF80 -:109BB00081E09091A005963009F080E09091FA1430 -:109BC00028E63EE0911102C024E63EE001E04AE5CD -:109BD0005EE06E2D50CF80913F0910923F0988239F -:109BE00011F38091FA1481278093FA14F092750290 -:109BF0000E944C2680919F058823A9F211CFC33083 -:109C000009F066CF8091A005833009F44BCF809195 -:109C10007502882309F4F6CE81E09091A005933077 -:109C200009F080E09091AE1528E63EE0911102C067 -:109C300024E63EE001E042E65EE0682D1CCF2F9274 -:109C40003F924F925F926F927F928F929F92AF92CC -:109C5000BF92CF92DF92EF92FF920F931F93CF9319 -:109C6000DF9300D0CDB7DEB78091470690914806CC -:109C700077247394892B39F480915E0690915F0666 -:109C8000892B09F4712C61E081E00E9432238091DC -:109C9000A1058A838B83982F9B5F9983382E3194FB -:109CA00083E0582EEA815E1A55E0452E66E6A62E20 -:109CB0006DE2B62E7DE1872E7EE0972EFA81F111BE -:109CC00012C01091A005112309F43DC180917502C5 -:109CD000882349F081E0111180E024E049E45EE04E -:109CE000632D0F941E154FE3C42E46E0D42EF12CA5 -:109CF000E12C662463942A808B81281AF6018085E2 -:109D000091859093370980933609FA81F61126C020 -:109D1000E092470910924B0910924A0910924909A2 -:109D2000109248098091A0058F1709F430C18091E5 -:109D30007502882399F011E08091A005861110E04A -:109D400080913609909137090E9492BD00E09C01F4 -:109D500040E45EE0622D812F0E942048862D9FEF17 -:109D6000E91AF90AE7E1CE0ED11C22E0622E823018 -:109D700029F6FA81F330E9F48091A005833009F4E3 -:109D800028C1809175028823A1F011E08091A0057F -:109D9000833009F010E080913606909137060E94DA -:109DA00092BD00E09C014CE35EE0652D812F0E9496 -:109DB00020488091D205809336098A81843041F50C -:109DC0001092470910924B0910924A0910924909C2 -:109DD000109248098091A005843009F415C1809142 -:109DE00075028823A9F0FA809B81F91A11E080910D -:109DF000A005EA818E1310E0809136090E942ABEE8 -:109E000000E09C0140E35EE06F2D812F0E9420481E -:109E10008091D30580933609FA814F1229C081E0E1 -:109E20008093470910924B0910924A0910924909F0 -:109E3000109248098091A005841509F4FAC0809118 -:109E400075028823A9F0FA809B81F91A11E08091AC -:109E5000A005EA818E1310E0809136090E942ABE87 -:109E600000E09C0140E35EE06F2D812F0E942048BE -:109E700096E0F92E09E11EE0E12CDA80FB81DF1A81 -:109E8000E09236098A818F1120C0F8018591949162 -:109E90001092470990934B0980934A0910924909FF -:109EA00010924809C090A0059A81C91609F4D9C03A -:109EB00080917502882349F081E0CF1080E023E093 -:109EC00046E25EE06D2D0F941E15CF2CF3940E5FCD -:109ED0001F4FE1E0EE12C2C0809136069091370626 -:109EE000892B11F4772031F1FA81FF121EC01091F5 -:109EF000A0051F1709F4C6C0809175028823A9F038 -:109F0000BF92AF929F928F928A819B81891B8F9380 -:109F100081E0EA811E1380E08F930E947D250F90DF -:109F20000F900F900F900F900F9082E0F82EFC0C86 -:109F300077247394FA81FF5FFA838981F813BECE88 -:109F4000F0929E050EC080913F0910923F09882330 -:109F500009F4BCCE0E946C2E80919F05882309F4E1 -:109F6000B5CE0F900F900F90DF91CF911F910F9171 -:109F7000FF90EF90DF90CF90BF90AF909F908F9029 -:109F80007F906F905F904F903F902F9008958091B9 -:109F90003F0910923F09882309F4C9CE0F94BF15D9 -:109FA000F701EE0FFF1FE054FD4F208131812F504C -:109FB00031090EE716E250E040E066E379E080E424 -:109FC0009EE00F94CC1680919F05882309F4AFCEB4 -:109FD000C8CF80913F0910923F09882309F4D1CE60 -:109FE0000F94BF1502E216EC24E630E050E040E0AA -:109FF00066E376E08CE39EE00F94CC1680919F059B -:10A00000882309F4BECEADCF80913F0910923F095D -:10A01000882309F4E4CE0F94BF1566E07FE180E366 -:10A020009EE00F94A41780919F05882309F4D7CE52 -:10A0300098CF80913F0910923F09882309F4FFCE01 -:10A040000F94BF1566E07FE180E39EE00F94A417B4 -:10A0500080919F05882309F4F2CE83CFEE24E39408 -:10A060000FCF80913F0910923F09882309F420CF38 -:10A0700084E19FE20E947D2480919F05882309F45A -:10A0800017CF6FCF80913F0910923F09882309F4C1 -:10A0900033CF0E94662D80919F05882309F42CCF31 -:10A0A00060CFCF92DF92EF92FF920F931F93CF93E7 -:10A0B000DF9361E081E00E943223C091A10585E039 -:10A0C000D82EDC0ED3E0DC1B12E01C1B81E0F82E46 -:10A0D000FC1ACC2EC194C1112DC0E090A005EE2039 -:10A0E000A1F080917502882349F081E0E11080E0C1 -:10A0F00024E04CEF5BE06C2D0F941E15CF5FCD116B -:10A10000EACF84E080939E050CC080913F091092B5 -:10A110003F09882331F30E946C2E80919F0588238C -:10A1200001F3DF91CF911F910F91FF90EF90DF909E -:10A13000CF900895C13069F58091A0058130C1F0BC -:10A14000809175028823D1F2EE24E3948091A005DA -:10A15000813009F0E12C809183160E9408BE00E056 -:10A160009C014EEE5BE06F2D8E2D0E942048C6CFE5 -:10A1700080913F0910923F09882311F363E876E14B -:10A180008EEE9BE00F94E81780919F058823C1F223 -:10A19000C8CFC230E1F58091A0058230B1F0809146 -:10A1A0007502882309F4AACFEE24E3948091A005D8 -:10A1B000823009F0E12C809184160E9408BE00E0F4 -:10A1C0009C014EED5BE0612FCFCF80913F09109253 -:10A1D0003F09882321F364E876E18EED9BE00F943C -:10A1E000E81780919F058823D1F29BCF80913F098A -:10A1F00010923F09882391F065E876E18FEC9BE0AF -:10A200000F94E81780919F05882341F08ACFC330CF -:10A2100009F074CF8091A005833041F380917502DD -:10A22000882309F46BCFEE24E3948091A00583305A -:10A2300009F0E12C809185160E9408BE00E09C0187 -:10A240004FEC5BE06D2F90CF5F926F927F928F9279 -:10A250009F92AF92BF92CF92DF92EF92FF920F93B5 -:10A260001F93CF93DF9361E081E00E943223C0917E -:10A27000A1056C2E85E0782E7C0ED4E0DC1B93E0EB -:10A28000892E582C5C1A21EFE22E2BECF22E34E2B0 -:10A29000C32E3CE0D32E12E01C1B4CE0A42E4CEC51 -:10A2A000B42E81E0982E9C1AC11113C00091A00514 -:10A2B000002329F180917502882309F4DFC0662DFF -:10A2C000619581E0011180E024E04AE35CE00F94B5 -:10A2D0001E1580910B0680933609C13009F055C0D8 -:10A2E0009091A005913039F180917502811138C0AB -:10A2F000CF5F7C12D9CF85E080939E050CC0809102 -:10A300003F0910923F098823A9F20E946C2E809188 -:10A310009F05882379F2DF91CF911F910F91FF90D4 -:10A32000EF90DF90CF90BF90AF909F908F907F90F5 -:10A330006F905F90089590913F0910923F09992383 -:10A3400099F28C278093360980927502A114B1048A -:10A3500011F00E940CCC80919F05882329F2DBCF5D -:10A3600081E09091A005913009F080E0909136094C -:10A3700020E33CE0911102C02CE23CE001E043E329 -:10A380005CE0692D0E942048B3CFC23071F5809106 -:10A39000A0058230D1F080917502882309F4A8CFFE -:10A3A000FF92EF92DF92CF921F9381E09091A005F0 -:10A3B000923009F080E08F930E947D250F900F90DE -:10A3C0000F900F900F900F9093CF80913F091092B4 -:10A3D0003F09882301F3E114F10411F00E94F1CB4D -:10A3E00080919F058823B9F296CFC33091F50091F3 -:10A3F000A005033081F080917502882309F478CF9D -:10A4000081E0033009F080E023E046E15CE0652D67 -:10A410000F941E156DCF80913F0910923F0988233C -:10A4200051F389E199E30E947D2480919F0588235F -:10A4300011F371CF80913F0910923F09882381F079 -:10A4400081E590E50E947D2480919F05882341F05D -:10A4500062CFC43009F04CCF0091A005043051F315 -:10A4600080917502882309F443CF81E0043009F01C -:10A4700080E023E048E05CE06D2FCACF80910B06BE -:10A480008093360935CF2F923F924F925F926F9211 -:10A490007F928F929F92AF92BF92CF92DF92EF9274 -:10A4A000FF920F931F93CF93DF9300D000D01F92A2 -:10A4B000CDB7DEB7482E662E809393056093920544 -:10A4C00020914709298361E081E00E943223709046 -:10A4D000A10527E1362D3202C0011124AC01495BF0 -:10A4E000594F6A01572C55E0570D5A833324339442 -:10A4F000832D87198D8333EDA32E3CE2B32E40EFDD -:10A50000842E49E0942EE62CF12CEE0CFF1CF70172 -:10A51000E054FD4F7F01562D5203A0011124495BE9 -:10A52000594F5F834E8371107FC03320D9F08091E3 -:10A53000A0051816BCF040913B0950913C09609170 -:10A540003D0970913E094F5F5F4F6F4F7F4F4093C2 -:10A550003B0950933C0960933D0970933E098F5F1E -:10A560008093A00580917502882389F083E063EDD4 -:10A5700079E0481639F094E063EC79E0491611F07F -:10A5800063EB79E043E0852D81950F94931409E105 -:10A590001EE022E0222EFEEFF70DFB83272D25196A -:10A5A0002C83721018C0F801859194913B813093EF -:10A5B000470990934B0980934A09109249091092D8 -:10A5C00048098091A005871509F46BC08091750238 -:10A5D000811176C0312C822D0E5F1F4F93E0292E02 -:10A5E0008330F9F654E0751214C060924709109256 -:10A5F0004B0910924A09109249091092480980911A -:10A60000A005843009F471C08091750281118AC05F -:10A61000312C7394FA81F71186CF85E080939E05E3 -:10A6200029812093470919C0E1E07E12B0CF109133 -:10A63000A005113031F080917502811127C0312CB5 -:10A64000A6CF80913F0910923F098823A1F30E9471 -:10A650006C2E80919F05882371F327960FB6F8948E -:10A66000DEBF0FBECDBFDF91CF911F910F91FF9045 -:10A67000EF90DF90CF90BF90AF909F908F907F90A2 -:10A680006F905F904F903F902F90089581E0113030 -:10A6900009F080E024E04AEF59E06D810F941E1527 -:10A6A000CECF80913F0910923F09882309F48ECFC5 -:10A6B0000E94D32C80919F05882309F487CFCDCFAA -:10A6C000BF92AF929F928F924C814F9381E0909175 -:10A6D000A005921180E08F930E947D250F900F902E -:10A6E0000F900F900F900F9075CF80913F091092AF -:10A6F0003F09882309F488CF0F94BF15F701208103 -:10A7000031812F5031090FED1CE24AEA50E0B601C9 -:10A7100081EE99E00F94CC1680919F05882309F46F -:10A7200073CF9BCF11E08091A005843009F010E039 -:10A73000EE81FF81808191810E9492BD64E0651964 -:10A7400000E09C0141EE59E0812F0E94204860CF3B -:10A750006091470984E00C9443526091470983E07B -:10A760000C9443526091470982E00C9443522F921B -:10A770003F924F925F926F927F928F929F92AF9291 -:10A78000BF92CF92DF92EF92FF920F931F93CF93DE -:10A79000DF9300D000D0CDB7DEB70E9462CD482E47 -:10A7A00061E081E00E9432232091A1052D834420A5 -:10A7B00069F185E08E837D80272D2B5F298385E0DD -:10A7C00087198A8384E087198B8383E087198C83B8 -:10A7D00082E0682E671881E0582E5718272C2194A4 -:10A7E0002D8121113BC01091A005112391F0809182 -:10A7F0007502882309F451C081E0111180E024E042 -:10A8000049ED58E0622D0F941E1547C096E09E83D7 -:10A81000D2CF80913F0910923F09882341F30E94D3 -:10A820006C2E80919F05882311F326960FB6F8941D -:10A83000DEBF0FBECDBFDF91CF911F910F91FF9073 -:10A84000EF90DF90CF90BF90AF909F908F907F90D0 -:10A850006F905F904F903F902F9008958D81813041 -:10A8600009F096C01091A005113009F47CC08091C8 -:10A870007502882391F01F9288EC98E09F938F9344 -:10A880005F9281E0113009F080E08F930E947D2576 -:10A890000F900F900F900F900F904110B1C02D812D -:10A8A000253009F0ADC01091A005153009F402C1A2 -:10A8B0008091750281110FC116E081E0810F9D81A9 -:10A8C000891314C03090A005391609F42CC1809169 -:10A8D0007502882359F06D81671981E02D8132124C -:10A8E00080E023E04CE758E00F941E1582E0810FD2 -:10A8F0009D81891314C03090A005391609F424C134 -:10A9000080917502882359F06D81671981E02D814E -:10A91000321280E023E043E758E00F941E1583E0F5 -:10A92000810F9D81891315C09091A0052D819217EB -:10A9300009F41BC180917502882359F06D81671954 -:10A9400081E02D81921380E023E041E658E00F94EE -:10A950001E158D818F5F8D839981981341CF1C5F68 -:10A9600010939E0562CF80913F0910923F09882382 -:10A9700009F47DCF8CE598E09093F3088093F2087A -:10A980000E945E2D80919F05882309F470CF4DCFE2 -:10A990008D81823009F012C11091A005123071F042 -:10A9A00080917502882309F478CF81E0123009F094 -:10A9B00080E023E047EB58E0662D25CF80913F09EA -:10A9C00010923F09882361F383E69AE50E947D2473 -:10A9D00080919F05882321F328CF1091A005133083 -:10A9E000F1F080917502882309F457CF81E013308C -:10A9F00009F080E023E04AEA58E06C810F941E15CC -:10AA00008E819D81891309C01091A005181709F442 -:10AA10006DC08091750281117AC01E814ECF8091E8 -:10AA20003F0910923F098823E1F28CE09CE50E94E7 -:10AA30007D2480919F058823A1F2F7CE80913F0964 -:10AA400010923F09882309F4C6C020E030E04AE7AD -:10AA500054E46091FE057091FF058091000690918D -:10AA600001060F94173A20E030E040E85FE30F94CE -:10AA7000073E0F947B3F1F92912C812C8AE1A82ED8 -:10AA800088E4B82E6B011BE2E12EFF24F39400E072 -:10AA900010E021E030E040E050E06EEF75E08DE93D -:10AAA00098E00E94EB2C0F9080919F05882309F479 -:10AAB00092C0BBCE80913F0910923F09882309F4D0 -:10AAC000F7CE84E19FE50E947D2480919F05882335 -:10AAD00009F4EECEAACE81E0153009F080E023E043 -:10AAE00044E958E06A810F941E15E6CE80913F0933 -:10AAF00010923F09882309F48CCF8DE89EE20E94D2 -:10AB00007D2480919F05882309F483CF8ECE6D81AB -:10AB1000671981E02D81121380E023E048E858E0B6 -:10AB20000F941E157ACF80913F0910923F09882318 -:10AB300009F4CDCE84E693E60E947D2480919F05A2 -:10AB4000882309F4C4CE71CE80913F0910923F0949 -:10AB5000882309F4D5CE83E790E60E947D24809176 -:10AB60009F05882309F4CCCE60CE80913F091092D6 -:10AB70003F09882309F4DECE0E94532420E040E000 -:10AB800070E060E088EC96E226960FB6F894DEBF9F -:10AB90000FBECDBFDF91CF911F910F91FF90EF902E -:10ABA000DF90CF90BF90AF909F908F907F906F90ED -:10ABB0005F904F903F902F900C9493232D812330E2 -:10ABC00009F40BCF243009F068CE3090A00594E052 -:10ABD000391609F433CF80917502882309F45DCECC -:10ABE0006091FE057091FF0580910006909101062D -:10ABF0000E94E6219C0181E094E0391280E000E0AF -:10AC00004DE958E06B810E942048FACE2F923F9286 -:10AC10004F925F926F927F928F929F92AF92BF926C -:10AC2000CF92DF92EF92FF920F931F93CF93DF9318 -:10AC300000D0CDB7DEB761E081E00E9432232091E1 -:10AC4000A1052A832B5F298384E09A81891B8B834A -:10AC500066246394B2E05B2E83E0782E791A452C4B -:10AC6000491A362C391A292E21942A8121113DC0E6 -:10AC70001091A0051123B9F080917502882349F045 -:10AC800081E0111180E024E041E159E0622D0F9450 -:10AC90001E159A819F5F9A8329819213E6CF85E0E2 -:10ACA00080939E050CC080913F0910923F09882334 -:10ACB00019F30E946C2E80919F058823E9F20F9072 -:10ACC0000F900F90DF91CF911F910F91FF90EF9018 -:10ACD000DF90CF90BF90AF909F908F907F906F90BC -:10ACE0005F904F903F902F9008958A81813009F0B6 -:10ACF0006BC01092470910924B0910924A091092AA -:10AD00004909109248098091A0058130F1F08091A5 -:10AD10007502882309F4BDCF11E08091A005813030 -:10AD200009F010E060917A0670917B0680917C06B4 -:10AD300090917D060E94651F00E09C014FEE58E057 -:10AD4000632D812F0E942048A4CF80913F0910924B -:10AD50003F098823E1F20F94BF1520E030E048EC72 -:10AD600052E460917A0670917B0680917C06909106 -:10AD70007D060F94173A20E030EB4AE156E40F9439 -:10AD8000083E0F947B3F1F92E3EF8E2EE0E29E2E53 -:10AD9000F0EFAF2EF7E4BF2E6B0118E5E12E1DE4B6 -:10ADA000F12E00E010E024E539ED4FEF5FEF6AE7A8 -:10ADB00076E08FEE98E00E94EB2C0F9080919F053B -:10ADC000882309F4A4CF7BCF9A81923009F0DDC0AB -:10ADD0006092470910924B0910924A091092490952 -:10ADE000109248098091A0058230D9F080917502B7 -:10ADF000882309F44ECF11E08091A005823009F03C -:10AE000010E060917E0670917F068091800690919F -:10AE100081060E94651F00E09C014FEE58E0642D02 -:10AE200090CF80913F0910923F098823F9F20F9447 -:10AE3000BF1520E030E048EC52E460917E0670914E -:10AE40007F0680918006909181060F94173A20E04A -:10AE500030EB4AE156E40F94083E0F947B3F1F927B -:10AE600033EF832E30E2932E40EFA42E47E4B42E2E -:10AE70006B0118E5E12E1DE4F12E00E010E024E561 -:10AE800039ED4FEF5FEF6EE776E08FEE98E00E94CE -:10AE9000EB2C0F9080919F05882309F4A7CF0FCF4B -:10AEA0005092470910924B0910924A091092490991 -:10AEB000109248098091A0058330D9F080917502E5 -:10AEC000882309F4E6CE11E08091A005833009F0D3 -:10AED00010E06091820670918306809184069091C3 -:10AEE00085060E94651F00E09C014FEE58E0672D2B -:10AEF00028CF80913F0910923F098823F9F20F94DF -:10AF0000BF1520E030E048EC52E460918206709179 -:10AF1000830680918406909185060F94173A20E06D -:10AF200030E048E453E40F94083E0F947B3F1F92B7 -:10AF300083EF882E80E2982E90EFA92E97E4B92E09 -:10AF40006B0110EBE12E14E0F12E00E010E028E39D -:10AF50003FEF4FEF5FEF62E876E08FEE98E00E9400 -:10AF6000EB2C0F9080919F05882309F4A7CFA7CEE3 -:10AF700080913F0910923F09882391F00E94D92BBC -:10AF800080919F05882361F09ACE8A81833009F4ED -:10AF900087CF843009F07DCE8091A005843041F3C5 -:10AFA00080917502882309F474CE89ED9BE29F930A -:10AFB0008F938EE399E09F938F938B818F9381E0A2 -:10AFC0009091A005943009F080E08F930E947D2538 -:10AFD0000F900F900F900F900F900F905ACE5F929E -:10AFE0006F927F928F929F92AF92BF92CF92DF9299 -:10AFF000EF92FF920F931F93CF93DF9361E081E075 -:10B000000E943223C091A10525E0722E7C0ED1E072 -:10B01000DC1B6C2E6194C11134C01091A00511236A -:10B02000A1F080917502882349F081E0111180E040 -:10B0300024E041E159E0662D0F941E15CF5F7C128C -:10B04000EACF82E080939E050CC080913F09109268 -:10B050003F09882331F30E946C2E80919F0588233D -:10B0600001F3DF91CF911F910F91FF90EF90DF904F -:10B07000CF90BF90AF909F908F907F906F905F9098 -:10B080000895C130D9F65090A00581E0581609F412 -:10B0900047C080917502882389F211E0511210E0B7 -:10B0A000C0908606D0908706E0908806F0908906CA -:10B0B00020E030E0A901C701B6010F94B1392DEBB2 -:10B0C00037E346E055EB87FD04C02DEB37E346E060 -:10B0D00055E3C701B6010F94083E6B017C0120E0E7 -:10B0E00030E0A9010F94B13920E030E040E05FEB9F -:10B0F00087FD04C020E030E040E05FE3C701B60117 -:10B100000F94083E0F94743FCB010E9492BD00E063 -:10B110009C0147EE58E06D2F812F0E9420488ECF72 -:10B1200080913F0910923F09882309F4B2CF6091C2 -:10B1300086067091870680918806909189060F9403 -:10B140007B3F1F92912C812C8AEEA82E87E4B82E8B -:10B150006B011AE0E12EF12C00E010E020E030E07D -:10B16000A90166E876E087EE98E00E94EB2C0F904C -:10B1700080919F05882309F48CCF73CF2F923F9243 -:10B180004F925F926F927F928F929F92AF92BF92F7 -:10B19000CF92DF92EF92FF920F931F93CF93DF93A3 -:10B1A00000D000D01F921F92CDB7DEB72091470983 -:10B1B000288761E081E00E9432233091A1053F831E -:10B1C000E8858E2F90E0880F991F9C01275E314FF4 -:10B1D0003C832B8336E0E39FC0011124FC01EC503B -:10B1E000FA4FFA83E9839C012E503A4F79015F8030 -:10B1F00035E0432E450C11E0312E3518252C2194D5 -:10B20000FE82ED82570134E0A30EB11C49EDC42E3D -:10B210004BE2D42E85E0782E75184701E2E08E0EC1 -:10B22000911C82E0682E6518FF81F11161C0112325 -:10B23000D9F08091A0051816BCF040913B095091BF -:10B240003C0960913D0970913E094F5F5F4F6F4F20 -:10B250007F4F40933B0950933C0960933D097093A5 -:10B260003E098F5F8093A00580917502882341F08D -:10B27000EB81FC816591749143E0822D0F949314CE -:10B28000F501808180933609FF81F23009F080C09A -:10B2900028852093470910924B0910924A09109271 -:10B2A0004909109248098091A005823009F45DC0D7 -:10B2B00080917502882391F011E08091A005823081 -:10B2C00009F010E0809136090E942ABE00E09C013E -:10B2D00047E059E0662D812F0E94204810E02F8121 -:10B2E0002F5F2F834212A0CF86E080939E0519C066 -:10B2F0002F81213029F61091A005113031F0809175 -:10B300007502811127C010E0BBCF80913F091092D8 -:10B310003F098823A1F30E946C2E80919F0588230A -:10B3200071F328960FB6F894DEBF0FBECDBFDF9144 -:10B33000CF911F910F91FF90EF90DF90CF90BF9032 -:10B34000AF909F908F907F906F905F904F903F90C5 -:10B350002F90089581E0113009F080E024E041E170 -:10B3600059E0632D0F941E15CECF80913F091092A6 -:10B370003F09882309F49CCF65EE70E287E099E0ED -:10B380000F94A41780919F05882309F491CFC9CF0A -:10B390003F81333091F58091A0058330C1F08091D9 -:10B3A0007502882309F49ACF11E08091A0058330BB -:10B3B00009F010E0ED81FE81808191810E9492BDB3 -:10B3C00063E0651900E09C0140E059E084CF809182 -:10B3D0003F0910923F09882311F310E000E025EFA8 -:10B3E00030E045E050E0B70180E099E00F94CC16E2 -:10B3F00080919F05882399F294CFFF81F43091F5D5 -:10B400008091A0058430B9F080917502882309F4F9 -:10B4100065CF11E08091A005843009F010E0F401BF -:10B42000808191810E9492BD64E0651900E09C01D9 -:10B430004CEF58E050CF80913F0910923F0988238C -:10B4400019F310E000E024E630E045E050E06981C7 -:10B450007A818CEF98E00F94CC1680919F05882319 -:10B4600099F25FCFFF81F53009F039CF8091A005C7 -:10B470008530E1F080917502882309F42FCFDF92A7 -:10B48000CF928EE399E09F938F937F9281E090918A -:10B49000A005953009F080E08F930E947D250F90E4 -:10B4A0000F900F900F900F900F9018CF80913F0941 -:10B4B00010923F098823F1F20E94D92B80919F05B9 -:10B4C0008823C1F22ECF5F926F927F928F929F92CC -:10B4D000AF92BF92CF92DF92EF92FF920F931F93A2 -:10B4E000CF93DF93CDB7DEB760970FB6F894DEBF8A -:10B4F0000FBECDBF80E1ECE8F2E0DE0111960190D5 -:10B500000D928A95E1F761E081E00E943223D090AC -:10B51000A1059D2C65E0862E8D0C7D2C719473E029 -:10B52000672ED11012C01091A005112309F4CEC0CE -:10B5300080917502882349F081E0111180E024E0B8 -:10B540004CE358E0672D0F941E15AA24A394B12C48 -:10B550005D2C5918DA102FC08FEF8A0D80934709A0 -:10B5600010924B0910924A09109249091092480909 -:10B570008091A0058D1509F4CDC0809175028823B6 -:10B58000D1F011E08091A0058D1110E0F501EE0FD2 -:10B59000FF1FEE0FFF1FEB5AF64F60A171A182A1B2 -:10B5A00093A10E94F52700E09C014CEE57E0652D29 -:10B5B000812F0E942048CA2C81E08A0D9FEFA91A92 -:10B5C000B90A94E0A916B10429F68D112CC0609235 -:10B5D000470910924B0910924A091092490910929A -:10B5E00048098091A0058D1509F4BEC080917502AF -:10B5F0008823C9F0BD2CB91811E08091A0058D11E8 -:10B6000010E0609185097091860980918709909179 -:10B6100088090E94F52700E09C014CEE57E06B2D55 -:10B62000812F0E94204882E08C0D8D1122C08091D4 -:10B63000A0058D1509F4B6C0809175028823C9F064 -:10B64000BD2CB91811E08091A0058D1110E060911A -:10B6500095097091960980919709909198090E9497 -:10B66000F52700E09C014FED57E06B2D812F0E94E4 -:10B67000204883E08C0D8D1121C08091A0058D158F -:10B6800009F4ADC0809175028823C1F011E080916A -:10B69000A0058D1110E06091990970919A0980912F -:10B6A0009B0990919C090E94F52700E09C014EECBB -:10B6B00057E06D2D6919812F0E942048D3948D1079 -:10B6C00030CF84E08C0D80939E050EC080913F09A1 -:10B6D00010923F09882309F42BCF0E946C2E809191 -:10B6E0009F05882309F424CF60960FB6F894DEBF37 -:10B6F0000FBECDBFDF91CF911F910F91FF90EF90C3 -:10B70000DF90CF90BF90AF909F908F907F906F9081 -:10B710005F90089580913F0910923F09882309F4B2 -:10B720002CCF0F94BF15B501660F771F660F771FDB -:10B73000FB01349781E090E08C0F9D1FE80FF91F0B -:10B74000E080F180028113816B58764F20E030E079 -:10B7500040E85FE38CEE97E00F94CB1580919F0556 -:10B76000882309F40ACFC0CF80913F0910923F0986 -:10B77000882309F43BCF0F94BF15E12C1CE3F12E75 -:10B780000CE116E420E030E040E85FE365E879E0B2 -:10B790008CEE97E00F94CB1580919F05882309F4D8 -:10B7A00025CFA2CF80913F0910923F09882309F449 -:10B7B00043CF0F94BF15E12C1CE3F12E0CE116E4EE -:10B7C00020E030E0A90165E979E08FED97E00F9482 -:10B7D000CB1580919F05882309F42ECF85CF8091CA -:10B7E0003F0910923F09882309F44CCF0F94BF15ED -:10B7F000E12C1CE3F12E0CE116E420E030E0A9017D -:10B8000069E979E08EEC97E00F94CB1580919F0564 -:10B81000882309F437CF68CF2F923F924F925F92DF -:10B820006F927F928F929F92AF92BF92CF92DF9250 -:10B83000EF92FF920F931F93CF93DF93CDB7DEB7B5 -:10B840002C970FB6F894DEBF0FBECDBFC09059093C -:10B85000D0905A09E0905B09F0905C0980915D09F5 -:10B8600090915E09A0915F09B09160098C159D05CA -:10B87000AE05BF0510F4D701C601C0905509D090A0 -:10B880005609E0905709F0905809BC01CD016C159C -:10B890007D058E059F0510F4C701B6010F94B639DA -:10B8A0002B013C0161E081E00E9432232091A1053F -:10B8B0002C872E83822F8B5F8D8387E0821B8F8363 -:10B8C00086E0821B888785E0821B898784E0821B53 -:10B8D0008A8783E0821B8B8742E0242E221A322E35 -:10B8E00031942C85211140C01091A0051123B9F08D -:10B8F00080917502882349F081E0111180E024E0F5 -:10B900004CE358E0632D0F941E159C859F5F9C8728 -:10B910002D812913E6CF88E080939E050CC080918D -:10B920003F0910923F09882319F30E946C2E8091E1 -:10B930009F058823E9F22C960FB6F894DEBF0FBE60 -:10B94000CDBFDF91CF911F910F91FF90EF90DF90CE -:10B95000CF90BF90AF909F908F907F906F905F90AF -:10B960004F903F902F9008958C85813009F081C0D1 -:10B970008091A0058130F9F080917502882329F229 -:10B9800011E08091A005813009F010E060918909F3 -:10B9900070918A0980918B0990918C090E94F527FA -:10B9A00061E02E81621B00E09C014BE258E0812F98 -:10B9B0000E942048AACF80913F0910923F09882316 -:10B9C000D9F20F94BF152AE037ED43E25DE3C301DE -:10B9D000B2010F94173A4B015C0120E030E040E0E7 -:10B9E0005FE40F94B13987FD05C0812C912CA12C07 -:10B9F0003FE4B32E2AE037ED43E25DE3609189092D -:10BA000070918A0980918B0990918C090F94173A53 -:10BA100020E030E040E85FE30F94073E0F947B3F67 -:10BA200069837A838B839C83C501B4010F94743F2F -:10BA30007B018C0121E0E21AF108010911091F9232 -:10BA4000912C812C22E0A22E28E4B22EC980DA802B -:10BA500021E030E040E050E069E879E08BE298E0F6 -:10BA60000E94EB2C0F9080919F05882309F484CFCE -:10BA700062CF8C85823009F0A6C18091A00582300A -:10BA8000D9F080917502882309F43FCF11E08091AD -:10BA9000A005823009F010E060918D0970918E0947 -:10BAA00080918F09909190090E94F52700E09C01F8 -:10BAB0004DE158E0622D7BCF80913F0910923F0904 -:10BAC0008823F9F20F94BF156091610970916209A2 -:10BAD00080916309909164090F94B6397B018C01C0 -:10BAE00020E030E048EC52E46DE879E08DE198E048 -:10BAF0000F94CB1580919F05882319F21CCF80915C -:10BB0000A0058330D9F080917502882309F4FDCE19 -:10BB100011E08091A005833009F010E06091910957 -:10BB20007091920980919309909194090E94F52750 -:10BB300000E09C0140E158E06B8539CF80913F09DE -:10BB400010923F098823F9F20F94BF152AE037EDD0 -:10BB500043E25DE3C301B2010F94173A4B015C016C -:10BB600020E030E040E05FE40F94B13987FD05C08C -:10BB7000812C912CA12C9FE4B92E2AE037ED43E2D1 -:10BB80005DE3609191097091920980919309909180 -:10BB900094090F94173A20E030E040E85FE30F94F7 -:10BBA000073E0F947B3F69837A838B839C83C50117 -:10BBB000B4010F94743F7B018C0121E0E21AF1087B -:10BBC000010911091F92912C812C82E0A82E88E492 -:10BBD000B82EC980DA8021E030E040E050E061E931 -:10BBE00079E080E198E00E94EB2C0F9080919F0516 -:10BBF000882309F488CF9FCE1092470910924B09F1 -:10BC000010924A0910924909109248098091A005A2 -:10BC10008430E9F080917502882309F476CE11E032 -:10BC20008091A005843009F010E060915509709171 -:10BC3000560980915709909158090F94B6390E947E -:10BC4000D22700E09C0144E058E06A85B0CE8091A4 -:10BC50003F0910923F098823E9F20F94BF150CE7C2 -:10BC600018E224E630E040E050E065E579E084E069 -:10BC700098E00F94541680919F05882359F25BCE6B -:10BC800081E08093470910924B0910924A09109263 -:10BC90004909109248098091A0058530E9F080910A -:10BCA0007502882309F431CE11E08091A00585301A -:10BCB00009F010E06091590970915A0980915B096F -:10BCC00090915C090F94B6390E94D22700E09C0144 -:10BCD00044E058E069856BCE80913F0910923F099E -:10BCE0008823E9F20F94BF150AE718E224E630E052 -:10BCF00040E050E069E579E084E098E00F94541664 -:10BD000080919F05882359F216CE82E080934709DF -:10BD100010924B0910924A09109249091092480951 -:10BD20008091A0058630E9F080917502882309F49E -:10BD3000ECCD11E08091A005863009F010E0609113 -:10BD40005D0970915E0980915F09909160090F947F -:10BD5000B6390E94D22700E09C0144E058E0688593 -:10BD600026CE80913F0910923F098823E9F20F9473 -:10BD7000BF1508E718E22AE030E040E050E06DE54A -:10BD800079E084E098E00F94541680919F05882311 -:10BD900059F2D1CD80913F0910923F09882339F1A2 -:10BDA0000F94BF1506E718E224E630E040E050E0CB -:10BDB00061E679E088EF97E00F94541680919F0533 -:10BDC0008823A9F0B8CD8C85833009F498CE8430CF -:10BDD00009F412CF853009F453CF863009F495CF9A -:10BDE000873009F092CD8091A005873099F280913B -:10BDF0007502882309F489CD11E08091A005873070 -:10BE000009F010E060916109709162098091630905 -:10BE1000909164090F94B6390E94D22700E09C01EA -:10BE200048EF57E06F81C3CD2F923F924F925F92C0 -:10BE30006F927F928F929F92AF92BF92CF92DF923A -:10BE4000EF92FF920F931F93CF93DF9300D01F9237 -:10BE50001F92CDB7DEB761E081E00E94322380916E -:10BE6000A1058C838A83982F9B5F9983E82FE195A6 -:10BE7000EB8384E0482EFC814F1A8C81811114C021 -:10BE80009091A0059D83992309F489C08091750242 -:10BE9000882351F081E0ED81E11180E024E04CE362 -:10BEA00058E06B810F941E1565E5662E69E0762ECD -:10BEB000F1E0FD833C803A942C808A81281A9C8191 -:10BEC000ED819E1328C03092470910924B091092C1 -:10BED0004A0910924909109248098091A0058917D2 -:10BEE00009F483C0809175028823A9F011E0809144 -:10BEF000A005FD818F1310E0F3016489758986899F -:10BF000097890E94052100E09C0141E358E0622DE1 -:10BF1000812F0E9420485D80F4E06F0E711C81E04B -:10BF2000850D8D83843059F69C81943069F5E3E06A -:10BF3000E093470910924B0910924A09109249095F -:10BF4000109248098091A005843009F48CC080913A -:10BF500075028823C9F0F1E0FD838091A00584304B -:10BF600009F01D82609175097091760980917709B9 -:10BF7000909178090E94052100E09C0141E358E07E -:10BF8000642D8D810E9420488C818F5F8C839981E4 -:10BF9000981373CF5394539450929E050EC0809182 -:10BFA0003F0910923F09882309F470CF0E946C2E3C -:10BFB00080919F05882309F469CF0F900F900F900F -:10BFC0000F900F90DF91CF911F910F91FF90EF9005 -:10BFD000DF90CF90BF90AF909F908F907F906F90A9 -:10BFE0005F904F903F902F90089580913F0910925D -:10BFF0003F09882309F476CF0F94BF1520E030E085 -:10C0000040E251E4F30164897589868997890F9428 -:10C01000173A20E030E048E452E40F94073E0F94D2 -:10C020007B3F1F9234E7832E38E2932E46EFA42EF7 -:10C0300047E4B42E6B0114E6E12E16E8F12E01E080 -:10C0400010E022E330E040E050E0B3016C5E7F4F4F -:10C0500081E398E00E94EB2C0F9080919F0588234C -:10C0600009F440CFAACF80913F0910923F0988235D -:10C0700009F46DCF0F94BF1520E030E040E251E4A9 -:10C08000609175097091760980917709909178098E -:10C090000F94173A20E030E048E452E40F94073E52 -:10C0A0000F947B3F1F9282E7882E88E2982E96EFAE -:10C0B000A92E97E4B92E6B0114E6E12E16E8F12EB5 -:10C0C00001E010E022E330E040E050E065E779E095 -:10C0D00081E398E00E94EB2C0F9080919F058823CC -:10C0E00009F435CF6ACF2F923F924F925F926F92B1 -:10C0F0007F928F929F92AF92BF92CF92DF92EF92F8 -:10C10000FF920F931F93CF93DF9300D000D0CDB752 -:10C11000DEB761E081E00E9432232091A1052D83EA -:10C120002E83322F3B5F398381E0922F821B8A83DB -:10C1300091959B8382E0821B8C83FD81F11185C1E7 -:10C140001091A005112309F459C18091750288232B -:10C1500049F081E0111180E024E04CE358E06B816C -:10C160000F941E158091F105882309F437C2FD81D3 -:10C17000F23029F58091A005823009F4A2C18091A6 -:10C1800075028823E1F011E08091A005823009F06A -:10C1900010E0E091510924E0E29FF0011124E75101 -:10C1A000FA4F60817181828193810E94E62100E0D3 -:10C1B0009C0144E957E06C81812F0E942048712C3A -:10C1C000612C13E0312E2D803E81231A8D81831145 -:10C1D0002EC06092470910924B0910924A091092A2 -:10C1E0004909109248098091A0059D81891709F499 -:10C1F000B1C1809175028823D1F011E08091A00532 -:10C20000831110E0F301EE0FFF1FEE0FFF1FE75148 -:10C21000FA4F60817181828193810E94E62100E062 -:10C220009C0148E857E0622D812F0E942048FFEFD3 -:10C230006F1A7F0A24E032128AC115E03D81131380 -:10C2400029C08091A005811709F4CAC180917502A7 -:10C25000882301F16D809E81691A772473948091FF -:10C26000A005ED818E13712CE091510928E0E29F29 -:10C27000F0011124E752FA4F60817181828193812C -:10C280000E94362800E09C014EE757E0662D872D7E -:10C290000E94204844244394410E712C612C3D801F -:10C2A0003E81331A8D8184112FC06092470910920C -:10C2B0004B0910924A09109249091092480980913D -:10C2C000A0059D81891709F4AAC180917502882370 -:10C2D000D9F011E08091A005841110E0F30133E062 -:10C2E000EE0FFF1F3A95E1F7E752FA4F6081718137 -:10C2F000828193810E94362800E09C0145E757E047 -:10C30000632D812F0E942048542C44244394450CD3 -:10C310006A94672809F07FC1FD814F1228C080917F -:10C32000A0058F1709F496C1809175028823F9F052 -:10C330007D803E81731A11E08091A0059D81891353 -:10C3400010E0E091510928E0E29FF0011124E7524A -:10C35000FA4F64817581868197810E94362800E0BA -:10C360009C014DE657E0672D812F0E942048539491 -:10C370005394712C612C4D803E81431A8D8185111F -:10C380002FC06092470910924B0910924A091092EF -:10C390004909109248098091A0059D81891709F4E7 -:10C3A00078C1809175028823D9F011E08091A005B1 -:10C3B000851110E0F30183E0EE0FFF1F8A95E1F78E -:10C3C000E752FA4F64817581868197810E943628F1 -:10C3D00000E09C0146E657E0642D812F0E94204832 -:10C3E00053946A94672809F050C1FD81FF5FFD8373 -:10C3F00029812F13A2CE50929E050EC080913F0935 -:10C4000010923F09882309F4A0CE0E946C2E8091DF -:10C410009F05882309F499CE26960FB6F894DEBFBF -:10C420000FBECDBFDF91CF911F910F91FF90EF9085 -:10C43000DF90CF90BF90AF909F908F907F906F9044 -:10C440005F904F903F902F9008952D81213009F0FB -:10C4500089CE8091A0058130D1F08091750288232A -:10C4600009F480CE81E09091A005913009F080E040 -:10C470009091F10522EC37E0911102C02EEB37E0EC -:10C4800001E04EE957E06A810E9420486BCE80911E -:10C49000F10590913F0910923F099923F1F23D81F6 -:10C4A00083278093F10583E080937502E7EEF1E73F -:10C4B000EF2B11F00E94E77180919F05882369F2AC -:10C4C000ABCF80913F0910923F09882309F457CEE2 -:10C4D0000F94BF156090510924E0629E3001112431 -:10C4E000C30187519A4F3C0120E030E04AE754E411 -:10C4F000FC0160817181828193810F94173A20E061 -:10C5000030E84BEB54E40F94073E0F947B3F1F92AF -:10C5100007EE802E01E7902E8AE1A82E88E4B82E3F -:10C520006B0116EDE12E16E0F12E00E010E02CED8F -:10C5300035E040E050E0B30184E997E00E94EB2C45 -:10C540000F9080919F05882309F419CE65CFB4E040 -:10C550003B2E3CCE80913F0910923F09882309F47D -:10C5600048CE0F94BF15C301880F991F880F991FDC -:10C57000FC01E751FA4F2F0120E030E04AE754E494 -:10C5800060817181828193810F94173A20E030E8B5 -:10C590004BEB54E40F94073E0F947B3F1F92E7EE62 -:10C5A0008E2EE1E79E2EFAE1AF2EF8E4BF2E6B014E -:10C5B00016EDE12E16E0F12E00E010E02CED35E056 -:10C5C00040E050E0B20188E897E00E94EB2C0F9029 -:10C5D00080919F05882309F40CCE1ECF12E02ECE49 -:10C5E00080913F0910923F09882309F42FCE0F94C0 -:10C5F000BF156091510988E0689FB001112467520E -:10C600007A4F8EE797E00F946A1780919F058823F1 -:10C6100009F41CCE01CF66246394712C43CE809123 -:10C620003F0910923F09882309F44FCE0F94BF159C -:10C63000B30143E0660F771F4A95E1F767527A4FDF -:10C6400085E797E00F946A1780919F05882309F486 -:10C650003CCEE2CE80913F0910923F09882309F435 -:10C6600063CE0F94BF156091510928E0629FB0011D -:10C67000112463527A4F8DE697E00F946A178091E8 -:10C680009F05882309F450CEC7CE66246394712C8D -:10C6900075CE80913F0910923F09882309F481CE1D -:10C6A0000F94BF15B30193E0660F771F9A95E1F7DA -:10C6B00063527A4F86E697E00F946A1780919F0540 -:10C6C000882309F46ECEA8CE2F923F924F925F92AC -:10C6D0006F927F928F929F92AF92BF92CF92DF9292 -:10C6E000EF92FF920F931F93CF93DF9300D0CDB7BC -:10C6F000DEB761E081E00E9432232091A1052A8308 -:10C700002B5F298384E09A81891B8B8323E0522E3F -:10C71000352C391A82E0782E791A81E0682E691A50 -:10C72000292E21942A8121113DC01091A0051123A9 -:10C73000B9F080917502882349F081E0111180E001 -:10C7400024E04CE358E0622D0F941E152A812F5FE0 -:10C750002A8389812813E6CF85E080939E050CC04B -:10C7600080913F0910923F09882319F30E946C2E93 -:10C7700080919F058823E9F20F900F900F90DF9131 -:10C78000CF911F910F91FF90EF90DF90CF90BF90CE -:10C79000AF909F908F907F906F905F904F903F9061 -:10C7A0002F9008958A81813071F59091A005913084 -:10C7B000B9F080917502882349F281E0913009F047 -:10C7C00080E090916D0622EC37E0911102C02EEBD3 -:10C7D00037E001E045EC57E0662D0E942048B6CFD7 -:10C7E00080913F0910923F09882319F380916D06CB -:10C7F0002A81822780936D065092750280919F0551 -:10C800008823B9F2B9CF8A81823009F098C080912B -:10C81000A0058230C1F080917502882309F496CF7B -:10C8200011E08091A005823009F010E0809118029B -:10C83000909119020E9492BD00E09C0147EB57E0E5 -:10C84000672D812FCACF80913F0910923F0988231D -:10C8500011F310E000E025EF30E050E040E068E147 -:10C8600072E087EB97E00F94CC1680919F058823A8 -:10C8700091F282CF8091A0058330B9F0809175024A -:10C88000882309F463CF11E08091A005833009F07B -:10C8900010E080911602909117020E9492BD00E074 -:10C8A0009C0140EB57E0632DCCCF80913F09109263 -:10C8B0003F09882319F310E000E025EF30E050E055 -:10C8C00040E066E172E080EB97E00F94CC16809137 -:10C8D0009F05882399F250CF80913F0910923F091C -:10C8E0008823C9F120E030E048EC52E46091120264 -:10C8F0007091130280911402909115020F94173ACF -:10C900000F947B3F1F92912C812C80EFA82E87E4FF -:10C91000B82E6B0118EEE12E13E0F12E00E010E0CE -:10C9200020E030E0A90162E172E088EA97E00E942D -:10C93000EB2C0F9080919F05882369F01DCF9A8181 -:10C94000933009F497CF943009F000CF4090A005C0 -:10C9500094E0491609F280917502882309F4F6CE15 -:10C96000609112027091130280911402909115024D -:10C970000E94651F9C0181E094E0491280E000E084 -:10C9800048EA57E06B8129CFE5E4F6E183AF64AF75 -:10C990006FEF7FEFCA010C947FC72F923F924F92A7 -:10C9A0005F926F927F928F929F92AF92BF92CF923F -:10C9B000DF92EF92FF920F931F93CF93DF9300D0FC -:10C9C00000D01F921F92CDB7DEB710924509E091BB -:10C9D0001712F0911812309721F0199581110F94C8 -:10C9E0008E1080913F0910923F09882319F120E0B1 -:10C9F00040E070E060E08EE89BE30E9493230E9499 -:10CA0000DE3F28960FB6F894DEBF0FBECDBFDF9194 -:10CA1000CF911F910F91FF90EF90DF90CF90BF903B -:10CA2000AF909F908F907F906F905F904F903F90CE -:10CA30002F90089580919705882309F434C260915E -:10CA4000470670914806072E000C880B990B0F942F -:10CA5000B83911E0209143063091440640914506D3 -:10CA6000509146060F94684018160CF010E0609143 -:10CA70005E0670915F06072E000C880B990B0F94D1 -:10CA8000B8399B01AC0160915A0670915B068091A8 -:10CA90005C0690915D060F94B13987FD12600E948B -:10CAA0003BC88111146010932E0520916D0F3091B9 -:10CAB0006E0F40916F0F5091700F609176027091E0 -:10CAC000770280917802909179020F94083E4B0191 -:10CAD0005C012091710F3091720F4091730F509152 -:10CAE000740F60917A0270917B0280917C02909128 -:10CAF0007D020F94083E6D837E838F8398872091FB -:10CB0000750F3091760F4091770F5091780F6091AB -:10CB10007E0270917F0280918002909181020F9439 -:10CB2000083E2B013C0120E030E040E251E40F944C -:10CB3000173A20E030E048EC52E40F94173A6B01CA -:10CB40007C0120E030E0A901C301B2010F94B139AA -:10CB500020E030E040EA50EC87FD04C020E030E007 -:10CB600040EA50E4C701B6010F94083E20E030E0EF -:10CB700040E251E40F94023F0F94743F2B013C01BB -:10CB800080E277FE09C07094609450944094411CF8 -:10CB9000511C611C711C8DE28093A20560E220E1B2 -:10CBA000421627E25206610471048CF0C301B201FF -:10CBB00020E137E240E050E00F94C63DCA01B901E0 -:10CBC0002AE030E040E050E00F94C63D605D6093A5 -:10CBD000A30560E238EE431633E0530661047104A6 -:10CBE0008CF0C301B20128EE33E040E050E00F9436 -:10CBF000C63DCA01B9012AE030E040E050E00F94A0 -:10CC0000C63D605D6093A405C301B20124E630E037 -:10CC100040E050E00F94C63D6AE0C62ED12CE12CD6 -:10CC2000F12CCA01B901A70196010F94C63D605DC0 -:10CC30006093A505C301B201A70196010F94C63DFB -:10CC4000162FCA01B901A70196010F94C63D112301 -:10CC500009F4F6C08EE28093A605605D6093A70597 -:10CC6000105D1093A80562EA75E086E295E00F94E6 -:10CC7000ED4120E030E0A901C501B4010F94B139C4 -:10CC800020E030E040E05FEB87FD04C020E030E0D2 -:10CC900040E05FE3C501B4010F94083E0F94743F78 -:10CCA000CB010E9413BDBC0181E295E00F94ED41E0 -:10CCB00020E030E0A9016D817E818F8198850F94FD -:10CCC000B13920E030E040E05FEB87FD04C020E0B8 -:10CCD00030E040E05FE36D817E818F8198850F9425 -:10CCE000083E0F94743FCB010E9413BDBC018CE140 -:10CCF00095E00F94ED418091A21714E683FD29C0C1 -:10CD00000E9473CD882309F4ADC080919A17909149 -:10CD10009B17A0919C17B0919D170097A105B10595 -:10CD200009F4A0C0BC01CD016D597F4F8F4F9F4FBB -:10CD300024E630E040E050E00F94A43D60919E175F -:10CD400070919F178091A0179091A1170F94A43D07 -:10CD5000122F0E94E4BA4B015C01062F80910F0252 -:10CD60008117A1F010930F0288E4189FB0011124DD -:10CD700090E080E00F94B6392AE037ED43E25CE3BF -:10CD80000F94173A0F947B3F60931B0580910E021E -:10CD9000081709F488C080920E02C501B40120E191 -:10CDA0003EE040E050E00F94A43DC22E732EE22EF0 -:10CDB000F32E5CE3252E312C412C512CC501B401FE -:10CDC000A20191010F94A43D062F672ECA01B9015B -:10CDD000A20191010F94A43D162FD72E90E8891639 -:10CDE00091E5990691E0A906B104F0F1C501B401FD -:10CDF00020E831E541E050E00F94A43D5901DF9275 -:10CE00001F93C70168E170E00F9434419F938F93A3 -:10CE10003F932F938FE796E09F938F938BE095E05E -:10CE20009F938F930F9448390FB6F894DEBF0FBECF -:10CE3000CDBF89E0BAE0AB16B10470F588E02CC034 -:10CE4000662351F08EE28093A605605D6093A7058E -:10CE500080E28093A80507CF80E28093A7058093A6 -:10CE6000A605F6CF10E075CFE114F10409F087C2F2 -:10CE70006F920F93DF921F9383E796E09F938F93B8 -:10CE80008BE095E09F938F930F9448390FB6F894F9 -:10CE9000DEBF0FBECDBF85E0982F990F990F891B7C -:10CEA000855A80930A050E94F224D82E81E00E94C0 -:10CEB000AA3F80912E05982F947042E102E082FFF4 -:10CEC00002C048E00CE080917D16843180F48091AE -:10CED0007F16841760F0992309F471C28BE197E003 -:10CEE0007C0123E060E589E496E10F94852680913A -:10CEF0007D168431B8F480917F16823098F0DD2061 -:10CF000009F460C28091D205882309F45BC28FEDD9 -:10CF100096E07C0102E123E042E068E689E496E1E4 -:10CF20000F94852680917D168C3108F0EAC02FE39E -:10CF3000222E26E0322E1FE0B12CA12C39E0432E08 -:10CF4000512C612C712C4CE1C42E3A2DD101149638 -:10CF50008D919D910D90BC91A02D8D839E83AF836B -:10CF6000B887F1018084918480917D16843118F511 -:10CF700080917F168830F8F062E2A11001C068E06D -:10CF8000F501E855FD4F208180912E0590E002C00B -:10CF9000959587953A95E2F7F501EE0FFF1F80FF13 -:10CFA00014C2EB55F94FE590F4900CE048E089E4A9 -:10CFB00096E10F94852680917D168830B0F4D110CB -:10CFC0000BC025E02A9DF0012B9DF00D1124E25E9F -:10CFD000F94F8481811109C097FEFAC14DE956E0ED -:10CFE00067E087EF810F0E94C46480917D168C31C9 -:10CFF000C8F480917F168431A8F020E030E040E052 -:10D000005FE36D817E818F8198850F94083E0F9438 -:10D01000743F77FF08C24DE956E06CE187EF810F5E -:10D020000E94C4643FEFA31AB30A87E1280E311CA3 -:10D03000165E133409F089CF809032069090330643 -:10D04000A0903406B090350680917D16883090F41B -:10D05000D11004C080912C0681110CC0809136063D -:10D060009091370697FF09C24DE956E067E081E5E8 -:10D070000E94C46480917D168C31B0F480917F163B -:10D08000843190F020E030E040E05FE3C501B4017E -:10D090000F94083E0F94743F77FF1DC24DE956E090 -:10D0A0006CE181E50E94C46480917D168C3148F565 -:10D0B00080917F16843128F18091D205882309F16F -:10D0C000E4E68E9FC001112481589F4F6FEF70E0FE -:10D0D0000F944841CB010E9492BD27E62093801611 -:10D0E0002CE1209381160E94AD4285E290E0A0E001 -:10D0F000B0E089839A83AB83BC83CE0101960E9402 -:10D1000067400E9473CD882379F180917D16843326 -:10D1100058F580917F168A3238F107E028E04AE21C -:10D120006AE289E496E10F94C72305E022E04CE22D -:10D1300062E389E496E10F94C72324E04AE061E3C7 -:10D140008AE20F948D2360914B1670914C1682E306 -:10D15000809365168BE28093661625E636E142E3FE -:10D1600089E496E10F94452280917D16853350F431 -:10D1700080917F16813330F024E04AE461E386E356 -:10D180000F948D2380917D16843368F480917F16EF -:10D19000823348F002E020911B0542E367E389E413 -:10D1A00096E10F94C72380917D16803378F48091A7 -:10D1B0007F16883258F080910A058093801680E3AC -:10D1C000809381168BE095E00E94AD4280917D16A0 -:10D1D000883208F06FC080917F168D3108F46AC0E4 -:10D1E0002BE040E86DE180E00F948D2380917D1667 -:10D1F000873208F05FC080917F168F3108F45AC0E3 -:10D2000088E590E0A0E0B0E089839A83AB83BC839B -:10D2100083E08093801616E210938116CE0101966A -:10D220000E9467408BE08093801610938116DD206A -:10D2300009F480C181E295E00E94AD4289E590E069 -:10D24000A0E0B0E089839A83AB83BC8388E28093BB -:10D25000801616E210938116CE0101960E94674057 -:10D2600080E38093801610938116DD2009F48AC133 -:10D270008CE195E00E94AD428AE590E0A0E0B0E04C -:10D2800089839A83AB83BC838DE48093801616E2F6 -:10D2900010938116CE0101960E94674085E5809328 -:10D2A000801610938116DD2009F494C186E295E082 -:10D2B0000E94AD4280917D168333A8F580917F1640 -:10D2C0008B3288F183E00E94AA3F86E090E0A0E0E4 -:10D2D000B0E089839A83AB83BC8383E0809380161C -:10D2E00013E310938116CE0101960E94674081E0FE -:10D2F0000E94AA3F80912002909121020E9492BD3B -:10D300002CE020938016109381160E94AD4285E296 -:10D3100090E0A0E0B0E089839A83AB83BC83CE0128 -:10D3200001960E94674080917D16813408F069CB98 -:10D3300080917F16863308F464CB109280168EE3BA -:10D340008093811689E192E10E94A724182F60E85A -:10D3500070E089E192E10E94DDC780E2C82ED12C05 -:10D36000E12CF12C153108F04CCBC982DA82EB822A -:10D37000FC82CE0101960E9467401F5FF3CFF4E666 -:10D38000EF16F10438F4DF921F937F92CF9287E675 -:10D3900096E074CDDF921F937F92CF928DE596E059 -:10D3A0009F938F938BE095E09F938F930F944839D1 -:10D3B0000FB6F894DEBF0FBECDBF86E06DCD85E120 -:10D3C00097E08ECD89EA96E0A4CDEF55F94FEBCDED -:10D3D000C4010E9492BDFC01808193E0803229F457 -:10D3E000818192E0803209F491E0892F880F880FC3 -:10D3F000392F381B832F810F8093801687E080930D -:10D400008116A3E0B0E0A91BB109CD018E0F9F1FCB -:10D410000E94AD4249825A826B827C82CE01019683 -:10D420000E946740E2CDCB010E9492BDFC01808149 -:10D4300093E0803229F4818192E0803209F491E016 -:10D44000892F880F880FB92FB81B8B2F810F8093DE -:10D450008016C092811623E030E0291B3109C901F2 -:10D460008E0F9F1F0E94AD4249825A826B827C823E -:10D47000CE0101960E946740D5CD0E9492BDFC016D -:10D48000808193E0803229F4818192E0803209F436 -:10D4900091E0892F880F880FA92FA81B8A2F865A01 -:10D4A0008093801687E08093811623E030E0291B6B -:10D4B0003109CF01820F931F0E94AD4289E090E0B5 -:10D4C000A0E0B0E089839A83AB83BC83CE01019650 -:10D4D0000E946740CFCDCB010E9492BDFC018081AC -:10D4E00093E0803229F4818192E0803209F491E066 -:10D4F000892F880F880FB92FB81B8B2F865A8093DE -:10D5000080168CE18093811623E030E0291B3109DD -:10D51000CF01820F931F0E94AD4289E090E0A0E00E -:10D52000B0E089839A83AB83BC83CE0101960E94CD -:10D530006740BACD0F94171180FF19C001E215E0C2 -:10D54000D8018D918D01882309F478CE8F320CF0AB -:10D550008FE3082E000C990BAA0BBB0B89839A83CF -:10D56000AB83BC83CE0101960E946740E9CF8091D6 -:10D57000E40880FD5FCE6FEF7FEF88E996E00E94C0 -:10D580007FC75CCE0F94171181FF19C00CE115E025 -:10D59000F80181918F01882309F46ECE8F320CF04F -:10D5A0008FE3082E000C990BAA0BBB0B89839A837F -:10D5B000AB83BC83CE0101960E946740E9CF809186 -:10D5C000E40881FD55CE6FEF7FEF88E996E00E9479 -:10D5D0007FC752CE0F94171182FF19C006E215E0E3 -:10D5E000D8018D918D01882309F464CE8F320CF01F -:10D5F0008FE3082E000C990BAA0BBB0B89839A832F -:10D60000AB83BC83CE0101960E946740E9CF809135 -:10D61000E40882FD4BCE6FEF7FEF80E996E00E9439 -:10D620007FC748CECF93DF93FC0125AD211104C005 -:10D6300021E025AF0F944922C0914B16D0914C1692 -:10D64000E0917A16F0917B1682E01995E0917A16B6 -:10D65000F0917B1681E0199530E020E044E1BE01B5 -:10D6600089E496E10F9445222CE736E147E1BE01BB -:10D6700089E496E10F944522E0917A16F0917B16A9 -:10D6800080E0DF91CF9119944F925F926F927F92D9 -:10D690008F929F92AF92BF92CF92DF92EF92FF92C2 -:10D6A0001F93CF93DF93CDB7DEB760970FB6F89493 -:10D6B000DEBF0FBECDBF0F941E1D6B017C0180919C -:10D6C00010028F3F09F44DC00F941E1D809030054D -:10D6D00090903105A0903205B09033056819790912 -:10D6E0008A099B0997FD3DC08091091690910A1601 -:10D6F0008F5F8F708917A9F18091100240E050E090 -:10D7000065E073E4843050F424E0829FF00111243A -:10D71000E655FD4F40815181628173814D875E875F -:10D720006F87788B19821A821B821C821D821E824F -:10D730001F82188619861A861B861C8640912F0523 -:10D74000833011F0409151099E012F5F3F4FBE0180 -:10D75000635F7F4F86E792E00E94ACA68FEF8093D5 -:10D7600010020E94603E8091FF0382FF33C08091CF -:10D770003B05811131C091E090933B0580914F09A9 -:10D78000892780933F0910924F0983E080937502A7 -:10D790001092FF030F941E1D6C507E4F8F4F9F4FB2 -:10D7A00060933E0570933F0580934005909341053B -:10D7B00068E873E182E090E00E948D2B16E0115042 -:10D7C00059F00E94312B62E070E080E090E00F940D -:10D7D000911CF5CF10923B058091FB039091FC03C7 -:10D7E000A091FD03B091FE03A7019601281B390B00 -:10D7F0004A0B5B0BDA01C901B7FF05C080919405A4 -:10D80000882309F4BDC1D701C6018C599F4FAF4F82 -:10D81000BF4F8093FB039093FC03A093FD03B09351 -:10D82000FE0360913C05062E000C770B77FF03C0CA -:10D8300071956195710990913C0580913A05981315 -:10D8400065C0633008F062C010923C0580913C05D1 -:10D8500080933A05653008F06BC080913F098111D3 -:10D86000E9C080914316909144168D5C944641F432 -:10D8700080911102882309F4EFC081508093110236 -:10D880000E943C958090CE059090CF05A090D00549 -:10D89000B090D10581110E944995D501C4013AE0AB -:10D8A000B695A795979587953A95D1F7009741E05A -:10D8B000A407B10520F08FEF9FEFA0E0B0E09695B0 -:10D8C0008795209175022111D9C0309194053111AD -:10D8D00086C180914316909144168D5C944609F45C -:10D8E00065C180914009811161C180913605909197 -:10D8F0003705A0913805B0913905C81AD90AEA0A46 -:10D90000FB0AF7FC61C10E945E2D5EC18DEF860FA0 -:10D91000823008F09BCF80913C0591E087FD9FEF1E -:10D92000892F880F880F890F80933C0565E08ECF83 -:10D930008091450921E030E040E050E0882309F47F -:10D9400056C08090410990904209A0904309B09040 -:10D95000440981149104A104B104E9F170E090E05C -:10D9600080E00F94B63920E030E040EA50E40F94B4 -:10D97000023F2B013C01C701B601681979098A09E8 -:10D980009B090F94B6399B01AC01C301B2010F94FE -:10D99000023F20E030E04AE754E40F94173A4B018D -:10D9A0005C0120E030E040EA52E40F94684024E655 -:10D9B00030E040E050E087FF12C020E030E040EF70 -:10D9C00051E4C501B4010F9468402AE030E040E022 -:10D9D00050E087FF04C021E030E040E050E0C0921A -:10D9E0004109D0924209E0924309F0924409A09182 -:10D9F0003C050A2E000CBB0B0F94F03D25E030E0F7 -:10DA000040E050E00F94C63D80913B0990913C0965 -:10DA1000A0913D09B0913E09820F931FA41FB51F2D -:10DA200080933B0990933C09A0933D09B0933E0934 -:10DA300010923C05D701C6018856954CAF4FBF4F99 -:10DA40008093360590933705A0933805B093390538 -:10DA500081E08093750205CF8CE080931102809164 -:10DA6000340590913505009729F00197909335057D -:10DA70008093340581E08093750202CF009741F0D6 -:10DA800040913405509135054817590708F021CFCA -:10DA900080919405811112C0223038F0243008F4AE -:10DAA00041C0243011F41092750285E496E10E9481 -:10DAB000126B81E0809397058093940583E00E9428 -:10DAC000AA3F81E080936916E0914316F0914416D5 -:10DAD00019951092970580919405811127C0109295 -:10DAE0003F0980914316909144168D5C944609F04D -:10DAF000F8CE0F941E1DDC01CB018C199D09AE09D7 -:10DB0000BF098090340590903505B12CA12C881662 -:10DB10009906AA06BB0608F0DCCE909335058093E3 -:10DB20003405D7CE81E080937502BFCF89E496E1BA -:10DB30000F94E72491E0811101C090E09093940547 -:10DB4000882369F280914316909144168D5C944627 -:10DB5000B9F40F941E1DDC01CB018C199D09AE098F -:10DB6000BF09C0903405D0903505F12CE12CC816C2 -:10DB7000D906EA06FB0620F4909335058093340518 -:10DB800060960FB6F894DEBF0FBECDBFDF91CF9188 -:10DB90001F91FF90EF90DF90CF90BF90AF909F903C -:10DBA0008F907F906F905F904F90089548E9C40EDA -:10DBB0004AE3D41EE11CF11CC0923605D092370511 -:10DBC000E0923805F0923905809194058111D8CF03 -:10DBD000809175028130A1F610927502D1CF009725 -:10DBE00009F46CCF4DCF3F924F925F926F927F922C -:10DBF0008F929F92AF92BF92CF92DF92EF92FF925D -:10DC00000F931F93CF93DF93CDB7DEB7EB970FB68C -:10DC1000F894DEBF0FBECDBF8FEF80931B028091C3 -:10DC20009705882369F18091A21700E010E084FF36 -:10DC300023C089E894E10E945F808BE1E9E8F4E188 -:10DC4000DE01919601900D928A95E1F710E000E0D7 -:10DC5000BE016F5F7F4FCE0181960F946C0E181638 -:10DC60003CF4CE0101960E94F579080F111DF0CF0A -:10DC7000CE0181960E9464800093950510939605CD -:10DC800061E081E00E9432231091A105412E85E0E0 -:10DC9000582E510E312E319491E1A92E9FE1B92ECB -:10DCA00024E1822E2DE0922E81E0682E611A11115E -:10DCB00011C00091A005002329F1809175028823ED -:10DCC00049F081E0011180E024E049E15DE0632D4D -:10DCD0000F941E158091A21786FD59C084FF57C06E -:10DCE000113009F052C00091A005013079F1809106 -:10DCF0007502811138C082E01F5F5112D8CF809326 -:10DD00009E050CC080913F0910923F098823A9F21B -:10DD10000E946C2E80919F05882379F2EB960FB6B6 -:10DD2000F894DEBF0FBECDBFDF91CF911F910F9151 -:10DD3000FF90EF90DF90CF90BF90AF909F908F902B -:10DD40007F906F905F904F903F90089580913F0932 -:10DD500010923F09882359F20E94111F80919F055C -:10DD6000882329F2DBCFBF92AF929F928F926F925E -:10DD700081E0013009F080E08F930E947D250F90B3 -:10DD80000F900F900F900F900F9082E001C081E0F4 -:10DD900090917502992309F4AFCF082FD12CC12C93 -:10DDA000712E7418802FE0909505F0909605CE1492 -:10DDB000DF0408F0A1CF0113A9C081E0E81AF1083F -:10DDC000EC18FD0889E894E10E945F808BE1E9E8A6 -:10DDD000F4E1DE01919601900D928A95E1F7F12C24 -:10DDE000BE016F5F7F4FCE0181960F946C0E1816A7 -:10DDF0007CF4CE0101960E94F579882389F3EF1017 -:10DE00006BC0BE016F5F7F4F89E79FE00E94127A6F -:10DE1000CE0181960E9464808091A217F090A005A7 -:10DE200085FF79C0F11263C080913F0910923F09CC -:10DE3000882309F45CC019821C8280918C1464EAE6 -:10DE400074E1882311F069E874E121E049E75FE0BB -:10DE5000CE0101960E946A80882309F43FC08BE1BD -:10DE6000FE013196A9E8B4E101900D928A95E1F79F -:10DE70008091A2178F7B8093A217A0919717AA3049 -:10DE800080F481E08A0F809397178BE18A9FD001FD -:10DE90001124A757B94EE9E8F4E101900D928A9553 -:10DEA000E1F7CE0101960E9464801092A10582E004 -:10DEB00090E0A0E0B0E080933B0990933C09A093F0 -:10DEC0003D09B0933E0981E080939F05109294052F -:10DED00083E08093750222CFF39482CF0E940FD803 -:10DEE00069E77FE08EEF9CE00F94E226DACF809125 -:10DEF0007502882359F0EE24E394F112E12C6E2D83 -:10DF0000872D0E94733F41E0811116C08FEFC81A20 -:10DF1000D80A0F5F47CFF116A1F0809175028823D0 -:10DF2000A9F3EE24E394F112E12C6E2D872D0E94CB -:10DF3000733F882359F340E0672D8E2D0F944014D2 -:10DF4000E5CF80913F0910923F09882331F381EE9C -:10DF500096E20E947D2480919F058823F1F2DECE17 -:10DF6000DC01680F791F90E080E02D91E92FFF27F9 -:10DF7000E227EE0FFF1FE656FB4D25913491982FB7 -:10DF80008827822793276A177B0779F708950F93CD -:10DF90001F93CF93DF93CDB7DEB760970FB6F8949A -:10DFA000DEBF0FBECDBF8C01DC01ED91FC91028084 -:10DFB000F381E02DBE016F5F7F4F1995882309F42F -:10DFC00064C08981807CC9F56F81637070E0762FB1 -:10DFD0006627770F770F8885B4E08B9FC0011124E7 -:10DFE000682B792B89858295869586958370682B19 -:10DFF0006F5F7F4F90E080E02A852370220F3B8582 -:10E0000037FB332730F9232B3E813F70230F332713 -:10E01000331F2750310904C0660F771F881F991FCF -:10E020002A95D2F760960FB6F894DEBF0FBECDBF2B -:10E03000DF91CF911F910F910895803419F5688574 -:10E040006695669570E090E080E0CB0177276627C3 -:10E050002A85622B098510E0102F0027012E000C65 -:10E06000220B330B602B712B822B932B6F5F7F4F17 -:10E070008F4F9F4F4AE0660F771F881F991F4A9561 -:10E08000D1F7D0CF8BE0F801848360E070E0CB0162 -:10E09000C9CF0895FC0182810895CF93DF93E09169 -:10E0A000390687E1E89FF0011124E15CF94FC08552 -:10E0B000D18581E0CE31D105C4F020E030E040E0F0 -:10E0C0005FE364817581868197810F94083E0F9488 -:10E0D000743F6C1B7D0B77FF03C0719561957109CF -:10E0E00081E0633071050CF080E0DF91CF910895FD -:10E0F000FC0190E1AFEAB7E001900D929A95E1F74B -:10E100000895BC012091A0073091A1074091A0077C -:10E110005091A1072417350731F481E026173707FE -:10E1200009F080E008959A01F1CFEF92FF920F93EA -:10E130001F93E0920306F0920406009305061093E5 -:10E1400006066093070670930806809309069FEF02 -:10E15000FF27621B730B840B30F4809570956195DB -:10E16000790B890B992790930E08A6E06A9F00927D -:10E170000208512DEE277A9F500DE11D8A9FE00D78 -:10E1800050930308E0930408AFE06A9F00920608EA -:10E19000512DEE277A9F500DE11D8A9FE00D50937F -:10E1A0000708E0930808AAE06A9F00920A08512D28 -:10E1B000EE277A9F500DE11D8A9FE00D50930B08CA -:10E1C000E0930C081F910F91FF90EF90089580E06D -:10E1D00008959F92AF92BF92CF92DF92EF92FF92FB -:10E1E0000F931F93CF93DF9300D01F921F92CDB751 -:10E1F000DEB7EBEBF6E10027BB27462F572FA82F02 -:10E20000AA2341F4A52F542FB85FAA2319F4A52FF0 -:10E210005527B85FA03138F45295A295452F4F701D -:10E22000507FA42BBC5FA03428F4550FAA1F550FB4 -:10E23000AA1FBE5FA03818F4550FAA1FB395550F3B -:10E24000AA1FEA0FF01F449151E0AA27B85081F1AC -:10E25000C8F0B0FF02C0440F551FB1FF04C0440F07 -:10E26000551F440F551FB2FF06C052954295142FFB -:10E270001F70407F512BB3FF1BC0A52F542F442785 -:10E280000C945871B195B0FF02C055954795B1FFF8 -:10E2900004C05595479555954795B2FF05C05295D1 -:10E2A000407F4295452B5F70B3FF02C0452F552735 -:10E2B000DD24CC24BB24B2E0649FD018C108B00A8E -:10E2C000B00B749FC018B108B00B849FB018B1098F -:10E2D000659FC018B108B00B759FB018B109859F34 -:10E2E000B0196A9FB018B1097A9FB0194D9DA12C41 -:10E2F00099243327992722275D9DA00C911C301F5C -:10E30000901F201FAD9D900C311D901F201F4C9D14 -:10E31000A00C911C301F901F201F5C9D900C311D84 -:10E32000901F201FAC9D300D911D201F4B9D900C08 -:10E33000311D901F201F5B9D300D911D201FAB9D37 -:10E34000900D211D4B9F300D911D201F5B9F900D47 -:10E35000211DAB9F200DB1E0BB24CC24DD24639FA5 -:10E36000D018C108B00AB00B739FC018B108B00B29 -:10E37000839FB018B109699FC018B108B00B799F8D -:10E38000B018B109899FB019629FB018B109729F86 -:10E39000B019D61AC70AB80A20F0B1E03B0F901F97 -:10E3A000201F1124792F632F90E0822F0F900F9060 -:10E3B0000F900F900F90DF91CF911F910F91FF90D1 -:10E3C000EF90DF90CF90BF90AF909F9008957F9295 -:10E3D0008F929F92AF92BF92CF92DF92EF92FF9275 -:10E3E0000F931F93CF93DF937090F105C6EBD5E0A9 -:10E3F00092E2C92E92E0D92E26E2E22E22E0F22EFF -:10E4000009EE15E0772009F45EC0F8018080918064 -:10E41000A280B38020E030E0A901C501B4010F94CF -:10E42000B139882309F44FC020E030E040E05FE3D9 -:10E43000C501B4010F94173A9B01AC010F94173A30 -:10E440002BED3FE049E450E40F94173A9B01AC01F7 -:10E4500060E070E080E89FE30F94023F4B015C01B5 -:10E4600089929992A992B992F601619171916F0185 -:10E47000072E000C880B990B0F94B8392AE037ED62 -:10E4800043E25CE30F94173AA50194010F94173A05 -:10E49000F70161937193819391937F010C5F1F4FFB -:10E4A000F5E0CE3BDF0709F0ADCFDF91CF911F91B3 -:10E4B0000F91FF90EF90DF90CF90BF90AF909F9023 -:10E4C0008F907F900895812C912C80E8A82E8FE367 -:10E4D000B82EC6CFFC01908193FB882780F993FF6B -:10E4E0000E94E770811102C081E0089580E00895E4 -:10E4F000CF92DF92EF92FF920F931F93CF93DF9310 -:10E50000E82FF0E0EF01CC0FDD1FCC0FDD1F461729 -:10E5100039F0823009F049C0C12CD12C760117C0E6 -:10E520008230D1F3A09151098A2F90E0DC01AA0F2B -:10E53000BB1FA80FB91FAE0FBF1FAA0FBB1FAA0F8B -:10E54000BB1FA259B94FCD90DD90ED90FC908F018B -:10E55000000F111F000F111FF801E059FB4E25910C -:10E56000359145915491C95CDD4FC701B6010F94B7 -:10E57000083E6A837B838C839D83F801EC59FB4EB4 -:10E580002591359145915491C701B6010F94083EEC -:10E590006E877F87888B998BDF91CF911F910F9129 -:10E5A000FF90EF90DF90CF90089550E0DA01AA0F2E -:10E5B000BB1FA40FB51FAE0FBF1FAA0FBB1FAA0F13 -:10E5C000BB1FA259B94F862F90E0BC01660F771F81 -:10E5D000680F791FE60FF71FEE0FFF1FEE0FFF1FEB -:10E5E000E259F94F20813181428153816D917D91B2 -:10E5F0008D919C910F94073E6B017C01C95CDD4FAE -:10E60000AC019B016A817B818C819D810F94083EC6 -:10E610006A837B838C839D83A70196016E857F85AA -:10E6200088899989B3CFCF93DF93EC018D810E94C4 -:10E63000CFDD60E08B81DF91CF910D945D18AF92BB -:10E64000BF92DF92EF92FF920F931F93CF93DF93CE -:10E6500000D000D0CDB7DEB77C01D62E122F032F0D -:10E66000B42EA52E0E9413730F942A1D1E821D82A4 -:10E670008D2D80648983AA82BB820C831D838E01C9 -:10E680000F5F1F4FCE010696D801E0E02D91F0E01C -:10E69000EE0FFF1FE227E656FC4DE491A817B907DD -:10E6A000A9F7EE0FE160EE83580186E0A80EB11CD9 -:10E6B000F80181918F010E94C3DD0A151B05C1F786 -:10E6C000FCE0DF1202C00E94C8DD10E00E94C8DD3D -:10E6D000F701868387FF04C01F3F11F01F5FF6CF4D -:10E6E00026960FB6F894DEBF0FBECDBFDF91CF9157 -:10E6F0001F910F91FF90EF90DF90BF90AF90089522 -:10E7000061E0FC0183810F945D188FEF0C94C3DDF1 -:10E710000F931F93CF938C010E9413730F942A1DA4 -:10E72000C82F882371F08DEF0E94C3DD0F942A1D3E -:10E73000C82FC8010E9480738C2FCF911F910F9119 -:10E74000089582E1F8018483F4CF8F929F92AF9273 -:10E75000BF92CF92DF92EF92FF920F931F93CF93CE -:10E76000DF93EC016A017B01590120E030E0A9014F -:10E7700067E30E941F73A501980167E1CE010E9423 -:10E780001F73811127C08F81833039F089E0CC0C51 -:10E79000DD1CEE1CFF1C8A95D1F7A701960169E1EB -:10E7A000CE010E941F7311E0882319F010E087E06A -:10E7B0008C83CE010E948073812FDF91CF911F91B6 -:10E7C0000F91FF90EF90DF90CF90BF90AF909F9010 -:10E7D0008F90089589E08C8310E0EBCFEF92FF9249 -:10E7E0000F931F93CF93DF93EC01E62E8A0160E035 -:10E7F00072E0CA010E94B06FF82E892FEEBCF801BA -:10E8000098013E5F0DB407FEFDCF90819EBD0DB413 -:10E8100007FEFDCF91819EBD3296E217F30791F777 -:10E820000DB407FEFDCF0E94C3DD8F2D0E94C3DD16 -:10E830000E94C8DD8E838F71853069F083E18C83FF -:10E84000CE010E94807380E0DF91CF911F910F91E4 -:10E85000FF90EF90089581E0F7CF0F931F93CF9330 -:10E86000DF93EC018B010E9413730F942A1D811119 -:10E870000CC085E18C8310E0CE010E948073812F53 -:10E88000DF91CF911F910F910895A8016CEFCE01F8 -:10E890000E94EE73182F882361F3EECF0F931F931E -:10E8A000CF93DF93EC0189018F81833039F089E0C8 -:10E8B000440F551F661F771F8A95D1F79A01AB0148 -:10E8C00068E1CE010E941F7381112AC0A8016EEF7A -:10E8D000CE010E94EE73182F8823B1F00F942A1DE9 -:10E8E000182F8823D1F020E030E0A9016DE0CE019F -:10E8F0000E941F73882321F086E18C8310E004C0FE -:10E900000E94C8DD8111F8CFCE010E948073812F53 -:10E91000DF91CF911F910F91089587E18C83F4CF00 -:10E9200086E0EBCF1F93CF93DF93EC010E9413732C -:10E9300020E030E0A9016CE0CE010E941F7311E0DD -:10E94000882319F010E083E08C83CE010E9480734D -:10E95000812FDF91CF911F9108951F93CF93DF9364 -:10E96000EC018F81833039F089E0440F551F661F19 -:10E97000771F8A95D1F79A01AB0162E1CE010E941F -:10E980001F7311E0882319F010E085E08C83CE011D -:10E990000E948073812FDF91CF911F9108958F92F4 -:10E9A0009F92AF92BF92CF92DF92FF920F931F93ED -:10E9B000CF93DF93EC018B016A010F941E1D4B0175 -:10E9C0005C012CE2820E21E0921EA11CB11C0E946F -:10E9D000C8DD8E838F3F61F40F941E1D681979097D -:10E9E0008A099B0997FDF3CF81E18C8310E028C051 -:10E9F0008E3F09F040C0C60101972FEF2EBDF801F0 -:10EA00004FEF0DB407FEFDCF2EB521934EBD9F01F4 -:10EA1000201B310B28173907A0F30DB407FEFDCFDB -:10EA20002EB5800F911FFC0120830E94C8DDF82EB7 -:10EA30000E94C8DDB82E80915502811111C011E0ED -:10EA4000CE010E948073812FDF91CF911F910F9192 -:10EA5000FF90DF90CF90BF90AF909F908F900895E0 -:10EA6000B601C8010E94B06F3F2D2B2D821793076E -:10EA700031F38BE1BACF8FE0B8CF0F931F93CF93D1 -:10EA8000DF93EC018B010E94137340E052E0B80168 -:10EA9000CE01DF91CF911F910F910C94CF74AF9263 -:10EAA000BF92CF92DF92EF92FF920F931F93CF937B -:10EAB000DF93EC016A017B0159018F81833039F0CA -:10EAC00089E0CC0CDD1CEE1CFF1C8A95D1F713E00D -:10EAD00004E0A701960161E1CE010E941F73882323 -:10EAE00079F00C83CE010E9480731150E1F020E098 -:10EAF00030E0A9016CE0CE010E941F731C82E9CFB7 -:10EB000040E052E0B501CE010E94CF74882351F35A -:10EB1000DF91CF911F910F91FF90EF90DF90CF90F9 -:10EB2000BF90AF90089580E0F3CF8F929F92AF9205 -:10EB3000BF92CF92DF92EF92FF920F931F93CF93EA -:10EB4000DF93EC01162F1F821C824B830F941E1D36 -:10EB50006B017C0120EDC20E27E0D21EE11CF11CEE -:10EB6000A89561E08B810F945D1861E08B810F9413 -:10EB70002C1B209A289A219A2398229A81E00E949D -:10EB8000CFDD85E08D830E94CFDD0AE08FEF0E940C -:10EB9000C3DD0150D9F7A89520E030E0A90160E07D -:10EBA000CE010E941F738E83813081F00F941E1D51 -:10EBB0006C197D098E099F0997FDEECF81E08C834A -:10EBC000CE010E9480731A8280E078C021E030E09C -:10EBD00040E050E06BE3CE010E941F7391E0813072 -:10EBE00009F090E090935502A8952AEA31E040E0C0 -:10EBF00050E068E0CE010E941F73853041F581E04E -:10EC00008F83A8958F81812C912C5401823029F417 -:10EC1000812C912CA12C80E4B82E20E030E0A901B9 -:10EC200067E3CE010E941F73A501940169E2CE0142 -:10EC30000E941F738E838823F1F00F941E1D6C19A0 -:10EC40007D098E099F0997FDE8CF8AE0B8CF04E0DF -:10EC50000E94C8DD8E830150D9F78A3A11F482E010 -:10EC6000CFCF0F941E1D6C197D098E099F0997FD4A -:10EC7000BCCF82E0A4CF8F818230C1F420E030E0AD -:10EC8000A9016AE3CE010E941F73882311F088E076 -:10EC900096CF0E94C8DD807C803C11F483E08F8396 -:10ECA0000E94C8DD0E94C8DD0E94C8DDCE010E941E -:10ECB000807381E08A83173070F41D83DF91CF91D8 -:10ECC0001F910F91FF90EF90DF90CF90BF90AF908A -:10ECD0009F908F90089588E18C8376CF0F931F9338 -:10ECE000CF93DF93EC018B0120E030E0A90169E0D4 -:10ECF0000E941F7381110AC040E150E0B801CE01AB -:10ED0000DF91CF911F910F910C94CF7480E18C8390 -:10ED1000CE010E94807380E0DF91CF911F910F910F -:10ED200008950F930091020621E0022725E537E0C0 -:10ED30004CE050E0BC0183E597E00E9461CE0F916A -:10ED400008950F930091020621E0022725E537E0A0 -:10ED500041E050E0BC0183E597E00E9461CE0F9155 -:10ED600008950F930091020621E0022725E537E080 -:10ED700041E050E0BC0183E597E00E9461CE0F9135 -:10ED800008950F930091020621E0022725E537E060 -:10ED900048E050E0BC0183E597E00E9461CE0F910E -:10EDA00008950F930091020621E0022725E537E040 -:10EDB0004CE050E0BC0183E597E00E9461CE0F91EA -:10EDC00008950F930091020621E0022725E537E020 -:10EDD00044E050E0BC0183E597E00E9461CE0F91D2 -:10EDE00008950F9301E025E537E041E050E0BC01D4 -:10EDF00083E597E00E9461CE0F9108950F93AB01D8 -:10EE00000091020621E0022725E537E0BC0183E5F9 -:10EE100097E00E9461CE0F91089525E537E04CE020 -:10EE200050E0BC0183E597E00C9494DA25E537E0E7 -:10EE300041E050E0BC0183E597E00C9494DA25E5CD -:10EE400037E041E050E0BC0183E597E00C9494DAB0 -:10EE500025E537E04CE050E0BC0183E597E00C94F9 -:10EE600094DA25E537E044E050E0BC0183E597E023 -:10EE70000C9494DACF93C82FCB010E94ACCE85E3DB -:10EE800094E10E94ACCE86E294E1CC2311F08BE2B7 -:10EE900094E1CF910C9409DB2F923F924F925F92B5 -:10EEA0006F927F928F929F92AF92BF92CF92DF929A -:10EEB000EF92FF920F931F93CF93DF93CDB7DEB7FF -:10EEC0006C970FB6F894DEBF0FBECDBF8C015B010F -:10EED0005A834983FC01E95BFF4F208031804280E7 -:10EEE00053802D823E824F825886C201B1010F9419 -:10EEF000B6396B017C01D5012D913D914D915C910D -:10EF00000F94173A0F94E63E2B013C01E981FA81F8 -:10EF10002081318142815381C701B6010F94173A94 -:10EF20000F94E63E4B015C01C301B2010F947B3F9D -:10EF30006D877E878F87988B68377105810591056E -:10EF400048F438E7232E312C412C512C2D863E8657 -:10EF50004F86588AC501B4010F947B3F698B7A8B29 -:10EF60008B8B9C8B683771058105910548F428E7E8 -:10EF7000222E312C412C512C298A3A8A4B8A5C8AC8 -:10EF8000F801ED5AFF4F80809180A280B380D801B4 -:10EF900095962D903D904D905C90989729863A8655 -:10EFA0004B865C86C501B4010F94B8396D8B7E8B9E -:10EFB0008F8B988F89288A288B2809F49CC1A701F8 -:10EFC0009601C701B6010F94173A69837A838B8340 -:10EFD0009C836D857E858F8598890F94B6399B01BA -:10EFE000AC010F94173A698F7A8F8B8F9C8F2D8984 -:10EFF0003E894F89588D60E070E080E09FE30F9478 -:10F00000023F4B015C01298D3A8D4B8D5C8D6981EE -:10F010007A818B819C810F94073EA50194010F9406 -:10F02000173A6B017C010F94E63E0F947B3F1B0166 -:10F030002C0169897A898B899C890F94B6399B0147 -:10F04000AC010F94173A9B01AC0169817A818B81E5 -:10F050009C810F94073EA50194010F94173A4B0130 -:10F060005C010F94AA3F0F947B3F69837A838B8363 -:10F070009C83DC01CB01820D931DA41DB51D298548 -:10F080003A854B855C85281B390B4A0B5B0BDA01F3 -:10F09000C901B7FF61C069857A858B859C850F940E -:10F0A000B639A70196010F94083EA50194010F946B -:10F0B000073E20E030E040E05FE30F94173A0F9402 -:10F0C000E63E6B017C0120E030E0A9010F9468402E -:10F0D00018161CF0C12CD12C7601C701B6010F9473 -:10F0E0007B3F1B012C0149855A856B857C85421528 -:10F0F00053056405750510F41A012B0169857A859D -:10F100008B859C85621973098409950969837A83C3 -:10F110008B839C83C201B1010F94B6396B017C01D2 -:10F120002D893E894F89588DCA01B9010F94083E37 -:10F130009B01AC01C701B6010F94173A298D3A8D96 -:10F140004B8D5C8D0F94083E0F94B6400F947B3F1F -:10F150006D837E838F8398876D817E818F81988573 -:10F160002D853E854F855889621B730B840B950B4B -:10F170000F94B6392D893E894F89588D0F94023FDF -:10F1800020E034E244EF59E40F94173A0F947B3FA8 -:10F190006B017C016D817E818F81988529893A89F7 -:10F1A0004B895C89621B730B840B950B0F94B639EA -:10F1B0002D893E894F89588D0F94023F20E034E21B -:10F1C00044EF59E40F94173A0F947B3F4B015C01D5 -:10F1D0003FE6C316D104E104F10408F094C0F6013F -:10F1E000EE0FFF1FEE0FFF1FE150FB4E8591959133 -:10F1F000A591B4913C01AD8BB9874FE6841691047B -:10F20000A104B10408F087C0F401EE0FFF1FEE0F58 -:10F21000FF1FE150FB4E4591559165917491342F3C -:10F22000252FCB01D8019A962D923D924D925C925A -:10F230009D9795964D915D916D917C9198972980C0 -:10F240003A804B805C8042195309640975099E9687 -:10F250004D935D936D937C93D197F801E55BFF4FE0 -:10F260002D843E844F84588820823182428253828A -:10F27000D696CD92DD92ED92FC92D997F80182AEAE -:10F2800093AEA4AEB5AEFE96608271822D882282C6 -:10F2900039843382349630832183828393832D8013 -:10F2A0003E804F805884D2962D923D924D925C9232 -:10F2B000D5973D9629883A884B885C882082318290 -:10F2C000428253826C960FB6F894DEBF0FBECDBF5C -:10F2D000DF91CF911F910F91FF90EF90DF90CF9032 -:10F2E000BF90AF909F908F907F906F905F904F9066 -:10F2F0003F902F90089519821A821B821C82212C24 -:10F30000312C210129CFC701B6010E94E9703B01D0 -:10F310008D8B998772CFC501B4010E94E970362F99 -:10F32000272F80CF8091A21784FF04C08460877F3D -:10F330008093A2170895CF92DF92EF92FF920F93DE -:10F340001F93CF93DF93CDB7DEB7EDB6FEB6DC01EA -:10F350000D900020E9F79D01281B390B285F3F4FD6 -:10F36000EDB7FEB7E21BF30B0FB6F894FEBF0FBE6E -:10F37000EDBF0DB71EB70F5F1F4F9F938F9380E1B7 -:10F3800097E29F938F931F930F930F9448396801CF -:10F39000F4E0CF0ED11C0F900F900F900F900F90B4 -:10F3A0000F90D6018D916D01882349F0082E000C35 -:10F3B000990B0F94B141F60131978083F2CF6BE046 -:10F3C00077E2C8010F94E838C8010E94E12B0FB61C -:10F3D000F894FEBE0FBEEDBEDF91CF911F910F914D -:10F3E000FF90EF90DF90CF900895FC01938591FFFF -:10F3F00002C080E00895987121E0903109F020E08A -:10F400008091A21720FB85F98093A217903141F0DB -:10F410008085873471F781E091859E3751F3089597 -:10F4200081E0FDCFFC0120E03EE2DB014D91BD011A -:10F43000403249F0283011F430833196DB011197C6 -:10F440004C91408331962F5F2B3079F710820895CD -:10F45000CF9380914D14C1E08823C9F080914E1460 -:10F4600090914F1440914514509146146091471467 -:10F4700070914814DC01ED91FC910288F389E02D34 -:10F4800025E432E11995C82F811104C0C0E08C2F0A -:10F49000CF9108954091491450914A1460914B14B2 -:10F4A00070914C144115510561057105B9F08091B9 -:10F4B0004E1490914F14DC01ED91FC910288F38978 -:10F4C000E02D25E432E11995882301F310924914C7 -:10F4D00010924A1410924B1410924C1410924D1426 -:10F4E000D6CFCF92DF92EF92FF92CF936B017C0148 -:10F4F000C42F8091451490914614A0914714B09167 -:10F5000048148C159D05AE05BF0529F10E94287A87 -:10F51000811108C0C0E08C2FCF91FF90EF90DF9059 -:10F52000CF90089580914E1490914F14DC01ED918D -:10F53000FC910088F189E02D25E432E1B701A601B4 -:10F540001995882339F3C0924514D0924614E0925D -:10F550004714F0924814CC2321F081E080934D149D -:10F56000DACFC1E0D8CF4F925F926F927F928F92A5 -:10F570009F92AF92BF92CF92DF92EF92FF920F9342 -:10F580001F93CF93DF93EC01423051056105710564 -:10F5900090F480E0DF91CF911F910F91FF90EF9059 -:10F5A000DF90CF90BF90AF909F908F907F906F90A3 -:10F5B0005F904F90089589859A85AB85BC850196AB -:10F5C000A11DB11D84179507A607B70710F38F89F2 -:10F5D0008031C9F5852E962EA72EBB248B899C8958 -:10F5E000AD89BE89880E991EAA1EBB1E280139014D -:10F5F0006A017B0141E0C501B4010E94717A882350 -:10F6000041F29F89903181F5DD24EE24FF24F6013B -:10F61000EE0FFF1FEB5BFD4E118300839A89923042 -:10F6200008F4B8CF4D815E816F817885840E951E78 -:10F63000A61EB71E8092491490924A14A0924B14B1 -:10F64000B0924C14A7CF803209F0A3CF8B899C894C -:10F65000AD89BE894A015B01E7E0B694A79497940F -:10F660008794EA95D1F7BECFE894C7F8DD24EE245D -:10F67000FF24F601EE0FFF1FEE0FFF1FEB5BFD4EA9 -:10F680004082518262827382C9CFCF92DF92EF9221 -:10F69000FF920F931F93CF93DF93FC018185928597 -:10F6A000A385B4850196A11DB11D84179507A607F2 -:10F6B000B70750F480E0DF91CF911F910F91FF9039 -:10F6C000EF90DF90CF90089587898031A9F5BB270F -:10F6D000A72F962F852FC388D488E588F6888C0DB0 -:10F6E0009D1DAE1DBF1DE9016A017B018F01409187 -:10F6F0004514509146146091471470914814841732 -:10F700009507A607B70749F5F8018789803169F59C -:10F71000B701A601552766277727440F551F4B5B76 -:10F720005D4EFA0180819181B0E0A0E088839983E9 -:10F73000AA83BB8381E0BFCF803209F0BBCFC388EF -:10F74000D488E588F688DB01CA01C7E0B695A7959D -:10F7500097958795CA95D1F7C2CF40E0BC01CD01FE -:10F760000E94717A8111D0CFA5CFB701A6014F7742 -:10F77000552766277727440F551F440F551F4B5BAE -:10F780005D4EFA0180819181A281B381BF70CECF9D -:10F790004F925F926F927F92AF92BF92CF92DF9221 -:10F7A000EF92FF920F931F93CF93DF9300D01F929E -:10F7B000CDB7DEB78C0149835A836B837C835901B3 -:10F7C000C12CD12C7601412C82E0582E612C712C59 -:10F7D00049815A816B817C819E012F5F3F4FC80117 -:10F7E0000E94457B882319F1F8018585A3019201C8 -:10F7F00004C0220F331F441F551F8A95D2F7DA0128 -:10F80000C901C80ED91EEA1EFB1E49815A816B81AF -:10F810007C8187898031F1F481E0483F5F4F610549 -:10F820007105B0F2F501C082D182E282F3820F90BD -:10F830000F900F900F90DF91CF911F910F91FF903C -:10F84000EF90DF90CF90BF90AF907F906F905F90E0 -:10F850004F90089581E0483F5F4F6F4F7F4008F41D -:10F86000B7CFE0CF0F931F93CF93DF93FC0123819A -:10F87000222331F080E0DF91CF911F910F91089505 -:10F880008B01EC01FB018789803139F582E08B83A4 -:10F890001D8A1E8A1F8A188E808D918DB0E0A0E08F -:10F8A00025E0880F991FAA1FBB1F2A95D1F7898BC6 -:10F8B0009A8BAB8BBC8B1A8F098F81E0898318865A -:10F8C00019861A861B861C821D821E821F82188A38 -:10F8D0001C861D861E861F86CECF803259F683E099 -:10F8E0008B83428D538D648D758D4D8B5E8B6F8BAD -:10F8F000788F9E012F5E3F4FC8010E94C87B811107 -:10F90000DACFB8CF8F929F92AF92BF92CF92DF9211 -:10F91000EF92FF920F931F93CF93DF93EC018B81B4 -:10F9200081110EC080E0DF91CF911F910F91FF9068 -:10F93000EF90DF90CF90BF90AF909F908F90089501 -:10F9400009891A892B893C89041715072607370767 -:10F9500048F34A015B01823031F488869986AA8691 -:10F96000BB8681E0E0CF81149104A104B10449F485 -:10F97000188619861A861B861C821D821E821F828B -:10F98000F0CF088519852A853B85E98DFA8D858517 -:10F9900090E00996B901A801415051096109710926 -:10F9A000082E04C076956795579547950A94D2F727 -:10F9B00075016401E1E0CE1AD108E108F10804C044 -:10F9C000F694E794D794C7948A95D2F7C416D506CF -:10F9D000E606F70620F0012B022B032B11F58D898B -:10F9E0009E89AF89B88D8C839D83AE83BF838E0142 -:10F9F0000C5F1F4FC114D104E104F10409F4ADCF31 -:10FA00004C815D816E817F819801898D9A8D0E94E4 -:10FA1000457B91E0C91AD108E108F1088111EACFCC -:10FA200081CFC41AD50AE60AF70AE1CF2F923F9296 -:10FA30004F925F926F927F928F929F92AF92BF92FE -:10FA4000CF92DF92EF92FF920F931F93CF93DF93AA -:10FA5000EC014B017A018B81811115C08FEF9FEF73 -:10FA6000DF91CF911F910F91FF90EF90DF90CF909A -:10FA7000BF90AF909F908F907F906F905F904F90CE -:10FA80003F902F900895898180FFE8CF89899A89D6 -:10FA9000AB89BC89488559856A857B85841B950B14 -:10FAA000A60BB70BA70170E060E084179507A607C7 -:10FAB000B70708F47C0167011E0124E0220E311C07 -:10FAC000C114D10409F4A9C0488559856A857B858C -:10FAD0005A0181E0B822898D9A8D2A013B0129E0E3 -:10FAE00076946794579447942A95D1F72B81FC011B -:10FAF000223081F5628D738D848D958D640D751D19 -:10FB0000861D971D00E012E00A191B09C016D106D8 -:10FB100008F486010115E2E01E0771F440904514D7 -:10FB20005090461460904714709048146415750501 -:10FB30008605970509F04EC040E00E94717A88233F -:10FB400009F48CCFB5016B5B7D4EA801C4010F9405 -:10FB5000C64152C0148111501421A114B10471F492 -:10FB600011110CC0452B462B472B51F58D899E89D1 -:10FB7000AF89B88D8C839D83AE83BF83E98DFA8D69 -:10FB80004C805D806E807F8022E0421A51086108BF -:10FB90007108858504C0440C551C661C771C8A9529 -:10FBA000D2F786859785A089B189480E591E6A1EAD -:10FBB0007B1EC301B201610F711D811D911DA2CF7A -:10FBC0004C815D816E817F8191010E94457B811115 -:10FBD000D5CF44CFA0914E14B0914F14ED91FC912C -:10FBE00011970088F189E02D9401AB01BC01CD0192 -:10FBF0001995882309F432CF800E911E8885998546 -:10FC0000AA85BB85800F911FA11DB11D888799878B -:10FC1000AA87BB87C01AD10A53CFC70121CFCF9380 -:10FC2000DF93EC01462F41706C857D858E859F8525 -:10FC30000E94717A882351F0888920E2829FC00156 -:10FC400011248B5B9D4EDF91CF91089590E080E071 -:10FC5000FACFCF93DF93EC018B81882349F189811F -:10FC600087FF22C061E0CE010E940F7EFC01892B3C -:10FC7000F9F08081853EE1F08B81823040F4898902 -:10FC80009A89AB89BC89848F958FA68FB78F8D8910 -:10FC90009E89938F828F8D899E89AF89B88DB58B10 -:10FCA000A48B89818F778983DF91CF910C94287AF7 -:10FCB00081E0888380E0DF91CF910895CF93DF9337 -:10FCC000EC010E94297E1B82DF91CF910895109252 -:10FCD0009A068091A2178F778093A2170E9473CD06 -:10FCE000882321F080E594E10C945E7E0895CF9303 -:10FCF000C091A217C2FF10C0C7FD0EC00E9473CDF5 -:10FD000080FBC7F9C093A2178091A2178F7E8064F1 -:10FD10008093A217CF9108950E94677EF5CFCF936D -:10FD2000DF938091A2178F7E8093A2178091A714F2 -:10FD3000882321F084EA94E10E945E7E8091A317DB -:10FD40009091A417DC01ED91FC910190F081E02DE0 -:10FD500045E360E01995811112C00E940FD88FEF22 -:10FD600096E20E94ACCE8091A21784FF34C00F941B -:10FD7000022783E080937502DF91CF910895C091AF -:10FD8000A317D091A41761E0CE010F94DA0A811174 -:10FD90000BC060E0CE010F94DA0A811105C00E9409 -:10FDA0000BD88BEE96E2DDCF6BE674E184EA94E14A -:10FDB0000E94327C811105C00E940BD88AED96E228 -:10FDC000D0CF8091A21780618093A2170E940FD894 -:10FDD0008EEC96E2C6CF80913509882351F261E01E -:10FDE0008EEB96E20E941D3B0E945E2DC2CFCF9308 -:10FDF000DF93EB01FC012381211104C080E0DF913E -:10FE0000CF9108952250223028F48FE288831982FE -:10FE100081E0F5CF60E00E940F7E009779F3DC016E -:10FE200060E080E09EE22D91203299F0883031F43C -:10FE30009E01260F311DF90190836F5F9E01260FF1 -:10FE4000311DAD0141505109FA014081F901408352 -:10FE50006F5F8F5F8B3039F7FE01E60FF11D108267 -:10FE6000D7CFCF93DF93EC01CB01E881F98160819B -:10FE700071810E94F77E28813981D901ED91FC9131 -:10FE8000AA81BB818C919081992359F08936C8F45D -:10FE9000CF010196F901918380838C918F5F8C93C0 -:10FEA000EACF893670F48FE28083E881F98180811E -:10FEB0009181019691838083EA81FB8180818F5FAC -:10FEC0008083DF91CF9108953F924F925F926F921E -:10FED0007F928F929F92AF92BF92CF92DF92EF92DA -:10FEE000FF920F931F93CF93DF93CDB7DEB72C977D -:10FEF0000FB6F894DEBF0FBECDBF5C01DC01599692 -:10FF00008D909C90F40181859285A385B4859C0198 -:10FF1000AD012F5F3F4F4F4F5F4F29873A874B8788 -:10FF20005C87D50114964D905D906D907C901797ED -:10FF3000411451046104710409F459C0BFEF4B1A14 -:10FF40005B0A6B0A7B0A312C730162011D821E82DF -:10FF50001F821886F40181859285A385B4852D8141 -:10FF60003E814F815885281739074A075B0708F0FB -:10FF700056C089859A85AB85BC858C159D05AE05D7 -:10FF8000BF0550F482E0C82ED12CE12CF12C92E078 -:10FF9000492E512C612C712C9E012F5F3F4FB701D0 -:10FFA000A601C4010E94457B8823C9F189819A81F9 -:10FFB000AB81BC81892B8A2B8B2B01F12601370168 -:10FFC0009FEF491A590A690A790A2D813E814F81AA -:10FFD00058852F5F3F4F4F4F5F4F2D833E834F8399 -:10FFE00058873FEFC31AD30AE30AF30AB3CF40801E -:10FFF00051806280738033243394A6CFC414D50417 -:020000040001F9 -:10000000E604F70411F70FEF1FEF2FEF3FE0B70102 -:10001000A601C4010E94B37A782E81111AC0712CF6 -:10002000872D2C960FB6F894DEBF0FBECDBFDF91A3 -:10003000CF911F910F91FF90EF90DF90CF90BF90E5 -:10004000AF909F908F907F906F905F904F903F9078 -:100050000895F501448155816681778141155105E7 -:100060006105710539F097018601C4010E94B37AD8 -:100070008823A9F2D5011496CD92DD92ED92FC92DF -:100080001797332051F0D701C6010196A11DB11D6C -:10009000F40180839183A283B383F50185899689D6 -:1000A000A789B08D892B8A2B8B2B09F0B9CFC58AF4 -:1000B000D68AE78AF08E818180688183B1CF40E063 -:1000C00050E0BA010C94827CFC01238121110C9434 -:1000D0005E7E08952F923F924F925F926F927F9231 -:1000E0008F929F92AF92BF92CF92DF92EF92FF9248 -:1000F0000F931F93CF93DF93CDB7DEB7C454D109CD -:100100000FB6F894DEBF0FBECDBF7C014B015A0184 -:10011000222E19821C821C8E1F8E6115710511F40E -:1001200010E0B3C1DC0113968C918111F9CFFA0173 -:1001300080818B018F32D1F4DB0113968C91139760 -:100140008250823060F059966D917C91CE014C9630 -:100150000E94327C8E01045E1F4F882309F3C50183 -:100160005C010196F50120812F32D1F39E012F5FB2 -:100170003F4F6901290130E2332E2496CFAE2497F8 -:100180002596DFAE25973E013CE1630E711C229659 -:100190003FAE229721963FAE21973FAE3EAE3DAE99 -:1001A0003CAE3BAE3AAE39AE38AE3FAA950190E0D8 -:1001B00047E0D9018D91882361F18F3251F18E3260 -:1001C00039F44A3009F4ACCF98E04AE09D01F1CF10 -:1001D000EAE9F6E22491222321F031968213FACF44 -:1001E0009FCF491708F49CCF813208F499CF8F37FD -:1001F00009F496CF3FE9380F3A3108F420EEE7E3EF -:10020000F0E0EC0FFD1FE90FF11D820F80839F5F6F -:10021000DDCF8FA9803209F483CF5901D9018C91A8 -:100220002F5F3F4F8F32C9F38823A9F008151905B6 -:1002300019F0C8010E945E7E24969FAD24972596F2 -:100240008FAD25974C145D0411F4962D872D8601F2 -:10025000C92ED82E9CCFF801818D928DD7015A9648 -:100260009C938E935997C8010E945F80C12CF8011E -:1002700080859185A285B385418952896389748976 -:1002800084179507A607B70708F053C025E0B69571 -:10029000A795979587952A95D1F7F82FFF70DF2EB0 -:1002A000D80113968C91823008F43ACF41E050E0A7 -:1002B000BE016E5B7F4FC8010E94167D019709F059 -:1002C0002FCFF80180859185A285B3854F96A11D1A -:1002D000B11D80879187A287B387F0E2DF9EB001CE -:1002E00011246B5B7D4E6115710509F419CFDB019B -:1002F0008C91882341F0853E09F04DC0CC2029F037 -:10030000CC24C394B4CFC1100EC0809145149091F9 -:100310004614A0914714B0914814F701848795873B -:10032000A687B787D08ADB018C918111E9CFCC24D5 -:10033000C394822D8274823409F0F2CECC2009F469 -:10034000C7C0F701D08861E0C7010E940F7E009707 -:1003500009F4E6CE20E2DC011D922A95E9F72BE0B4 -:10036000FE01F796DC0101900D922A95E1F721E25A -:1003700038E2FC01318B208B40E058E057874687FC -:10038000338B228B318F208F578B468B0E94287A9C -:1003900081110AC0C5CE4BE050E0CE01C7960F9444 -:1003A000B941892B09F063CF2D2D30E0F901B5E07B -:1003B000EE0FFF1FBA95E1F7DF01AB5BBD4E1B9659 -:1003C0008C91817121F0822D827109F020C1D701B9 -:1003D00059968D919C915A9740914514509146148D -:1003E00060914714709148141C964D935D936D93E2 -:1003F0007C931F975096DC925097EB5BFD4E848860 -:100400009588B12CA12C54019924882455968D925D -:100410009D92AD92BC925897428D538D70E060E0F2 -:10042000482959296A297B2955964D935D936D93E7 -:100430007C935897A5E0220F331FAA95E1F7D901C5 -:10044000AB5BBD4E1B962C91287109F0D2C0848DF8 -:10045000958DA68DB78DF701818B928BA38BB48B75 -:1004600081E08383822D8F70F7018183148215824E -:1004700016821782108611861286138611E024FEDA -:1004800004C0C7010F94290C182FCE014C960E946E -:100490006480CE0101960E946480812FCC5BDF4F87 -:1004A0000FB6F894DEBF0FBECDBFDF91CF911F9185 -:1004B0000F91FF90EF90DF90CF90BF90AF909F9003 -:1004C0008F907F906F905F904F903F902F90089506 -:1004D000D80113968C911397823009F421CE51964E -:1004E0008D919D910D90BC91A02D803E9F4FAF416D -:1004F000B10508F015CEC8010E94647F882309F475 -:100500000FCE0E94287A882309F40ACED801599682 -:10051000ED91FC915A9714968D909D90AD90BC9062 -:100520001797B2E08B1A9108A108B108858504C01D -:10053000880C991CAA1CBB1C8A95D2F786859785C6 -:10054000A089B189880E991EAA1EBB1E81E08093E6 -:100550004D148092451490924614A0924714B09284 -:100560004814E5E4F2E180E092E0DF019C011D9295 -:1005700021503040E1F7DD24D394D8015996ED9114 -:10058000FC918481D816C0F480914E1490914F1440 -:10059000DC01ED91FC910288F389E02D25E432E144 -:1005A000B501A4014D0D511D611D711D19958823C3 -:1005B00009F4B6CDD394E1CF258580E092E0A0E0A8 -:1005C000B0E004C0880F991FAA1FBB1F2A95D2F75D -:1005D000F8014189528963897489840F951FA61F88 -:1005E000B71F818B928BA38BB48B85E492E1D12CC6 -:1005F000B1CE203161F497012F5E3F4F0E94C87B3E -:10060000882329F084E0D70113968C932BCFD70150 -:1006100013961C9285CD0F931F93CF93DF93CDB785 -:10062000DEB7EB970FB6F894DEBF0FBECDBF8C01DF -:1006300089E894E10E945F808BE1E9E8F4E1DE0162 -:10064000919601900D928A95E1F7BE016F5F7F4F01 -:10065000CE0181960F946C0E1816A4F4CE0101966B -:100660000E94F579882389F3BE016F5F7F4F89E788 -:100670009FE00E94127A69E77FE0C8010F94CF41A2 -:10068000892B19F7CE0181960E946480EB960FB6F4 -:10069000F894DEBF0FBECDBFDF91CF911F910F91B8 -:1006A00008958F929F92AF92BF92CF92DF92EF9276 -:1006B000FF920F931F93CF93DF93DC0170E0FB0158 -:1006C000EE0FFF1FEF5BFC4F20813181615C7C4F9F -:1006D000FB019081D92E80E0E82EF12CB7016D0D41 -:1006E000711D75956795611119C0F9013296659173 -:1006F0007491072E000C880B990B0F94B839DF9179 -:10070000CF911F910F91FF90EF90DF90CF90BF900E -:10071000AF909F908F900895D62EE0CF681711F07C -:10072000D6120CC0492F4150550BFA01EE0FFF1F96 -:10073000EE0FFF1F3296E20FF31FD9CFAB014150EE -:100740005109440F551F440F551FF901E40FF51FC0 -:1007500005911491FA013496E20FF31FC591D491DB -:10076000A017B107C8F2862FCA17DB0708F4B4CF69 -:10077000FA013296E20FF31FE590F490FA013696F3 -:10078000E20FF31FC590D490A01BB10BBD0190E008 -:1007900080E00F94B6394B015C01B6016E197F09F8 -:1007A000072E000C880B990B0F94B8399B01AC01F4 -:1007B000C501B4010F94173A4B015C01C01BD10B6A -:1007C000BE0190E080E00F94B6399B01AC01C501F9 -:1007D000B4010F94023F4B015C01B701FF0C880B81 -:1007E000990B0F94B8399B01AC01C501B4010F946A -:1007F000083E85CF8F929F92AF92BF92CF92DF92A9 -:10080000EF92FF92CF936B017C01C42F20E030E088 -:10081000A9010F94B13987FF07C08DE20E949FCED6 -:10082000F7FAF094F7F8F0942BE037ED43EA5BE346 -:10083000C23021F02FE632E143E05AE3C701B601AE -:100840000F94083E6B017C010F947B3F4B015C01D0 -:100850000F94B6399B01AC01C701B6010F94073E56 -:100860006B017C01C501B4010F94C00D8EE20E94A2 -:100870009FCEC150E8F020E030E040E251E4C701F3 -:10088000B6010F94173A6B017C010F947B3F4B012B -:100890005C010F94C00DC501B4010F94B6399B01E2 -:1008A000AC01C701B6010F94073E6B017C01E1CF9B -:1008B000CF91FF90EF90DF90CF90BF90AF909F903F -:1008C0008F900895EF92FF920F931F93CF93DF9332 -:1008D000C82F7B018A01D2E48F3F09F0D4E580E282 -:1008E0000E949FCE8D2F0E949FCEC7FD04C080E343 -:1008F0008C0F0E949FCE8AE30E949FCEF7016081F9 -:1009000071818281938142E00E94FA8387E693E2BB -:100910000E94ACCEF801608171818281938142E0B6 -:100920000E94FA8362E070E080E090E0DF91CF9176 -:100930001F910F91FF90EF900D94911CEF92FF92F9 -:100940000F931F93CF93DF9300D000D01F921F927D -:10095000CDB7DEB7082F17E1189FC00111249C0105 -:10096000215C394F7901F90160857185072E000CF2 -:10097000880B990B0F94B8396D837E838F8398878A -:10098000F70184819581A681B78189839A83AB839E -:10099000BC83AE014B5F5F4FBE016F5F7F4F80E84E -:1009A0000E9462846091360670913706072E000C13 -:1009B000880B990B0F94B8396D837E838F8398874A -:1009C0008091320690913306A0913406B09135069D -:1009D00089839A83AB83BC83AE014B5F5F4FBE01BB -:1009E0006F5F7F4F8FEF0E94628460914706709126 -:1009F0004806072E000C880B990B0F94B8396D83AD -:100A00007E838F8398878091430690914406A091BE -:100A10004506B091460689839A83AB83BC83AE01B9 -:100A20004B5F5F4FBE016F5F7F4F80E00E9462842B -:100A300060915E0670915F06072E000C880B990B83 -:100A40000F94B8396D837E838F83988780915A067F -:100A500090915B06A0915C06B0915D0689839A83B4 -:100A6000AB83BC83AE014B5F5F4FBE016F5F7F4FB7 -:100A700081E00E946284609138060F3F31F00103EB -:100A8000F0011124E15CF94F628570E082E793E2A6 -:100A90000E9487DA6091380670E08DE693E20E944A -:100AA00087DA60E08AE693E20E94A2D68AE30E9497 -:100AB0009FCE6091490670E090E080E00F942A0E8E -:100AC00061E08AE693E20E94A2D68AE30E949FCE6A -:100AD0006091600670E090E080E00F942A0E289606 -:100AE0000FB6F894DEBF0FBECDBFDF91CF911F913F -:100AF0000F91FF90EF9008950F930FB70F93009110 -:100B00006E000D7F00936E0078940F930BB70F93D8 -:100B10000CB70F921F922F933F934F935F936F9356 -:100B20007F938F939F93AF93BF93EF93FF93112482 -:100B30000E94CB95FF91EF91BF91AF919F918F91C3 -:100B40007F916F915F914F913F912F911F900F90E7 -:100B50000CBF0F910BBF0F910260F89400936E00D1 -:100B60000F910FBF0F911895EF92FF920F931F9364 -:100B7000CF93DF9310926D0660E090E080E00E94DA -:100B8000DCCCCFE3D6E01A8661E090E080E00E9402 -:100B9000DCCC19A22C9802E011E0F8018081807170 -:100BA000C0E0D1E088838EE2E82E86E0F82EF701DF -:100BB000118610860E9422C6F7011286F8018081F4 -:100BC00080728883DF91CF911F910F91FF90EF90FA -:100BD00008958F929F92AF92BF92CF92DF92EF9241 -:100BE000FF920F931F93CF93DF93B0E4A0E06A2F9F -:100BF00070E0AB014B0F511D55954795411119C040 -:100C0000E1EDF8E365917491072E000C880B990BC8 -:100C10000F94B839DF91CF911F910F91FF90EF9012 -:100C2000DF90CF90BF90AF909F908F900895B42F9A -:100C3000E0CFA41711F0B41303C0EDECF9E3E2CF59 -:100C40009A0121503109220F331F220F331FF9015E -:100C5000E153F74CE590F490F901ED52F74CC59152 -:100C6000D4918E159F0518F3A42FC817D90708F43F -:100C7000BECFF901EF52F74C05911491F901EB52F7 -:100C8000F74CC590D4908E199F09BC0190E080E08C -:100C90000F94B6394B015C01B601601B710B072E36 -:100CA000000C880B990B0F94B8399B01AC01C5015E -:100CB000B4010F94173A4B015C01CE19DF09BE0154 -:100CC00090E080E00F94B6399B01AC01C501B401FE -:100CD0000F94023F6B017C01B801110F880B990B37 -:100CE0000F94B8399B01AC01C701B6010F94083EBF -:100CF00091CF80910B06882339F060918316709113 -:100D0000841680918516089560E070E080E0089573 -:100D10002F923F924F925F926F927F928F929F920B -:100D2000AF92BF92CF92DF92EF92FF920F931F93F9 -:100D3000CF93DF93CDB7DEB765970FB6F894DEBFDC -:100D40000FBECDBF8F836B8B20916D062E871092C7 -:100D50006D0637E1839FF0011124E15CF94F848136 -:100D60009581A681B7818F87988BA98BBA8B1092BA -:100D70003A0681E080937402212C312C21011B82E0 -:100D80001C821D821E821A869CE39B87ACE1AC8785 -:100D9000B6E4BD87612C10E000E82FEB2A831982AE -:100DA000AF01485F5F4F59874887CF0104969D8BFD -:100DB0008C8BA885B9856D917C91072E000C880BD2 -:100DC000990B0F94B8396B017C01262D312F402FE0 -:100DD0005A810F94B1398823A9F0EC89FD892081CB -:100DE000318142815381FB89B601C701F1117DC078 -:100DF0000F94B139881F8827881F89836C2C1D2D7B -:100E00000E2DFA820F941E1D6B017C01DC01CB01BB -:100E10002B813C814D815E81821B930BA40BB50B12 -:100E2000B7FD10C0D701C60188519C4FAF4FBF4FCF -:100E30008B839C83AD83BE838F810E949E848AE0D6 -:100E40000E949FCE80E00E94EADD0F941E1D6093F9 -:100E50003B0670933C0680933D0690933E06AC891A -:100E6000BD89AC9011969C90119712968C90129718 -:100E700013967C90B981B1116FC0662D712F802FB0 -:100E80009A810F94743F6B016A2D792D882D972DCF -:100E90000F94743F4B016F85788989899A890F94E3 -:100EA000743FCB01A601B4010E949DCB80917402D6 -:100EB0008823F9F0A885B9856D917C91072E000CE7 -:100EC000880B990B0F94B8399B01AC01EC89FD8913 -:100ED0006081718182819381F981FF23C1F10F9437 -:100EE000684018160CF465CF04C00F94B13987FF21 -:100EF00028C0209174022983222331F010927402B9 -:100F00000F948E100E944B272E8520936D068981A9 -:100F100065960FB6F894DEBF0FBECDBFDF91CF91BF -:100F20001F910F91FF90EF90DF90CF90BF90AF9007 -:100F30009F908F907F906F905F904F903F902F90F9 -:100F400008956C2C1D2D0E2DFA8219825BCF0F9403 -:100F5000B13987FD2ECFCDCF211431044104510486 -:100F600041F0D701C60182199309A409B509B7FD5B -:100F70009DCF2A2D392D482D572D6A857B858C854F -:100F80009D850F94073E20E030E040EC5FE30F9436 -:100F9000B13987FDAECF16012701E0E62E0EEAEE4D -:100FA0003E1E411C511CAA869B868C867D867ECF68 -:100FB00012988D5F21E030E001C0220F8A95EAF798 -:100FC0008091BF07822B8093BF070895CF92DF9255 -:100FD000EF92FF92CF93DF93EC01C880D980EA8033 -:100FE000FB8083EB92E20E94ACCEC701B6010F9466 -:100FF0002A0ECC80DD80EE80FF8083E49CE30E949B -:10100000ACCEC701B6010F942A0EC884D984EA84F5 -:10101000FB848FE39CE30E94ACCEC701B6010F9422 -:101020002A0E8AE0DF91CF91FF90EF90DF90CF9072 -:101030000C949FCE0F930FB70F9300916E000F93F8 -:101040000D7F00936E0000916F000D7F00936F0085 -:101050000F930BB70F930CB70F921F922F933F93E1 -:101060004F935F936F937F938F939F93AF93BF93B0 -:10107000EF93FF9311240E9418A8FF91EF91BF9165 -:10108000AF919F918F917F916F915F914F913F9120 -:101090002F911F900F900CBF0F910BBF0F9102600B -:1010A000F89400936F000F9100936E000F910FBFA3 -:1010B0000F91189500008091E50880FF27C0899A5C -:1010C0008FEF809358078091E50881FF22C08F9AA7 -:1010D0008FEF809359078091E50882FF1DC08091B2 -:1010E0000B0180958270809309018FEF80935A07DE -:1010F00080915C079091E50893FF17C0811113C0A0 -:10110000169A8FEF80935B0700000895899881E01D -:10111000D8CF8F9881E0DDCF80910B0182708093D2 -:10112000090181E0E3CF4398ECCF811103C0169809 -:1011300081E0E8CF439AFCCFAF92BF92CF92DF928B -:10114000EF92FF921F93CF93DF9340EC50E070E05B -:1011500060E08FEA95E10F94CE218FEAA82E85E119 -:10116000B82E11E0F50113AF43E051E860E070E103 -:10117000C5010F940222C0E2D3E0F501D2AFC1AFA6 -:10118000C12CD12CE12C9FE3F92EC586D686E786AB -:10119000F08A60E273E0C5010F940F2164E0C5019D -:1011A0000F942E09C5010F94E61160E8C5010F9454 -:1011B000C72044E25EE06DE078ECC5010F94B221F7 -:1011C000C5010F94DA1168EC70E080E090E00F94B4 -:1011D000911C40EC50E070E060E083E795E10F94F3 -:1011E000CE2123E7A22E25E1B22EF50113AF43E075 -:1011F00051E860E070E1C5010F940222F501D2AF21 -:10120000C1AFC586D686E786F08A60E273E0C50185 -:101210000F940F2164E0C5010F942E09C5010F94AE -:10122000E61160E8C5010F94C72044E25EE06DE07E -:1012300078ECC5010F94B221C5010F94DA1168EC66 -:1012400070E080E090E00F94911C40EC50E070E082 -:1012500060E087E395E10F94CE2137E3A32E35E1DB -:10126000B32EF50113AF43E051E860E070E1C50132 -:101270000F940222F501D2AFC1AFC586D686E786AC -:10128000F08A60E273E0C5010F940F2164E0C501AC -:101290000F942E09C5010F94E61160E8C5010F9463 -:1012A000C72044E25EE06DE078ECC5010F94B22106 -:1012B000C5010F94DA1168EC70E080E090E00F94C3 -:1012C000911C40EC50E070E060E08BEF94E10F94F3 -:1012D000CE214BEFA42E44E1B42EF50113AF43E031 -:1012E00051E860E070E1C5010F940222F501D2AF30 -:1012F000C1AFC586D686E786F08A60E273E0C50195 -:101300000F940F2164E0C5010F942E09C5010F94BD -:10131000E61160E8C5010F94C72044E25EE06DE08D -:1013200078ECC5010F94B221C5010F94DA1168EC75 -:1013300070E080E090E00F94911C40EC50E070E091 -:1013400060E08FEB94E10F94CE215FEBA52E54E18A -:10135000B52EF50113AF43E051E860E070E1C5013F -:101360000F940222F501D2AFC1AFC586D686E786BB -:10137000F08A60E273E0C5010F940F2164E0C501BB -:101380000F942E09C5010F94E61160E8C5010F9472 -:10139000C72044E25EE06DE078ECC5010F94B22115 -:1013A000C5010F94DA1168EC70E080E090E00F94D2 -:1013B000911CDF91CF911F91FF90EF90DF90CF9024 -:1013C000BF90AF900C945A8893E0980F21E030E0E2 -:1013D00002C0220F331F9A95E2F720953095909125 -:1013E000BF0729232093BF07882321F0813021F0F4 -:1013F00081E00895129AFCCF479AFACF80E00E94CC -:10140000E48981E00C94E489882319F0813021F08B -:10141000089580E00C94D88747988091BF07806139 -:101420008093BF070895813089F070F0823081F099 -:1014300021E030E001C0220F8A95EAF78091BF07D2 -:10144000822B8093BF0708955F98F2CF8A98F0CFE0 -:1014500090910801917090930601EACF0F931F932A -:10146000CF93DF93C82F41E06DE979E10E946FD9F6 -:101470008C2F0E948ED985E999E10E94ACCE8DED2A -:1014800098E10E9409DB41E063E879E18C2F0E943A -:101490006FD98C2F0E948ED986E699E10E94ACCE3E -:1014A0008C2F0E9415DA8C2F0F9432128C2F0E94F1 -:1014B00010D68C2F0E943AD68C2F0E94EED58C2FFE -:1014C0000E94B6D58C2F0E9494D58C2F0E94E4D90F -:1014D00041E065EF78E18C2F0E946FD902EF15E0B3 -:1014E000D0E08C2F0E948ED96D2F8CEE98E10E9457 -:1014F00074D6F80160817181072E000C880B990B5E -:101500000F94B839AB01BC0189EE98E10E94A4CFD9 -:10151000F80162817381072E000C880B990B0F94E0 -:10152000B839AB01BC0186EE98E10E94A4CFF80166 -:101530006481758183EE98E10E9404DB0A5F1F4F8E -:10154000D13009F098C06FEF8C2F0E9493D98C2F67 -:101550000E9484D641E063E279E18C2F0E946FD92A -:101560008C2F0E948ED980E199E10E94ACCE6091CF -:10157000E8157091E9158EE499E10E947BDA60919B -:10158000AC157091AD158FE09CE30E947BDA609101 -:101590007015709171158CE09CE30E947BDA8AE0F3 -:1015A0000E949FCE8C2F0E948ED980E199E10E94EB -:1015B000ACCE60913415709135158DE199E10E94A2 -:1015C00004DB8C2F0E948ED980E199E10E94ACCE81 -:1015D0006091F8147091F91487E199E10E9404DB9D -:1015E0008AE00E949FCE41E061E579E18C2F0E9464 -:1015F0006FD9D091EA151091AE1500917215D111E5 -:101600003CC0111141C001113FC0809136158823A3 -:1016100091F0C11102C00E940FD88AE399E10E94A3 -:10162000ACCE80E20E949FCE89E499E10E94ACCECC -:101630008AE00E949FCE8091FA14882391F0C11114 -:1016400002C00E940FD88AE399E10E94ACCE80E2EA -:101650000E949FCE84E499E10E94ACCE8AE00E9471 -:101660009FCE8C2F0E94C7DB8C2FDF91CF911F91D3 -:101670000F910C948ED6D1E034CFCC2349F08AE37D -:1016800099E10E94ACCE0CC08AE399E1C1110AC075 -:101690000E940FD88AE399E10E94ACCEDD2321F0AD -:1016A0008EE499E10E94ACCE112321F08FE09CE3FF -:1016B0000E94ACCE002321F08CE09CE30E94ACCED3 -:1016C0008AE00E949FCEA1CF8F929F92AF92BF924D -:1016D000DF92EF92FF920F931F93CF93DF93CDB7DB -:1016E000DEB7C658D1090FB6F894DEBF0FBECDBF26 -:1016F000C358DF4F188219821A821B82CD57D040FF -:101700008091EF039091F003A091F103B091F20367 -:10171000CF57DF4F88839983AA83BB83C158D040BA -:1017200084E690E0909354078093530710925607F5 -:10173000109255071092570725E537E044E050E036 -:10174000BE016F577F4F83E597E00E9494DA809146 -:101750005307909154070296909354078093530730 -:10176000109256071092550781E0CA57DF4F8883C1 -:10177000C658D040CE018A579F4F0E941F7725E55B -:1017800037E048E450E065E579E083E597E00E94C2 -:1017900094DA80E1E4ECF2E08E010F5F1F4FD80194 -:1017A00001900D928A95E1F725E537E040E150E0A0 -:1017B000B80183E597E00E9494DA8EEF95E00E94ED -:1017C000317786EE98E00E9428778AE796E00E94BB -:1017D00028777E018DE6E80EF11C8FEFD7018C9300 -:1017E000C7010E941F7719821A821B821C82C801BE -:1017F0000E94317719821A821B821C82C8010E94C2 -:101800003177C358DF4F188219821A821B82CD5755 -:10181000D04083E0F70180838983CE0183589F4FB6 -:101820000E943177C7010E941F77C8010E941F776D -:101830005AE0D52EDA94DD2031F0CE0183589F4F47 -:101840000E943177F7CF8CE0D8011D928A95E9F795 -:10185000C8010E942877C358DF4F188219821A8264 -:101860001B82CD57D0404AE0D42EDA94DD2031F0EF -:10187000CE0183589F4F0E943177F7CF83E0CB573B -:10188000DF4F8883C558D040EA968FAFEA97CE01E4 -:101890008B579F4F0E941F77CE0187589F4F0E9402 -:1018A0001F7788E0F701982F11929A95E9F7D801F0 -:1018B0001D928A95E9F725E537E048E050E0B70149 -:1018C00083E597E00E9494DA25E537E048E050E0B0 -:1018D000B80183E597E00E9494DAC358DF4F18827D -:1018E00019821A821B82CD57D0403AE0A32EB12C28 -:1018F000B1E0AB1AB10831F0CE0183589F4F0E947E -:101900003177F6CF19828FEFF7018083C8010E94EB -:101910001677C7010E941F7780E1D8011D928A9532 -:10192000E9F725E537E040E150E0B80183E597E0CD -:101930000E9494DA1982C8010E94167725E537E0E3 -:101940004CE050E062EF75E083E597E00E9494DAA6 -:1019500092E0D92E812C912C20E8A22E2FE3B22EDA -:10196000198A1A8A1B8A1C8A8D869E86AF86B88A37 -:1019700080914A0690914B06A0914C06B0914D067D -:1019800089839A83AB83BC832CEA35EC47E25EE320 -:1019900060914E0670914F068091500690915106CD -:1019A0000F94023F6D837E838F8398872CEA35ECFA -:1019B00047E25EE3609152067091530680915406AF -:1019C000909155060F94173A69877A878B879C8781 -:1019D00025E537E044E150E0B80183E597E00E9457 -:1019E00094DAB1E0DB12C5C184E190E09A83898387 -:1019F00025E537E042E050E0B80183E597E00E943A -:101A000094DA8CE0E4EDF2E0D80101900D928A9531 -:101A1000E1F7C8010E940D778CE0E4EDF2E0D80117 -:101A200001900D928A95E1F7C8010E940D77198205 -:101A3000C8010E941F7780912E028983C8010E94ED -:101A40001F778FEF8983C8010E941F7785E0E0EE42 -:101A5000F2E0D80101900D928A95E1F725E537E093 -:101A600045E050E0B80183E597E00E9494DA1982DE -:101A7000C8010E94167780E2E5EEF2E0D8010190FD -:101A80000D928A95E1F725E537E040E250E0B80194 -:101A900083E597E00E9494DAF7011082C7010E9463 -:101AA000167781EF95E00E94167725E537E048E04C -:101AB00050E069EE75E083E597E00E9494DAC35840 -:101AC000DF4F188219821A821B82CD57D040CE0177 -:101AD00083589F4F0E943177CE0183589F4F0E94B9 -:101AE0003177FE0137968AE0DF011D928A95E9F78A -:101AF0008091E8159091E9159A8389838091AC15BE -:101B00009091AD159C838B83809170159091711588 -:101B10009E838D8380913415909135159A8B898B96 -:101B20008091F8149091F9149C8B8B8B25E537E00C -:101B300044E150E0B80183E597E00E9494DA88E23E -:101B4000E5E0F3E0D80101900D928A95E1F725E5F3 -:101B500037E048E250E0B80183E597E00E9494DA6C -:101B600080E1D82EF8018D2D11928A95E9F725E5AF -:101B700037E040E150E0B80183E597E00E9494DA55 -:101B80001A8219828091EA1581709091AE1590FBAE -:101B900081F99091721590FB82F989838A819091E5 -:101BA000361590FB80F99091FA1490FB81F98A83A5 -:101BB00025E537E042E050E0B80183E597E00E9478 -:101BC00094DAC358DF4F188219821A821B82CD57CC -:101BD000D040CE0183589F4F0E943177CE01835869 -:101BE0009F4F0E943177D8011D92DA94E9F725E5DD -:101BF00037E040E150E0B80183E597E00E9494DAD5 -:101C00008CE6F80111928A95E9F725E537E04CE674 -:101C100050E0B80183E597E00E9494DA87E497E00A -:101C20000E940D7725E537E040E150E069ED75E071 -:101C300083E597E00E9494DA25E537E044E050E040 -:101C400066E876E083E597E00E9494DA8CE0D701BD -:101C50001D928A95E9F7CB57DF4F1882C558D040BF -:101C600080E090E0A0E4B0E4ED968CAF9DAFAEAF25 -:101C7000BFAFED97C7010E942877CE018B579F4FCA -:101C80000E941F77CE0187589F4F0E943177D090D6 -:101C90005707D1104EC000915307109154070456B6 -:101CA00011098091550790915607F7019183808320 -:101CB00084E690E0909354078093530725E537E03E -:101CC00044E050E069E373E083E597E00E9494DA32 -:101CD00025E537E042E050E0B70183E597E00E9458 -:101CE00094DA0E940FD8B80185E998E10E947BDA66 -:101CF000D7018D909C90B12CA12C88E898E10E948E -:101D0000ACCEC501B4010F94C00D85E898E10E94E6 -:101D1000ACCE033B124041F00E940BD88AEA99E115 -:101D20000E94ACCEDD24D394809157078D298093F7 -:101D3000570780915707811105C060E085E798E15A -:101D40000E941D3B9091570781E08927CA57DF4FBA -:101D50000FB6F894DEBF0FBECDBFDF91CF911F91BC -:101D60000F91FF90EF90DF90BF90AF909F908F907A -:101D70000895DD24D394F4CDCF93DF9300D01F9248 -:101D8000CDB7DEB78091D108882389F083E390E056 -:101D90009C838B831A8219829E012F5F3F4F40E103 -:101DA00050E062ED78E0CE0103960E9494DA0F9045 -:101DB0000F900F900F90DF91CF910895CF93DF9305 -:101DC00000D01F921F92CDB7DEB781E08093D1087B -:101DD00080E1E2EDF8E0DF011D928A95E9F70E94CB -:101DE000BC8E86E18D8382E390E09C838B831A8294 -:101DF00019829E012F5F3F4F41E050E0BE016B5FB3 -:101E00007F4FCE0103960E9494DA0F900F900F90AF -:101E10000F900F90DF91CF910895AF92BF92CF9224 -:101E2000DF92EF92FF920F931F93CF93DF93C5E55D -:101E3000D9E00EEB15E085E6A82E89E0B82EC12C7E -:101E4000D12C7601C39469917991899199910F94DC -:101E5000B639288939894A895B890F94173A0F94D2 -:101E60007B3FF80161937193819391938F01C61623 -:101E7000D706E806F90610F46B017C01AC16BD0626 -:101E800011F76FEF7FEFCB01A70196010F94A43DEF -:101E90002093250730932607409327075093280760 -:101EA000DF91CF911F910F91FF90EF90DF90CF9036 -:101EB000BF90AF9008950F931F93CF93DF9309E6E0 -:101EC00019E0CBE2D7E0F801219131914191519194 -:101ED0008F0160E070E080E89FE30F94023F699318 -:101EE000799389939993F7E0CB33DF0761F70F94E8 -:101EF000BA11DF91CF911F910F910C940D8F90919A -:101F0000091680910A16981306C080914C09909189 -:101F10004D09892B21F080E00E94EADDF0CF089581 -:101F2000CF92DF92EF92FF920F931F93CF93DF93A5 -:101F3000CDB7DEB72C970FB6F894DEBF0FBECDBF7E -:101F4000182F6B017A0180913509833090F00E943F -:101F50000BD8C6010E94ACCE8DEC92E20E94ACCEB2 -:101F60001F3F51F589EC92E20E94ACCE8AE00E94BC -:101F70009FCE0E94B485A8958091C007811152C060 -:101F800081E08093C00782E0809335090E94B48588 -:101F900005E1015019F1A895409A69E170E080E0EF -:101FA00090E00F94911C409860E570E080E090E034 -:101FB0000F94911CA895EDCF17FDD8CF87EC92E236 -:101FC0000E94ACCE612F012E000C770B880B990B71 -:101FD0000F942A0E8AE00E949FCEC8CF409A0F9499 -:101FE0003211811111C08CE0EDE2F3E0DE011196B7 -:101FF00001900D928A95E1F7BE016F5F7F4F80E0FF -:102000000E947C2A0E947F8F60EC72E21F3F31F0B9 -:1020100064EC72E2113011F46DEB72E240E0C70142 -:102020000E94E2DC2C960FB6F894DEBF0FBECDBF47 -:10203000DF91CF911F910F91FF90EF90DF90CF90A4 -:1020400008954F925F926F927F929F92AF92BF924C -:10205000CF92DF92EF92FF920F931F93CF93DF9374 -:10206000EC016B015A01922E8FEFE2E02813E22F70 -:1020700085E0E802F0011124E25EF94F84818823B3 -:1020800009F456C01C821D821E821F8218868C8114 -:102090008230A1F0833009F47CC08130C9F52D81F4 -:1020A0003E814F815885F6016081718182819381E3 -:1020B0000F94B13987FD2CC082E08C830F941E1DD4 -:1020C0002B013C01B701FF0C880B990B0F94B83919 -:1020D0009B01AC016D817E818F8198850F94073EB5 -:1020E0009B01AC01F60160817181828193810F9423 -:1020F000684087FD42C09801A8EEB3E00F94F83D18 -:10210000460E571E681E791E488259826A827B825B -:10211000DF91CF911F910F91FF90EF90DF90CF90C3 -:10212000BF90AF909F907F906F905F904F90089579 -:10213000F5014080518062807380A30192016D811E -:102140007E818F8198850F94B139882309F49FCFC0 -:102150004D825E826F8278867724739420E030E02F -:10216000A901F50160817181828193810F9468409A -:1021700018160CF0712C7C828ACF88819981AA81F3 -:10218000BB81481A590A6A0A7B0A77FCC1CF83E0EF -:102190008C8347E453E267E573E2892DDF91CF91A9 -:1021A0001F910F91FF90EF90DF90CF90BF90AF9075 -:1021B0009F907F906F905F904F900C94908F4BEE1C -:1021C00052E268EF72E20C94908FAF92BF92CF927E -:1021D000DF92EF92FF920F931F93CF93DF93A89517 -:1021E00060E080914106909142060E945183609385 -:1021F000430670934406809345069093460661E03B -:1022000080915806909159060E94518360935A0616 -:1022100070935B0680935C0690935D068091300618 -:10222000909131060E94E9856093320670933306DF -:1022300080933406909335068FE3E82E86E0F82EDF -:102240009DE3A92E93E0B92EC4E6D2E010E0F70199 -:10225000C280D380F50101915F0107FF4DC08A81E3 -:102260009B81C816D90608F450C0F7018085918576 -:102270001816190644F407FF4CC0888199818C1503 -:102280009D0508F44FC0F7E1EF0EF11C28961130C0 -:1022900089F52091CF083091D00880913006909137 -:1022A00031068217930718F48FEF0E94DF90809118 -:1022B00036069091370618161906E4F52091620249 -:1022C00030916302809130069091310628173907CA -:1022D00088F548E253E265E373E28FEFDF91CF9137 -:1022E0001F910F91FF90EF90DF90CF90BF90AF9034 -:1022F0000C94908F11E0ABCF002309F4B6CF8A8104 -:102300009B818C159D0508F0B0CF812F0E94DF9036 -:10231000ACCF002309F4B7CF88819981C816D906BC -:1023200008F0B1CF48E253E265E373E2812F0E94E7 -:10233000908FA9CFDF91CF911F910F91FF90EF90D8 -:10234000DF90CF90BF90AF9008952F923F924F9221 -:102350005F926F927F928F929F92AF92BF92CF9235 -:10236000DF92EF92FF920F931F93CF93DF93CDB73E -:10237000DEB7A0970FB6F894DEBF0FBECDBF809139 -:10238000350981111AC0A895A0960FB6F894DEBF42 -:102390000FBECDBFDF91CF911F910F91FF90EF90B6 -:1023A000DF90CF90BF90AF909F908F907F906F9075 -:1023B0005F904F903F902F9008958091FB0781117F -:1023C000E3CF81E08093FB0780912D06811103C04C -:1023D0001092FB07D9CF0E94E59010922D060F9422 -:1023E0001E1D6F83788789879A8723E436E03E83B2 -:1023F0002D8344E652E0598B488B82E196E09B8B1B -:102400008A8BABEEB5E1BD8FAC8FEEE1F6E0FF87D6 -:10241000EE8745EC242E47E0342E1B86FB85F8A37F -:10242000A889B98916966D917C91072E000C880BAE -:10243000990B0F94B8399B01AC01ED81FE8160814D -:102440007181828193810F94684018161CF48B85EA -:102450000E94DF90AE85BF8514968C9114978111F0 -:102460001AC08D919D910D90BC91A02D0097A10552 -:10247000B10589F02F81388549855A85281B390B8C -:102480004A0B5B0BDA01C901B7FD05C0E1E0AE857F -:10249000BF851496EC93AD81BE8114966D917C91AD -:1024A000072E000C880B990B0F94B83969837A8337 -:1024B0008B839C8334E0E32EF12C08E210E02B8523 -:1024C000AE014F5F5F4F6D817E818C8D9D8D0E942F -:1024D0002190AD81BE812D913D914D915C912C8BD0 -:1024E0003D8B4E8B5F8BE889F98964817581072E5E -:1024F000000C880B990B0F94B8399B01AC016C89C7 -:102500007D898E899F890F94684018160CF06EC2E1 -:10251000A889B98916966D917C91072E000C880BBD -:10252000990B0F94B8399B01AC016C897D898E8918 -:102530009F890F94B13987FF59C28091F3078111A8 -:102540003FC0EFE3F6E0F093C607E093C507A7ECC2 -:10255000B7E0ECE01D92EA95E9F71092D3071092EC -:10256000D4071092D5071092D6071092D707109271 -:10257000D8071092D9071092DA07F1E0F093DB0741 -:1025800026E536E03093DD072093DC07AEEDB7E0BB -:10259000ECE01D92EA95E9F71092EA071092EB073A -:1025A0001092EC071092ED071092EE071092EF07D1 -:1025B0001092F0071092F107F093F207F093F307EF -:1025C000D1010D90BC91A02DBD87AC8718966D915F -:1025D0007C9119976115710501F114962D913D912A -:1025E0004D915C911797288F398F4A8F5B8F072EFB -:1025F000000C880B990B0F94B839288D398D4A8DB2 -:102600005B8D0F94073E4B015C0120E030E040E71A -:1026100051EC0F94B13987FF07C021E0F101268BFF -:10262000C12CD12C7601DEC020E030E040E751E43F -:10263000C501B4010F94684018165CF4E1E0D101C3 -:102640005696EC93C12CD12C2FE7E22E23E4F22EE8 -:10265000C9C0D10156968C915697882371F0569631 -:102660001C925697F10116861786108A118A1A96BF -:102670001D921D921D921C921D97EC85FD8547842D -:10268000508861887288D1011E962D913D914D919F -:102690005C915197C501B4010F94083E7B018C01F8 -:1026A00020E030E0A9010F94B13987FD9AC1A30160 -:1026B000920160E070E08FE793E40F94023F6E8F29 -:1026C0007F8F6C019701A8010F94B13987FF03C078 -:1026D000EE8CFF8C8601C701D801F10186879787B0 -:1026E000A08BB18BAC85BD851B962D913D914D91F5 -:1026F0005C911E97C501B4010F94173A4B015C0120 -:10270000F10182829382A482B5829701A801C3015C -:10271000B2010F94173A6B017C01D1011696CD924C -:10272000DD92ED92FC9219971A964D905D906D9006 -:102730007C901D97288D398D4A8D5B8D52966D91B9 -:102740007D918D919C9155970F94073EEC85FD8569 -:1027500023893489458956890F94173AA301920138 -:102760000F94073E20ED3CEC4CE45DE30F94173AE8 -:10277000A30192010F94083E2B013C01D1011A964E -:102780004D925D926D927C921D97288D398D4A8D68 -:102790005B8D52962D933D934D935C935597A70176 -:1027A0009601C501B4010F94083EA30192010F9454 -:1027B000083E20E030E0A9010F94083E6B017C0147 -:1027C00020E030E0A9010F94B13987FD29CF20E046 -:1027D00030E04FE753E4C701B6010F946840181684 -:1027E0000CF430CFC701B6010F94743F759567950F -:1027F000ED81FE816683EA89FB8982819381A481D0 -:10280000B5810097A105B105E9F02F81388549858B -:102810005A85281B390B4A0B5B0BDA01C901B7FD3E -:1028200011C06C897D898E899F890F94743FAA8914 -:10283000BB892D913C91621773070CF4D9C08B852D -:102840000E949ACCED81FE817796FE83ED832889E4 -:102850003989285F3F4F398B288B4A895B894A5FCA -:102860005F4F5B8B4A8B8C8D9D8D09969D8F8C8FD6 -:10287000AE85BF851596BF87AE87B7E12B0E311C9D -:10288000E1E0EB87F8A1F13009F0C8CD20E030E0BD -:102890004CED52E46091320670913306809134061B -:1028A000909135060F94684018161CF48FEF0E9423 -:1028B000DF9080910E0690910F06A0911006B091C6 -:1028C00011060097A105B10501F12F8138854985D1 -:1028D0005A85281B390B4A0B5B0BDA01C901B7FD7E -:1028E00014C0609132067091330680913406909145 -:1028F00035060F94743F20910C0630910D06621737 -:1029000073070CF47DC00E9422C68091C10790918C -:10291000C207A091C307B091C4072F8138854985AC -:102920005A85281B390B4A0B5B0BDA01C901B7FD2D -:102930004FCD8F819885A985BA8588579C4EAF4F1A -:10294000BF4F8093C1079093C207A093C307B09372 -:10295000C40780912C0681111BC08091280690919C -:102960002906A0912A06B0912B060097A105B10572 -:1029700079F02F81388549855A85281B390B4A0BF8 -:102980005B0BDA01C901B7FD03C081E080932C061F -:102990006091360670913706072E000C880B990B54 -:1029A0000F94B83969837A838B839C8382E0E82E05 -:1029B000F12C04E110E02FEFAE014F5F5F4F62E3B7 -:1029C00076E08DEF95E10E94219080912C0688237E -:1029D000F9F0109238068091020180728093000114 -:1029E000F7CCE12CF12C00E010E075CE60E000CFD8 -:1029F0004AE053E269E173E28B850E94908F22CF17 -:102A00004AE053E269E173E28FEF0E94908F7DCF3D -:102A1000C0903206D0903306E0903406F090350630 -:102A200020E030E040EA50E4C701B6010F9468406E -:102A300087FDCFCF20E030E04CED52E4C701B60176 -:102A40000F94B13918162CF2609136067091370642 -:102A5000072E000C880B990B0F94B8399B01AC0121 -:102A6000C701B6010F94B13987FF04C08FE7809387 -:102A70003806AECC80E0FBCF90916F0081E091FDF5 -:102A800002C080E0089590916F009D7F90936F0049 -:102A90000895EFE6F0E08081826080830895CF930F -:102AA000C82F0E943C9594E0C99F90011124F90120 -:102AB000ED55F84F2155384FD9014D915D916D91EC -:102AC0007C91408351836283738391E09093A2074A -:102AD000882319F0CF910C944995CF910895CF9305 -:102AE000DF9380910807649B4DC081608093080745 -:102AF000909103018091080791FD46C08D7F8093DE -:102B00000807809108074B9941C08B7F8093080785 -:102B1000C0919307C0FF10C08091E50880FD0CC0F4 -:102B20008091080780FF08C08091340981608093FC -:102B3000340980E00E944F95C1FF10C08091E508E4 -:102B400081FF0CC08091080781FF08C08091340983 -:102B500082608093340981E00E944F95C2FF18C0C3 -:102B60008091E50882FF14C08091080782FF10C0A1 -:102B70008091340984608093340982E0DF91CF91A1 -:102B80000C944F958E7FB2CF8260B9CF8460BECF58 -:102B9000DF91CF910895809136028F3708F449C0B4 -:102BA0008F57909149069093FF07992309F43FC0EE -:102BB0002C9A209160062093000890910201211127 -:102BC0009095907190930001209138062093FE0714 -:102BD00090910201211190959072909300018F5F66 -:102BE000809336028091FD0791E089278093FD074D -:102BF00081110E94603E9091350221E0290F9730AB -:102C00000CF020E0983008F041C0E92F092E000CAC -:102C1000FF0B8827E15FF9468F4F0D945C413F968B -:102C200087969396A696AB96BE96C3962F962C98AB -:102C3000C0CF9091FF07891708F02C989091000859 -:102C4000891728F090910201907190930001909162 -:102C5000FE07891708F4C3CF90910201BDCF809180 -:102C6000FC07811103C083E08093FC078091FC077F -:102C700081508093FC07882349F0292F07C0809159 -:102C800034028F5F8031ACF480933402209335029C -:102C90008091E30881110E946F9580914C09909179 -:102CA0004D09009729F0019790934D0980934C09A5 -:102CB00008951092340280912D0681111BC08091DD -:102CC0003F06909140069093420680934106809182 -:102CD0005606909157069093590680935806809116 -:102CE0002E0690912F06909331068093300681E056 -:102CF00080932D061092400610923F0610925706C0 -:102D00001092560610922F0610922E06BFCF88E022 -:102D100080937B0085E480937C0080917A008064BE -:102D200080937A00B3CF80917A0086FDA6CF409140 -:102D300078005091790080913F0690914006840F71 -:102D4000951F9093400680933F06A0CF88E0809324 -:102D50007B0086E4E0CF80917A0086FD8ECF4091A3 -:102D600078005091790080912E0690912F06840F63 -:102D7000951F90932F0680932E0688CF88E080932E -:102D80007B0087E4C8CF80917A0086FD76CF4091A2 -:102D90007800509179008091560690915706840FE3 -:102DA000951F909357068093560670CF2F923F92AF -:102DB0004F925F926F927F928F929F92AF92BF924B -:102DC000CF92DF92EF92FF920F931F93CF93DF93F7 -:102DD000CDB7DEB7C058D1090FB6F894DEBF0FBE2D -:102DE000CDBF7C018B01242EAA963FAF2EAFAA97B0 -:102DF0002091690930916A0940916B0950916C09E1 -:102E0000DC016D917D918D919C910F94173A0F94F7 -:102E10007540E8966CAF7DAF8EAF9FAFE89720917D -:102E20006D0930916E0940916F0950917009F70159 -:102E300064817581868197810F94173A0F9475404C -:102E4000EC966CAF7DAF8EAF9FAFEC972091710980 -:102E5000309172094091730950917409D701189605 -:102E60006D917D918D919C911B970F94173A0F94C2 -:102E70007540C458DF4F688379838A839B83CC571E -:102E8000D040209175093091760940917709509191 -:102E90007809F70164857585868597850F94173ABB -:102EA0000F947540A8966CAF7DAF8EAF9FAFA8977B -:102EB0008091D40583FF0EC0A8962CAD3DAD4EADDC -:102EC0005FADA89720932B1630932C1640932D16A8 -:102ED00050932E16D801BC916896BFAF6897F80141 -:102EE000F1812C96FFAF2C97D8011296BC91A09639 -:102EF000BFAFA097F80133808091091690910A1610 -:102F0000891B80958F7019F40E94EADDF5CFF0914E -:102F10000916C058DF4FF883C058D04020910916D9 -:102F20002DAF80914C0990914D09892B11F00C9493 -:102F300071A480911F1690912016A0912116B09136 -:102F40002216E8968CAC9DACAEACBFACE897881A64 -:102F5000990AAA0ABB0A8091231690912416A0917F -:102F60002516B0912616EC962CAD3DAD4EAD5FAD5D -:102F7000EC97281B390B4A0B5B0B29AF3AAF4BAFD1 -:102F80005CAF8091271690912816A0912916B091D8 -:102F90002A16C458DF4F288139814A815B81CC577A -:102FA000D040281B390B4A0B5B0B2DAB3EAB4FAB14 -:102FB00058AF80912B1690912C16A0912D16B091A0 -:102FC0002E16A896CCACDDACEEACFFACA897C81A18 -:102FD000D90AEA0AFB0A09F465C0822D0E940CCDC9 -:102FE0008823B9F0A8968CAD9DADAEADBFADA897C6 -:102FF00080932B1690932C16A0932D16B0932E161B -:103000000E940FD88AE598E10E94ACCEC12CD12C49 -:10301000760194E0299E800111240A5D1D4FC701AD -:10302000B6010F94B839D8012D913D914D915C9125 -:103030000F94173A2B013C0120E030E0A9010F94D6 -:10304000684087FF04C077FA709477F8709420E0A6 -:1030500030E048E453E460917509709176098091FD -:103060007709909178090F94173AA30192010F9470 -:10307000B13987FF17C0A8962CAD3DAD4EAD5FAD01 -:10308000A89720932B1630932C1640932D1650930F -:103090002E160E940FD88BE398E10E94ACCEC12C73 -:1030A000D12C7601D501C4018827B7FD83959927D6 -:1030B000AA27BB27782E29AD3AAD4BAD5CAD57FFA3 -:1030C00002C0689471F88DA99EA9AFA9B8ADB7FFE9 -:1030D00002C0689472F8F7FE02C0689473F894E036 -:1030E000299E800111240A5D1D4FC701B6010F946E -:1030F000B839D8012D913D914D915C910F94173ABB -:103100006B017C0120E030E0A9010F94684087FF4B -:10311000D2C1C701B6019058FDADEF2FF0E0FCAB76 -:10312000EBAB5DAD4DE5549F90011124D901A35641 -:10313000B64FBEAFADAF20E030E040E05FE30F94AC -:10314000083E0F947B3F2B966CAF7DAF8EAF9FAF49 -:103150002B97EDADFEAD1082EA5BFF4F70822DA97B -:103160003EA94FA958AD27962CAF3DAF4EAF5FAFEC -:10317000279757FF0DC050954095309521953F4FAB -:103180004F4F5F4F27962CAF3DAF4EAF5FAF2797A6 -:1031900049AC5AAC6BAC7CAC77FE08C070946094C0 -:1031A00050944094411C511C611C711C23968CAEA0 -:1031B0009DAEAEAEBFAE2397B7FE0DC08827992750 -:1031C000DC0188199909AA09BB0923968CAF9DAF28 -:1031D000AEAFBFAF239723962CAD3DAD4EAD5FADE7 -:1031E0002397ADADBEAD55962D933D934D935C9316 -:1031F0005897FD01418E528E638E748E27962CADAA -:103200003DAD4EAD5FAD27975D962D933D934D93AC -:103210005C939097C501B4010F94B83920912B07A6 -:1032200030912C0740912D0750912E070F94173A9B -:1032300063966CAF7DAF8EAF9FAF639769A37AA3A0 -:103240008BA39CA369AD7AAD8BAD9CAD0F94B839BF -:1032500020912F073091300740913107509132076C -:103260000F94173A67966CAF7DAF8EAF9FAF67979D -:103270006DA37EA38FA398A76DA97EA98FA998ADF2 -:103280000F94B839209133073091340740913507B6 -:10329000509136070F94173A6F966CAF7DAF8EAF93 -:1032A0009FAF6F9769A77AA78BA79CA72091370735 -:1032B000309138074091390750913A07C701B6015C -:1032C0000F94173A69AF7AAF8BAF9CAF6DA77EA70B -:1032D0008FA798AB23962CAD3DAD4EAD5FAD239738 -:1032E00026303105410551050CF0EDC036E043169E -:1032F0005104610471040CF0E6C027968CAD9DADBD -:10330000AEADBFAD27970697A105B1050CF0DBC0A8 -:1033100020E030E0A90169AD7AAD8BAD9CAD0F9492 -:10332000684087FFCBC089AD9AADABADBCADB0589E -:103330002DE54BA95CA9249FF001259FF00D1124D8 -:10334000E356F64F85879687A787B08B8DE5ABA9A7 -:10335000BCA98A9FF0018B9FF00D1124E356F64F14 -:103360002B962CAD3DAD4EAD5FAD2B9721A332A377 -:1033700043A354A327968CAD9DADAEADBFAD2797AB -:1033800084159505A605B70510F4D301C20123964F -:103390002CAD3DAD4EAD5FAD239782179307A407CB -:1033A000B50710F4DA01C9012B962CAD3DAD4EAD39 -:1033B0005FAD2B9782179307A407B50710F4DA01C6 -:1033C000C9012DE54BA95CA9249FF001259FF00DB3 -:1033D0001124E356F64F85A396A3A7A3B0A706979B -:1033E000A105B10510F40C9454A4DF01A95ABF4FF4 -:1033F0008091D2058C9311968091D3058C9321A650 -:1034000089288A288B2819F080E00E94138A8DE58C -:10341000ABA9BCA98A9FF0018B9FF00D1124E35644 -:10342000F64F818D928DA38DB48D892B8A2B8B2B9A -:1034300019F081E00E94138A8DE52BA93CA9829F97 -:10344000F001839FF00D1124E356F64F858D968D84 -:10345000A78DB0A1892B8A2B8B2B19F082E00E94BB -:10346000138A2B968CAD9DADAEADBFAD2B97892B3E -:103470008A2B8B2B11F40C9473A480912907882339 -:1034800019F081508093290780912A07882319F029 -:10349000815080932A07211075C080E00E94D88750 -:1034A00080E28093290780912A0781117AC081E008 -:1034B0000E94E48976C0C701B6012ECE89AD9AADCF -:1034C000ABADBCAD35CFAA96AEADBFADAA97CD9092 -:1034D000DD90ED90FC9020E030E0A901C701B6013D -:1034E0000F94B139882379F08DE52BA93CA9829FEF -:1034F000F001839FF00D1124E356F64FC586D68662 -:10350000E786F08A23CF63962CAD3DAD4EAD5FAD1F -:103510006397CA01B9010F94173A6B017C01679652 -:103520002CAD3DAD4EAD5FAD6797CA01B9010F94AB -:10353000173A9B01AC01C701B6010F94083E6B011D -:103540007C016F962CAD3DAD4EAD5FAD6F97CA015E -:10355000B9010F94173A9B01AC01C701B6010F9452 -:10356000083E0F94B6402DE54BA95CA9249FF001BD -:10357000259FF00D1124E356F64F658776878787E0 -:10358000908BE4CE80912907811102C00E94E489CA -:1035900091E0291288CF81E00E94048A80E2809322 -:1035A0002A07E0909509F0909609009197091091EB -:1035B00098090C947BA42B968CAD9DADAEADBFADA0 -:1035C0002B97892B8A2B8B2B09F404C52091890911 -:1035D00030918A0940918B0950918C09A4966CAD69 -:1035E0007DAD8EAD9FADA4970F94173A0F94E63E34 -:1035F0000F947B3F6B017C018091250790912607FA -:10360000A0912707B0912807EDADFEAD218D328D39 -:10361000438D548D2DAB3EAB4FAB58AF258D368DC2 -:10362000478D50A123962CAF3DAF4EAF5FAF239790 -:1036300021A132A143A154A12F962CAF3DAF4EAF93 -:103640005FAF2F9727962CAD3DAD4EAD5FAD279761 -:1036500082179307A407B50708F4C5C48114910421 -:10366000A104B104D1F06091BE057091BF058091B5 -:10367000C0059091C1056C157D058E059F0568F408 -:103680000F94943DA50194010F94A43D2C153D0584 -:103690004E055F0510F469017A018DA99EA9AFA9B5 -:1036A000B8AD892B8A2B8B2B11F16091C2057091DB -:1036B000C3058091C4059091C5056C157D058E05E7 -:1036C0009F05A8F427962CAD3DAD4EAD5FAD279775 -:1036D0000F94943D2DA93EA94FA958AD0F94A43D38 -:1036E0002C153D054E055F0510F469017A012396FE -:1036F0002CAD3DAD4EAD5FAD2397232B242B252B59 -:1037000021F16091C6057091C7058091C80590911F -:10371000C9056C157D058E059F05B8F427962CAD5F -:103720003DAD4EAD5FAD27970F94943D23962CADE4 -:103730003DAD4EAD5FAD23970F94A43D2C153D05D7 -:103740004E055F0510F469017A012F968CAD9DAD91 -:10375000AEADBFAD2F97892B8A2B8B2B21F16091BA -:10376000CA057091CB058091CC059091CD056C1563 -:103770007D058E059F05B8F427962CAD3DAD4EAD69 -:103780005FAD27970F94943D2F962CAD3DAD4EAD78 -:103790005FAD2F970F94A43D2C153D054E055F0599 -:1037A00010F469017A018DE54BA95CA9849F800121 -:1037B000859F100D11240356164FF801ED5AFF4F47 -:1037C000C082D182E282F382C701B6010F94B6397A -:1037D000A4962CAD3DAD4EAD5FADA4970F94023FC6 -:1037E000D80151966D937D938D939C9354976396D6 -:1037F0002CAD3DAD4EAD5FAD6397298B3A8B4B8BB6 -:103800005C8B67968CAD9DADAEADBFAD67978D8B74 -:103810009E8BAF8BB88F6F962CAD3DAD4EAD5FAD2F -:103820006F97298F3A8F4B8F5C8F89AD9AADABAD77 -:10383000BCAD8D8F9E8FAF8FB8A32B962CAD3DADB9 -:103840004EAD5FAD2B97232B242B252B09F4DAC427 -:103850008E010F5E1F4F5E0131E2A30EB11CC12C21 -:10386000D12C7601D8014D905D906D907D908D01A9 -:1038700020E030E0A901C301B2010F94B1398823DF -:1038800071F0A3019201C301B2010F94173A9B0199 -:10389000AC01C701B6010F94083E6B017C01A01674 -:1038A000B10601F7C701B6010F94B6409B01AC0108 -:1038B00060E070E080E89FE30F94023F6B017C01C1 -:1038C000AC019B0163966CAD7DAD8EAD9FAD6397F2 -:1038D0000F94173A698B7A8B8B8B9C8BA70196017F -:1038E00067966CAD7DAD8EAD9FAD67970F94173A1F -:1038F0006D8B7E8B8F8B988FA70196016F966CAD29 -:103900007DAD8EAD9FAD6F970F94173A698F7A8F0B -:103910008B8F9C8FA701960169AD7AAD8BAD9CAD65 -:103920000F94173A6D8F7E8F8F8F98A3A096BFAD9F -:10393000A097BB2309F4A2C520910B1630910C1659 -:1039400040910D1650910E1623962CAF3DAF4EAF01 -:103950005FAF23972DEB37E346E855E323966CAD35 -:103960007DAD8EAD9FAD23970F94B13987FD86C590 -:103970008090150790901607A0901707B090180731 -:10398000C988DA88EB88FC888091190790911A071A -:10399000A0911B07B0911C078DAB9EABAFABB8AF2E -:1039A0002D893E894F89588D2B962CAF3DAF4EAF58 -:1039B0005FAF2B9780911D0790911E07A0911F0765 -:1039C000B091200763968CAF9DAFAEAFBFAF63974A -:1039D000298D3A8D4B8D5C8D67962CAF3DAF4EAFE8 -:1039E0005FAF67978091210790912207A0912307ED -:1039F000B09124076F968CAF9DAFAEAFBFAF6F97FE -:103A00002D8D3E8D4F8D58A127962CAF3DAF4EAFDB -:103A10005FAF2797C501B4019058A70196010F9495 -:103A2000173A2B013C016DA97EA98FA998AD90583A -:103A30002B962CAD3DAD4EAD5FAD2B970F94173A45 -:103A40009B01AC01C301B2010F94083E2B013C0164 -:103A500063966CAD7DAD8EAD9FAD639790586796C4 -:103A60002CAD3DAD4EAD5FAD67970F94173A9B01FE -:103A7000AC01C301B2010F94083E2B013C016F96CB -:103A80006CAD7DAD8EAD9FAD6F97905827962CADE8 -:103A90003DAD4EAD5FAD27970F94173A9B01AC013A -:103AA000C301B2010F94083E69AF7AAF8BAF9CAFF0 -:103AB0002FEE3FEF4FE75FE30F94684018160CF4CA -:103AC000D6C4A5019401C701B6010F94073E2B018E -:103AD0003C0149825A826B827C822DA93EA94FA962 -:103AE00058AD2B966CAD7DAD8EAD9FAD2B970F94E1 -:103AF000073E2B966CAF7DAF8EAF9FAF2B976D833C -:103B00007E838F83988763962CAD3DAD4EAD5FADC0 -:103B1000639767966CAD7DAD8EAD9FAD67970F9443 -:103B2000073E63966CAF7DAF8EAF9FAF639769879B -:103B30007A878B879C876F962CAD3DAD4EAD5FAD80 -:103B40006F9727966CAD7DAD8EAD9FAD27970F9487 -:103B5000073E67966CAF7DAF8EAF9FAF67976D875F -:103B60007E878F87988BAE014F5F5F4F5EAB4DAB0B -:103B70008E010F5E1F4F1A01C12CD12C7601D1018D -:103B80008D909D90AD90BD901D0120E030E0A90189 -:103B9000C501B4010F94B139882371F0A5019401D6 -:103BA000C501B4010F94173A9B01AC01C701B601DE -:103BB0000F94083E6B017C010215130501F7C70144 -:103BC000B6010F94B6409B01AC0160E070E080E864 -:103BD0009FE30F94023F6B017C01AC019B01C30189 -:103BE000B2010F94173A69837A838B839C83A70170 -:103BF00096012B966CAD7DAD8EAD9FAD2B970F943E -:103C0000173A6D837E838F839887A7019601639609 -:103C10006CAD7DAD8EAD9FAD63970F94173A6987FC -:103C20007A878B879C87A701960167966CAD7DADDF -:103C30008EAD9FAD67970F94173A6D877E878F87FC -:103C4000988BEDADFEAD418852886388748805E598 -:103C500019E0ADA9BEA9CD90DD90ED90FD90BEAB71 -:103C6000ADAB20E030E0A901C701B6010F94B13936 -:103C7000882309F43EC020E030E0A901C701B60165 -:103C80000F94684087FFEBC2A701960150582B960E -:103C90002CAF3DAF4EAF5FAF2B97D8016D917D91AB -:103CA0008D919C910F94B6394B015C01A301920157 -:103CB0002B966CAD7DAD8EAD9FAD2B970F94173AC3 -:103CC000A50194010F94684018169CF4A701960171 -:103CD000C501B4010F94023F2B013C0120E030E00C -:103CE000A9010F94684087FF04C077FA709477F8B1 -:103CF00070940C5F1F4FEDA9FEA92E163F0609F028 -:103D0000A8CFAA96AEADBFADAA971496CD90DD9080 -:103D1000ED90FC90179720E030E0A901C701B601B3 -:103D20000F94B139882309F4A1C2A3019201C701FC -:103D3000B6010F94173A1B018C0123962CAD3DADB3 -:103D40004EAD5FAD2397CA01B9010F94173A6B01CD -:103D50007C018DE5ABA9BCA98A9FF0018B9FF00D7A -:103D60001124E356F64F61817281838194819B0116 -:103D7000AC010F94173A4B015C019B01AC01B601F9 -:103D8000C7010F946840181614F46401750191017D -:103D9000A801B601C7010F946840181614F4610118 -:103DA000780180E1FE017196A5E1B7E001900D92E6 -:103DB0008A95E1F78DE5EBA9FCA98E9F80018F9F85 -:103DC000100D11240356164FC601D701F801818743 -:103DD0009287A387B487618972898389948990586F -:103DE0009B01AC010F94083EADADBEAD1D962D916B -:103DF0003D914D915C9150970F94173A9B01AC0106 -:103E00006BE077ED83E29BE30F94073E6B017C014F -:103E10008BE097EDA3E2BBE3F80185839683A7834C -:103E2000B0876181728183819481ADADBEAD2C91EB -:103E300021602C939B01AC010F94173A9B01AC01BC -:103E4000C701B6010F94684087FD05C0EDADFEAD1A -:103E50008081826080838DE52BA93CA9829FF0013F -:103E6000839FF00D1124E356F64F81819281A38147 -:103E7000B48180930B1690930C16A0930D16B093FB -:103E80000E16E8968CAD9DADAEADBFADE8978093B4 -:103E90001F1690932016A0932116B0932216EC962D -:103EA0002CAD3DAD4EAD5FADEC9720932316309316 -:103EB00024164093251650932616C458DF4F888148 -:103EC0009981AA81BB81CC57D040809327169093CB -:103ED0002816A0932916B0932A16A8962CAD3DADAE -:103EE0004EAD5FADA89720932B1630932C164093C0 -:103EF0002D1650932E169091091680910A1698133C -:103F000003C084E680930616C058DF4F8881C058EE -:103F1000D0408F5F8F708093091680910916909121 -:103F2000081681508F70891709F4D5C310910916AE -:103F30002090081680910916281609F432C31150F2 -:103F40001F70D12CC12C121509F42BC3812E912C7A -:103F50003DE5139FC0011124AC014356564F5CABA5 -:103F60004BABCA010E946A72882309F417C38BA95C -:103F70009CA9892B09F19DE5989DF001999DF00D73 -:103F80001124E356F64FB1840285A384348445801E -:103F9000568067807084A30192016B2D702F8A2D4B -:103FA000932D0F94B139811171C2C114D10421F044 -:103FB000D6018C9180FD6EC211501F70822D209011 -:103FC0000816281609F45FC2181709F4EAC28F5FB1 -:103FD0008F70F5CF2091910930919209409193090A -:103FE00050919409FBCA81149104A104B10409F40D -:103FF0003FC06091BE057091BF058091C005909152 -:10400000C1056C157D058E059F0590F50F94B63999 -:104010006B962CAD3DAD4EAD5FAD6B970F94173ADF -:1040200027966CAF7DAF8EAF9FAF2797C501B401C8 -:104030000F94B6399B01AC0127966CAD7DAD8EAD6A -:104040009FAD27970F94023F4B015C01C701B6015A -:104050000F94B6399B01AC01C501B4010F94B1397D -:1040600087FF06C0C501B4010F947B3F6B017C0143 -:104070002DA93EA94FA958AD232B242B252BC9F1DF -:104080006091C2057091C3058091C4059091C505EA -:104090006C157D058E059F0560F50F94B6396B96FE -:1040A0002CAD3DAD4EAD5FAD6B970F94173A4B0104 -:1040B0005C016DA97EA98FA998AD0F94B6399B01BB -:1040C000AC01C501B4010F94023F4B015C01C70173 -:1040D000B6010F94B6399B01AC01C501B4010F9430 -:1040E000B13987FF06C0C501B4010F947B3F6B0156 -:1040F0007C0123968CAD9DADAEADBFAD2397892BD2 -:104100008A2B8B2BD9F16091C6057091C7058091E0 -:10411000C8059091C9056C157D058E059F0570F544 -:104120000F94B6396B962CAD3DAD4EAD5FAD6B9730 -:104130000F94173A4B015C0123966CAD7DAD8EADAB -:104140009FAD23970F94B6399B01AC01C501B40113 -:104150000F94023F4B015C01C701B6010F94B639C1 -:104160009B01AC01C501B4010F94B13987FF06C0B2 -:10417000C501B4010F947B3F6B017C012F962CADE0 -:104180003DAD4EAD5FAD2F97232B242B252B09F48E -:104190000ACB6091CA057091CB058091CC059091B6 -:1041A000CD056C157D058E059F0508F0FCCA0F94A2 -:1041B000B6396B962CAD3DAD4EAD5FAD6B970F94A0 -:1041C000173A4B015C012F966CAD7DAD8EAD9FAD66 -:1041D0002F970F94B6399B01AC01C501B4010F9420 -:1041E000023F4B015C01C701B6010F94B6399B0138 -:1041F000AC01C501B4010F94B13987FFD4CAC50120 -:10420000B401A4C5A301920163966CAD7DAD8EADE2 -:104210009FAD63970F94173A698B7A8B8B8B9C8B2E -:10422000A301920167966CAD7DAD8EAD9FAD679792 -:104230000F94173A6D8B7E8B8F8B988FA301920111 -:104240006F966CAD7DAD8EAD9FAD6F970F94173AA5 -:10425000698F7A8F8B8F9C8FA30192015DCB2B96F8 -:10426000CCAEDDAEEEAEFFAE2B9717CD2FEE3FEF0F -:104270004FE75FEB69AD7AAD8BAD9CAD0F94B13973 -:1042800087FF08C02FEE3FEF4FE75FEB29AF3AAF54 -:104290004BAF5CAF29AD3AAD4BAD5CAD60E070E0CB -:1042A00080E89FE30F94073E20E030E040E05FE3CA -:1042B0000F94173A0F94B6406B017C012091FE05D4 -:1042C0003091FF054091000650910106C301B201F3 -:1042D0000F94173AA70196010F94173A4B015C010E -:1042E000A701960160E070E080E89FE30F94073E2D -:1042F0009B01AC01C501B4010F94023F1B018C016D -:104300008DE54BA95CA9849FF001859FF00D1124D8 -:10431000E356F64F85859685A785B0898DAB9EAB14 -:10432000AFABB8AF20E030E040E85FE3BC01CD01C7 -:104330000F94B13987FF01CD23EF34E045E35FEB04 -:1043400069AD7AAD8BAD9CAD0F94B13987FFF5CCDB -:1043500020E030E0A90169AD7AAD8BAD9CAD0F9442 -:10436000B139C12CD12C60E8E62E6FEBF62E87FD1B -:1043700006C0C12CD12C50E8E52E5FE3F52EA70135 -:10438000960169AD7AAD8BAD9CAD0F94173A4B0198 -:104390005C0129E539ED40E053E30F94B13987FD25 -:1043A00063C0A501940160E070E080E89FE30F9492 -:1043B000073E20E030E040E057E40F94173A0F94B6 -:1043C0007B3FCB010F9464410197880F991F880FA1 -:1043D000991FFC01E550F84E259135914591549176 -:1043E000FC01E554F84E85919591A591B49189AF62 -:1043F0009AAFABAFBCAFC501B4010F94173A29AD6A -:104400003AAD4BAD5CAD0F94083E4B015C0120E032 -:1044100030E0A901C701B6010F946840181654F4A2 -:10442000A50194016BED7FE089E490E40F94073ED1 -:104430004B015C01A30192016DA97EA98FA998ADE2 -:104440000F94173AA50194010F94023F6B017C0170 -:104450009B01AC01B101C8010F94684018160CF023 -:104460006CCC1601870169CC90E080E0AECF2BE0E8 -:10447000222E37ED332E03E21BE35FCCC12CD12C6F -:10448000E12CF12C8ECCCBA8DCA85DCDC114D104DD -:1044900009F45CC0F601C580D680E780F084BDE5F4 -:1044A000B89DF001B99DF00D1124E356F64F8081BF -:1044B00081FD28C0618972898389948990589B0104 -:1044C000AC010F94083EEBA9FCA9258536854785EC -:1044D00050890F94173A9B01AC01C701B6010F94A4 -:1044E000073E6B018DAF99AF9B01AC016B2D702F17 -:1044F0008A2D932D0F94B13987FD04C0BC2C0D2D4E -:10450000ADAC39AC2B2D302F4A2D532DC301B20148 -:104510000F94B139882309F44FCDFDE5F89DC00112 -:10452000F99D900D11249C012356364F6901D90144 -:104530008C9181608C938BA99CA90E9481708823A7 -:1045400019F1F60180818E7F808336CDAA96AEADBB -:10455000BFADAA971896CD90DD90ED90FC901B977B -:104560002BE037ED43E25BE3C701B6010F946840EF -:1045700018160CF494CF9BE0C92E97EDD92E93E238 -:10458000E92E9BE3F92E8BCF8B2D902FAA2DB32DE7 -:10459000F60185839683A783B0870ECDDCAACBAACC -:1045A0000BCD10910816F12CE12C0DE58091091628 -:1045B000811709F490C0812E912C109FC001112405 -:1045C0009C012356364F3CAB2BABC9010E946A724B -:1045D000882309F47DC0E114F10409F46AC0C7011D -:1045E0000E948170811165C0D7018C9181FD4CC002 -:1045F000089DC001099D900D1124AC014356564FF2 -:104600001A01DA0115964D905D906D907C90189787 -:10461000F701A580B680C780D084A3019201C601AE -:10462000B5010F94B13987FF2FC0D70151966D9115 -:104630007D918D919C91549790589B01AC010F9462 -:10464000083EF70125853685478550890F94173A2E -:104650009B01AC01C601B5010F94073E6B017C01C3 -:10466000A30192010F94B13987FF0EC0D1018C9143 -:1046700081608C938BA99CA90E9481708823F1F0A2 -:10468000F10180818E7F8083089DF001099DF00DEE -:104690001124E356F64F2185328543855485658183 -:1046A0007681878190850F94B139811102C0109372 -:1046B00008161F5F1F70EBA8FCA878CFD1011596D4 -:1046C000CD92DD92ED92FC92189710930816DCCFF4 -:1046D000FCAAEBAAEECFF0900A16E09009160DE5C1 -:1046E000FE1409F480C01FEF1E0D1F70109FC00143 -:1046F00011248356964F0E946A72882309F471C070 -:10470000A12CB12C1BAA1DAE10E000E0FE1409F490 -:1047100071C0BDE5FB9EC0011124FC01E356F64FBC -:104720006F01CF010E946A72882309F45EC0D6012E -:1047300015966D917D918D919C9118970F94B6402F -:104740003B014C010115110509F442C0F6018081BD -:1047500080FF04C0D8018C9181608C93F801808126 -:1047600080FF36C0C8010E94817081112DC0D80120 -:1047700011962D913D914D915C91149760E070E000 -:1047800080E89FE30F94023F1B012C01AC019B01C9 -:10479000B301C4010F94173A69837A838B839C8396 -:1047A00095014BA95DADC201B1010F94173A698B18 -:1047B0007A8B8B8B9C8BAE014F5F5F4FBE016F5E20 -:1047C0007F4FC8010E944C77F80180818E7F8083E3 -:1047D000F394FF2DFF70FF2E53018BAA9DAE86012F -:1047E00095CFE12E7DCFEF2C8BCF35018BA89DACE3 -:1047F0006801EECF0115110509F456C0AA96AEADB9 -:10480000BFADAA9718966D917D918D919C911B9744 -:104810000F94B6406B017C012DEC3CEC4CE45DE365 -:104820000F946840181644F08DECC82E8CECD82EEE -:104830008CE4E82E8DE3F82EF8018081816080837E -:10484000C8010E94817081112BC0D80111962D9151 -:104850003D914D915C91149760E070E080E89FE39A -:104860000F94023F2B013C01A70196010F94173AC8 -:1048700069837A838B839C83A3019201B5018BA901 -:104880009DAD0F94173A698B7A8B8B8B9C8BAE0105 -:104890004F5F5F4FBE016F5E7F4FC8010E944C7734 -:1048A000F80180818E7F80830E94499581E0C05805 -:1048B000DF4F0FB6F894DEBF0FBECDBFDF91CF91B3 -:1048C0001F910F91FF90EF90DF90CF90BF90AF902E -:1048D0009F908F907F906F905F904F903F902F9020 -:1048E000089580E0E4CFE0909909F0909A09009152 -:1048F0009B0910919C099701A80168966FAD689774 -:104900002C967FAD2C97A0968FADA097932D0F94EA -:10491000B13987FD0AC06896EFAC68972C96FFAC5A -:104920002C97A0960FADA097132D8DE5ABA9BCA930 -:104930008A9FF0018B9FF00D1124E356F64F2585D9 -:1049400036854785508960E070E080E89FE30F94EA -:10495000023F2B013C019701A8010F94173A6B010C -:104960007C018091091690910716891B8F70A09683 -:104970008FAFA097A701960160E074E284E799E405 -:104980000F94023F0F9475404B015C01A0968FADD0 -:10499000A09782508630B0F56091650970916609E4 -:1049A0008091670990916809681979098A099B09BA -:1049B00016161706180619062CF5660F771F881F9E -:1049C000991FA096BFADA0972B2F30E050E040E09C -:1049D0000F94C63DCA01B9010F94B8390F94743FC2 -:1049E000860E971EA81EB91EC501B4010F94B839D2 -:1049F0009B01AC0160E074E284E799E40F94023F0C -:104A00006B017C010E943C954091CE055091CF05F1 -:104A10006091D0057091D105480D591D6A1D7B1D0F -:104A20004093CE055093CF056093D0057093D10588 -:104A30009DE52BA93CA9929FF001939FF00D1124B5 -:104A4000EA50F64F80829182A282B38281110E9445 -:104A500049958DE54BA95CA9849F8001859F100D28 -:104A600011240356164FD8011D962D913D914D915D -:104A70005C915097C701B6010F94173AA4966CAF9A -:104A80007DAF8EAF9FAFA497F8016183728383835C -:104A9000948325A136A147A150A527962CAF3DAF01 -:104AA0004EAF5FAF2797CA01B9010F94B6396B9625 -:104AB0006CAF7DAF8EAF9FAF6B979B01AC01C70111 -:104AC000B6010F94173A0F94E63E0F947B3FAE96D3 -:104AD0006CAF7DAF8EAF9FAFAE97F801E95BFF4F34 -:104AE0006083718382839383FE01B1962D96FFAF1D -:104AF000EEAF2D9729E739E0E4963FAF2EAFE4976C -:104B0000AE01435D5F4F5AAB49AB212C312C50E8CD -:104B10005DAB8FE38FAF2D96AEADBFAD2D972D91D1 -:104B20003D914D915D912D96BFAFAEAF2D97C701D1 -:104B3000B6010F94173A4B015C0120E030E0A90167 -:104B40000F94684087FF04C0B7FAB094B7F8B094E8 -:104B5000E496AEADBFADE4972D913D914D915D9141 -:104B6000E496BFAFAEAFE497E2962CAF3DAF4EAF49 -:104B70005FAFE297A5019401E2966CAD7DAD8EAD7D -:104B80009FADE2970F94B13987FF16C0A50194013C -:104B9000E2966CAD7DAD8EAD9FADE2970F94023F76 -:104BA0005B018C0191014DA95FAD0F94B13987FF75 -:104BB00003C015010DAB1FAFE9A9FAA92D962EADC3 -:104BC0003FAD2D97E217F30709F0A5CFA701960196 -:104BD00069AD7AAD8BAD9CAD0F94173A6B017C013A -:104BE00020E030E0A9010F94684087FF04C0F7FA85 -:104BF000F094F7F8F0948090850990908609A09041 -:104C00008709B0908809A7019601C501B4010F94E6 -:104C1000B13987FF12C0A7019601C501B4010F94F5 -:104C2000023F7B018C0191014DA95FAD0F94B13919 -:104C300087FF03C017010DAB1FAF20E030E040E855 -:104C40005FE3B1018DA99FAD0F94B13987FF33C0E8 -:104C50008DE54BA95CA9849F8001859F100D1124CF -:104C60000356164F780157E4E50EF11CAE966CAD75 -:104C70007DAD8EAD9FADAE970F94B63991014DA924 -:104C80005FAD0F94173A0F947B3FD7016D937D93DF -:104C90008D939C93139791014DA95FADA4966CAD34 -:104CA0007DAD8EAD9FADA4970F94173AF801618347 -:104CB0007283838394836B962CAD3DAD4EAD5FAD17 -:104CC0006B97C301B2010F94173AA4966CAF7DAFF6 -:104CD0008EAF9FAFA4978DE52BA93CA9829FF001D1 -:104CE000839FF00D1124E356F64F85889688A78898 -:104CF000B08C81149104A104B10411F00C94DB9ADE -:104D0000818D928DA38DB48D892B8A2B8B2B11F0E5 -:104D10000C94DB9A858D968DA78DB0A1892B8A2B5B -:104D20008B2B11F00C94DB9A20918D0930918E0918 -:104D300040918F0950919009A4966CAD7DAD8EADD8 -:104D40009FADA4970F94173A0F94E63E0F947B3FC4 -:104D50006B017C010C94D39BCF93DF93CDB7DEB76F -:104D600060970FB6F894DEBF0FBECDBFFC0190E197 -:104D7000DE01119601900D929A95E1F780914C0910 -:104D800090914D09892B69F4CE0101960E94D69627 -:104D900060960FB6F894DEBF0FBECDBFDF91CF9106 -:104DA000089580E0F5CFCF93DF93CDB7DEB72C9792 -:104DB0000FB6F894DEBF0FBECDBF19821A821B82D8 -:104DC0001C821D821E821F82188619861A861B86E7 -:104DD0001C869E012F5F3F4F40915109BC0186E721 -:104DE00092E00E94ACA62C960FB6F894DEBF0FBEE0 -:104DF000CDBFDF91CF9108954F925F926F927F92D6 -:104E00008F929F92AF92BF92CF92DF92EF92FF92DA -:104E10000F931F93CF93DF93CDB7DEB72C970FB6C9 -:104E2000F894DEBF0FBECDBF2B013C0129873A8726 -:104E30004B875C8747015801F601E080F1800281D1 -:104E4000138120E030E0A901B701C8010F94B13906 -:104E5000882309F484C05E2D4F2D302F212F852FFC -:104E6000942FA32FB22F89839A83AB83BC8320E036 -:104E700030E0A901B701C8010F94B139811104C014 -:104E8000E12CF12C00E810E4C701D8018D839E834A -:104E9000AF83B887A501940160917E0270917F0273 -:104EA00080918002909181020F94B13987FF0CC0EC -:104EB00080927E0290927F02A0928002B092810244 -:104EC000CE0105960E94D3A64092760250927702B8 -:104ED000609278027092790289859A85AB85BC854B -:104EE00080937A0290937B02A0937C02B0937D0220 -:104EF000CE0101960E94D3A6A501940160917E0285 -:104F000070917F0280918002909181020F9468409D -:104F1000181664F480927E0290927F02A092800222 -:104F2000B0928102CE0105960E94D3A60E947F8F87 -:104F30002C960FB6F894DEBF0FBECDBFDF91CF9198 -:104F40001F910F91FF90EF90DF90CF90BF90AF90A7 -:104F50009F908F907F906F905F904F90089550E05A -:104F600040E035E023E47BCF0E943C951092CE05D3 -:104F70001092CF051092D0051092D10581110C949A -:104F8000499508950F931F938091091690910A16E1 -:104F9000891B8F7009F449C090910616992361F01E -:104FA000833040F48FEF890F29F08093061690E04C -:104FB00080E038C01092061680910A162DE5829F77 -:104FC000C00111248356964FFC01208120FDEFCFB4 -:104FD0004091CE055091CF056091D0057091D105DB -:104FE000E75AFF4F0081118122813381401B510B11 -:104FF000620B730B4093CE055093CF056093D005A1 -:105000007093D10520910A162F5F2F7020930716F9 -:1050100030910A1620910816321304C02091071609 -:10502000209308161F910F9108950E94B4A7BFCF37 -:105030002F923F924F925F926F927F928F929F92A8 -:10504000AF92BF92CF92DF92EF92FF920F931F9396 -:10505000CF93DF93CDB7DEB765970FB6F894DEBF79 -:105060000FBECDBF8FEF9FEF909389008093880094 -:105070000AE00983712C612C789480919C079091AF -:105080009D07A0919E07B0919F07892B8A2B8B2BA0 -:1050900009F0EFC18091A2078823D1F08091A00789 -:1050A0009091A1071092A207892B91F01092A1076D -:1050B0001092A007109293079091091680910A16FA -:1050C000981731F080910A168F5F8F7080930A16BF -:1050D0008091A0079091A107892B09F4CAC1409142 -:1050E00098075091990760919A0770919B0780915A -:1050F000940790919507A0919607B091970700911A -:105100008A0710E030E020E0841B950BA60BB70B5C -:10511000081719072A073B0710F4D901C801E82F1F -:10512000840F951FA61FB71F809398079093990728 -:10513000A0939A07B0939B07F1E0409161075091CB -:105140006207609163077091640780917107909185 -:105150007207A0917307B0917407840F951FA61F63 -:10516000B71F8093710790937207A0937307B09352 -:1051700074071C012D0120943094409450942224F3 -:1051800057FC23943324442455242A82B7FD2FC08E -:1051900000915807002E000C110B220B330B40918D -:1051A000AF075091B0076091B1077091B207400FFF -:1051B000511F621F731F4093AF075093B007609356 -:1051C000B1077093B20740915D0750915E076091FF -:1051D0005F0770916007841B950BA60BB70B80933C -:1051E000710790937207A0937307B093740740916F -:1051F0006507509166076091670770916807809115 -:10520000750790917607A0917707B0917807840F82 -:10521000951FA61FB71F8093750790937607A093DD -:105220007707B09378078C019D0100951095209524 -:105230003095002737FD03951127222733270C8B44 -:10524000B7FD2FC0C09059070C2C000CDD08EE08EC -:10525000FF084091B3075091B4076091B507709172 -:10526000B6074C0D5D1D6E1D7F1D4093B307509317 -:10527000B4076093B5077093B60740915D075091EE -:105280005E0760915F0770916007841B950BA60B0A -:10529000B70B8093750790937607A0937707B09329 -:1052A00078074091690750916A0760916B07709188 -:1052B0006C078091790790917A07A0917B07B09154 -:1052C0007C07840F951FA61FB71F809379079093C3 -:1052D0007A07A0937B07B0937C07AC01BD01409592 -:1052E000509560957095442777FD4395552766271F -:1052F00077274B8BB7FD2FC080905A07082C000CE6 -:105300009908AA08BB08C090B707D090B807E090EA -:10531000B907F090BA07C80CD91CEA1CFB1CC09254 -:10532000B707D092B807E092B907F092BA07C090D9 -:105330005D07D0905E07E0905F07F09060078C19E2 -:105340009D09AE09BF098093790790937A07A093CE -:105350007B07B0937C07C0906D07D0906E07E090FC -:105360006F07F090700780917D0790917E07A09164 -:105370007F07B09180078C0D9D1DAE1DBF1D8093D2 -:105380007D0790937E07A0937F07B0938007B7FDBA -:10539000F2C080905B07082C000C9908AA08BB0893 -:1053A000C090BB07D090BC07E090BD07F090BE074F -:1053B000C80CD91CEA1CFB1CC092BB07D092BC07CE -:1053C000E092BD07F092BE07C0905D07D0905E07E7 -:1053D000E0905F07F09060078C199D09AE09BF0946 -:1053E00080937D0790937E07A0937F07B0938007FB -:1053F000A1E0F11104C080918400909185008A8120 -:105400008111889A9C8991118E9ABB89BB2331F0B6 -:1054100080910B018095887080930901AA2329F05F -:1054200080915C078111A9C0149A809184009091A9 -:105430008500809184009091850021108898011149 -:105440008E98442329F080910B0188708093090184 -:10545000AA2329F080915C07811191C01498EE2352 -:1054600021F08091840090918500E150F0E009F0F6 -:1054700064CE80919C0790919D07A0919E07B0916A -:105480009F07892B8A2B8B2B11F00C941EB1E09176 -:10549000A007F091A107FD8BEC8BEF2B11F40C947E -:1054A00090B18091980790919907A0919A07B09137 -:1054B0009B074091940750919507609196077091D2 -:1054C000970784179507A607B70708F45AC01092E4 -:1054D000A1071092A007109293079091091680914E -:1054E0000A16981711F40C9490B180910A168F5FE8 -:1054F0008F7080930A1630EDC32E37E0D32EE12C47 -:10550000F12C8091A0079091A107892B11F00C94A8 -:1055100016B10E94C2A79093A1078093A007892B80 -:1055200011F40C9416B1A091A007B091A107BD8B06 -:10553000AC8B9C9193FB882780F993FF0E94E770C6 -:10554000882309F412C58C899D8945960E9478703C -:105550001092A1071092A00710929307909109163C -:1055600080910A169817A9F280910A168F5F8F70A2 -:1055700080930A16CECFA0E03CCF419A56CF4198F7 -:105580006ECF40918F075091900760919107709175 -:105590009207481759076A077B0708F40FC2409122 -:1055A0008B0750918C0760918D0770918E07EC8965 -:1055B000FD8986A997A9A0ADB1AD481759076A071B -:1055C0007B0708F0D1C1411551056105710509F04E -:1055D00066C08090070690900806A0900906B090DB -:1055E0000A0683E992E2A1E0FC010591159125915B -:1055F0003491081519052A053B0558F4B694A7946B -:1056000097948794AA0F0496EFEAF2E2E817F90755 -:1056100059F7A0938A07F0E28F169104A104B10410 -:1056200028F480E2882E912CA12CB12C00E2801A63 -:105630009108A108B108811428E09206A104B104E0 -:1056400008F49BC134E0939EC00111248D56914E05 -:10565000FC01329625913491A82DEE27A39F80015D -:10566000A29F010D1E1F06940E1F1E1F112430E065 -:1056700020E0FC01C590D490F12CE12CC01AD10A95 -:10568000E20AF30A4C0D5D1D6E1D7F1D40938B07D2 -:1056900050938C0760938D0770938E0732CF10E084 -:1056A000942F852E862FBD81AE81FF81E8853985B7 -:1056B0002A85FB800C81E0910306E99FA12DFF273D -:1056C00030910406399FA00DF11D10900506199E1A -:1056D000F00DE89DA00DF11D389DF00DE89FF00D37 -:1056E0000A2FBF2F0A9FE12D332722270F9FE00D9E -:1056F000311D211FBA9FE00D311D211FBF9F300DAD -:10570000211D032FB22F0A9FF12C332722270F9F31 -:10571000F00C311D211FBA9FF00C311D211FBF9FBE -:10572000300D211D032FB22FEE2790910706809098 -:1057300008068091090600900E08012A09F484C029 -:1057400030910A08309FE119910B810A810B209159 -:105750000B08209FE0199109810A810BF0900C0839 -:10576000F09E90198108810B3B9FE0199109810AF5 -:10577000810B2B9F90198108810BFB9E801881095A -:105780000A9FF12C332722270F9FF00C311D211F78 -:10579000BA9FF00C311D211FBF9F300D211D032F1B -:1057A000B22F30910608309FE10D911F811E811F9D -:1057B00020910708209FE00D911D811E811FF09010 -:1057C0000808F09E900D811C811F3B9FE00D911DEC -:1057D000811E811F2B9F900D811C811FFB9E800CC1 -:1057E000811D0A9FF12C332722270F9FF00C311DBA -:1057F000211FBA9FF00C311D211FBF9F300D211DAD -:10580000032FB22F30910208309FE119910B810ACA -:10581000810B20910308209FE0199109810A810BD7 -:10582000F0900408F09E90198108810B3B9FE019CD -:105830009109810A810B2B9F90198108810BFB9E96 -:10584000801881090C94A6AC30910A08309FE10DB4 -:10585000911F811E811F20910B08209FE00D911D3B -:10586000811E811FF0900C08F09E900D811C811FFD -:105870003B9FE00D911D811E811F2B9F900D811C70 -:10588000811FFB9E800C811D0A9FF12C332722274C -:105890000F9FF00C311D211FBA9FF00C311D211FED -:1058A000BF9F300D211D032FB22F30910608309F6E -:1058B000E119910B810A810B20910708209FE019C3 -:1058C0009109810A810BF0900808F09E90198108D7 -:1058D000810B3B9FE0199109810A810B2B9F901945 -:1058E0008108810BFB9E801881090A9FF12C3327C8 -:1058F00022270F9FF00C311D211FBA9FF00C311D84 -:10590000211FBF9F300D211D032FB22F30910208A0 -:10591000309FE10D911F811E811F20910308209F60 -:10592000E00D911D811E811FF0900408F09E900DE6 -:10593000811C811F3B9FE00D911D811E811F2B9FAC -:10594000900D811C811FFB9E800C811D11240C83F6 -:10595000FB82BD83AE83FF83E88739872A87982C33 -:10596000892EB12CA82E3DCEAC89BD89D2968D90C2 -:105970009D90AD90BC90D59734CED501C401B6951D -:10598000A795979587958C7F8D56954EFC01C59070 -:10599000D490FC01329625913491B82DB770B29F06 -:1059A000C001B39F900D112403E0969587950A9549 -:1059B000E1F7C81AD90AF12CE12C64CE4091860790 -:1059C0005091870760918807709189074817590798 -:1059D0006A077B0708F031C28090810790908207A8 -:1059E000A0908307B090840780918507EC89FD899A -:1059F00081117CC0EE5BFF4FE080F180028113815A -:105A0000EC89FD89E15BFF4F208131814281538127 -:105A1000EC89FD8962A973A984A995A90E94957052 -:105A2000F1E0F0938507AC89BD89D2964D915D91E7 -:105A30006D917C91D59783E992E2A1E0FC010591FB -:105A4000159125913491041715072607370758F447 -:105A50007695679557954795AA0F0496EFEAF2E277 -:105A6000E817F90759F7A0938A07403251056105F5 -:105A7000710520F440E250E060E070E040525109CE -:105A8000610971094115F8E05F076105710508F4C6 -:105A9000B4C104E0509FC00111248D56914EFC0109 -:105AA000329625913491AA27439FF001429FE10D40 -:105AB000FA1F0694EA1FFA1F1124AF0170E060E09C -:105AC000FC01C590D490F12CE12CC41AD50AE60A49 -:105AD000F70A8C0C9D1CAE1CBF1C80928107909213 -:105AE0008207A0928307B09284070BCD82AD93AD5D -:105AF000A4ADB5AD88169906AA06BB0608F073C119 -:105B000081149104A104B10449F440910706509115 -:105B100008066091090670910A068DCFA0E0FB850A -:105B2000982D492D8A2DEC857D856E85BF855889F8 -:105B300039892A8950910306599F612DBB273091DD -:105B40000406399F600DB11D10900506199EB00D19 -:105B5000549F600DB11D349FB00D589FB00DE62FBE -:105B60007B2FE69F512D33272227EB9F500D311DB0 -:105B70002A1F769F500D311D2A1F7B9F300D211D3E -:105B8000E32F722FE69FF12D33272227EB9FF00D95 -:105B9000311D2A1F769FF00D311D2A1F7B9F300D6E -:105BA000211DE32F722F552790910706409108067B -:105BB0008091090600900E080A2A09F484C03091E9 -:105BC0000A083E9F51199A0B4A0B8A0B20910B0829 -:105BD0002E9F501991094A0B8A0BF0910C08FE9FD9 -:105BE000901941098A0B379F501991094A0B8A0B6A -:105BF000279F901941098A0BF79F40198109E69F59 -:105C0000F12D33272227EB9FF00D311D2A1F769FA0 -:105C1000F00D311D2A1F7B9F300D211DE32F722FA8 -:105C2000309106083E9F510D9A1F4A1F8A1F2091EE -:105C300007082E9F500D911D4A1F8A1FF0910808DA -:105C4000FE9F900D411D8A1F379F500D911D4A1FC9 -:105C50008A1F279F900D411D8A1FF79F400D811DB0 -:105C6000E69FF12D33272227EB9FF00D311D2A1FD0 -:105C7000769FF00D311D2A1F7B9F300D211DE32FD4 -:105C8000722F309102083E9F51199A0B4A0B8A0BD2 -:105C9000209103082E9F501991094A0B8A0BF0910D -:105CA0000408FE9F901941098A0B379F50199109EA -:105CB0004A0B8A0B279F901941098A0BF79F4019BD -:105CC00081090C94E5AE30910A083E9F510D9A1F50 -:105CD0004A1F8A1F20910B082E9F500D911D4A1FAD -:105CE0008A1FF0910C08FE9F900D411D8A1F379F5F -:105CF000500D911D4A1F8A1F279F900D411D8A1F1D -:105D0000F79F400D811DE69FF12D33272227EB9F42 -:105D1000F00D311D2A1F769FF00D311D2A1F7B9F2C -:105D2000300D211DE32F722F309106083E9F51192F -:105D30009A0B4A0B8A0B209107082E9F5019910944 -:105D40004A0B8A0BF0910808FE9F901941098A0BB3 -:105D5000379F501991094A0B8A0B279F90194109C7 -:105D60008A0BF79F40198109E69FF12D33272227DF -:105D7000EB9FF00D311D2A1F769FF00D311D2A1F5C -:105D80007B9F300D211DE32F722F309102083E9F23 -:105D9000510D9A1F4A1F8A1F209103082E9F500DF4 -:105DA000911D4A1F8A1FF0910408FE9F900D411D0E -:105DB0008A1F379F500D911D4A1F8A1F279F900DE4 -:105DC000411D8A1FF79F400D811D1124FB87EC8721 -:105DD0007D876E87BF87588B398B2A8B542F492F2D -:105DE00070E0682F28CE2C893D89215B3F4FD90177 -:105DF0004D915D916D917C911ECEDB01CA01B695EE -:105E0000A795979587958C7F8D56954EFC01C590EB -:105E1000D490FC013296259134914770429FC00185 -:105E2000439F900D1124F3E096958795FA95E1F73D -:105E3000C81AD90AF12CE12C4CCE809130029091F5 -:105E40003102A0913202B0913302B7FF62C02C89B7 -:105E50003D89295B3F4FD901CD90DD90ED90FC90BD -:105E600083E992E221E0FC0145915591659174919D -:105E70004C155D056E057F0558F4F694E794D794AC -:105E8000C794220F0496EFEAF2E2E817F90759F7F0 -:105E900020938A07F0E2CF16D104E104F10428F43C -:105EA00060E2C62ED12CE12CF12C00E2C01AD10800 -:105EB000E108F108C11428E0D206E104F10408F475 -:105EC00031C034E0D39EC00111248D56914EFC01A7 -:105ED0003296259134917C2D6627739FA001729F85 -:105EE000410D561F0694461F561F112470E060E0B6 -:105EF000FC0185919491B0E0A0E0841B950BA60B6A -:105F0000B70B8093300290933102A0933202B0938A -:105F10003302C0903002D0903102E0903202F09013 -:105F20003302EFCAD701C601B695A7959795879515 -:105F30008C7F8D56954EFC0125913491FC01329653 -:105F4000459154918C2D8770C82EC49EC001C59E6A -:105F5000900D112453E0969587955A95E1F7281BEB -:105F6000390BC901B0E0A0E0CCCFEC89FD89C58830 -:105F7000D688E788F08C81E0C114D104E104F104F3 -:105F800009F480E0AC89BD8959960D911D912D9140 -:105F90003C915C97011511052105310509F08260DE -:105FA000EC89FD89458D568D678D70A14115510590 -:105FB0006105710509F08460809393071092810751 -:105FC00010928207109283071092840710928B0719 -:105FD00010928C0710928D0710928E07EC89FD8924 -:105FE00085A196A1A7A1B0A580939407909395074A -:105FF000A0939607B0939707882499245401881A90 -:10600000990AAA0ABB0A8092710790927207A0921D -:106010007307B09274078092750790927607A092EA -:106020007707B09278078092790790927A07A092CA -:106030007B07B0927C0780927D0790927E07A092AA -:106040007F07B092800781A092A0A3A0B4A0880C83 -:10605000991CAA1CBB1CCC0CDD1CEE1CFF1CC092A6 -:106060006107D0926207E0926307F0926407000F25 -:10607000111F221F331F009365071093660720939B -:10608000670730936807440F551F661F771F4093BB -:10609000690750936A0760936B0770936C0780924F -:1060A0006D0790926E07A0926F07B0927007880FED -:1060B000991FAA1FBB1F80935D0790935E07A09353 -:1060C0005F07B0936007109298071092990710929B -:1060D0009A0710929B0782A593A5A4A5B5A58093C6 -:1060E0008F0790939007A0939107B093920786A58E -:1060F00097A5A0A9B1A98093860790938707A0933D -:106100008807B093890781A580935C07EA5BFF4FFE -:1061100090812091E508921304C020912F028217EC -:1061200031F080932F029093E5080E945A88809165 -:10613000E30881110E946F952FEF3FEFA901209393 -:106140003002309331024093320250933302EC8993 -:10615000FD89FE96E080F18002811381AC89BD89C2 -:10616000D2962D913D914D915C91D597A55BBF4FF6 -:10617000BD8BAC8B6D917D918D919C910E949570A2 -:1061800010928507EC89FD8940815181628173817C -:1061900083E992E2A1E0FC010591159125913491EA -:1061A000041715072607370758F47695679557950E -:1061B0004795AA0F04962FEA32E22817390759F7B4 -:1061C000A0938A07403251056105710520F440E231 -:1061D00050E060E070E040525109610971094115D9 -:1061E00038E053076105710508F478C0A4E05A9FB0 -:1061F000C00111248D56914EFC01329625913491A7 -:10620000AA27439FF001429FE10DFA1F0694EA1F5F -:10621000FA1F1124AF0170E060E0FC01C590D4903A -:10622000F12CE12CC41AD50AE60AF70AC0929C07A1 -:10623000D0929D07E0929E07F0929F0780919C0765 -:1062400090919D07A0919E07B0919F07AC01BD0161 -:106250000097E1E0AE07B10520F04FEF5FEF60E09F -:1062600070E0841B950BA60BB70B80939C07909353 -:106270009D07A0939E07B0939F07F8948091840098 -:10628000909185004096F981F150F983FF2309F43C -:1062900045C0640E751E6816790610F40C943CA86F -:1062A0007092890060928800789465960FB6F89491 -:1062B000DEBF0FBECDBFDF91CF911F910F91FF9039 -:1062C000EF90DF90CF90BF90AF909F908F907F9096 -:1062D0006F905F904F903F902F900895DB01CA011F -:1062E000B695A795979587958C7F8D56954EFC0111 -:1062F000C590D490FC013296259134914770429F0D -:10630000C001439F900D112433E0969587953A95EF -:10631000E1F7C81AD90AF12CE12C88CF3C01C0CF93 -:1063200080EDC82E87E0D82EE12CF12C0C9489AAA0 -:10633000FC01208131814281538160917509709106 -:10634000760980917709909178090F94173A0F9404 -:10635000754060932B1670932C1680932D16909396 -:106360002E169091091680910A1698130D9481119A -:106370000E947F8F0E943C9540912B1650912C16C5 -:1063800060912D1670912E164093BB075093BC0759 -:106390006093BD077093BE0781110C9449950895D1 -:1063A0004F925F926F927F928F929F92AF92BF9225 -:1063B000CF92DF92EF92FF92CF93DF93EC01209187 -:1063C00075093091760940917709509178096C856B -:1063D0007D858E859F850F94173A0F9475406B01CC -:1063E0007C0120917109309172094091730950919B -:1063F0007409688579858A859B850F94173A0F946F -:1064000075404B015C0120916D0930916E094091FE -:106410006F09509170096C817D818E819F810F94ED -:10642000173A0F9475402B013C0120916909309176 -:106430006A0940916B0950916C09688179818A8160 -:106440009B810F94173A0F94754060931F167093B9 -:106450002016809321169093221640922316509274 -:106460002416609225167092261680922716909216 -:106470002816A0922916B0922A16C0922B16D092F6 -:106480002C16E0922D16F0922E16909109168091FE -:106490000A16981781F0DF91CF91FF90EF90DF906F -:1064A000CF90BF90AF909F908F907F906F905F90B4 -:1064B0004F900D9481110E947F8F0E943C95C82FB0 -:1064C0008FE196E10E947870CC2381F0DF91CF912B -:1064D000FF90EF90DF90CF90BF90AF909F908F9004 -:1064E0007F906F905F904F900C944995DF91CF9182 -:1064F000FF90EF90DF90CF90BF90AF909F908F90E4 -:106500007F906F905F904F900895CF92DF92EF92BF -:10651000FF92CF93DF93C82F0E943C9594E0C99FD0 -:10652000E0011124FE01E155F84FC080D180E280E6 -:10653000F38081110E944995C55DD84FC701B6010E -:106540000F94B839288139814A815B810F94173AB9 -:10655000DF91CF91FF90EF90DF90CF900895CF9291 -:10656000DF92EF92FF92CF93DF93C82F0E943C956A -:1065700094E0C99FE0011124FE01ED55F84FC08061 -:10658000D180E280F38081110E944995C55DD84F8A -:10659000C701B6010F94B839288139814A815B81DE -:1065A0000F94173ADF91CF91FF90EF90DF90CF904B -:1065B0000895FC017081472F50E0062E02C05595CA -:1065C00047950A94E2F740FF14C04091010850E05B -:1065D000062E02C0559547950A94E2F740FF09C080 -:1065E00021E030E001C0220F6A95EAF720952723C9 -:1065F00020830895CF93DF9324E0829FC00111246C -:10660000EC01C359D04FFC01EA51F74F86559A4F20 -:10661000DC012D913D914D915C9160817181828170 -:1066200093810F94083E688379838A839B83DF91EB -:10663000CF9108958F929F92AF92BF92CF92DF92A7 -:10664000EF92FF92CF93DF9320913702222309F438 -:106650008EC0EC0180910108E82E80FF2CC0809054 -:10666000390290903A02A0903B02B0903C022881FF -:1066700039814A815B81C501B4010F9468401816C5 -:1066800024F488829982AA82BB82809045029090ED -:106690004602A0904702B0904802288139814A8181 -:1066A0005B81C501B4010F94B13987FF04C08882B2 -:1066B0009982AA82BB82E1FE2CC080903D0290901C -:1066C0003E02A0903F02B09040022C813D814E815D -:1066D0005F81C501B4010F946840181624F48C82C0 -:1066E0009D82AE82BF828090490290904A02A09023 -:1066F0004B02B0904C022C813D814E815F81C501DF -:10670000B4010F94B13987FF04C08C829D82AE82A0 -:10671000BF82E2FE2CC0C0904102D0904202E090C5 -:106720004302F0904402288539854A855B85C7017C -:10673000B6010F946840181624F4C886D986EA86F4 -:10674000FB86C0904D02D0904E02E0904F02F09038 -:106750005002288539854A855B85C701B6010F94AB -:10676000B13987FF04C0C886D986EA86FB86DF91E7 -:10677000CF91FF90EF90DF90CF90BF90AF909F9020 -:106780008F900895CF92DF92EF92FF921F93CF9355 -:10679000DF93CDB7DEB760970FB6F894DEBF0FBEBC -:1067A000CDBF8AE896E00E941AB38091D40583FD9C -:1067B00076C02091820230918302409184025091F0 -:1067C0008502609196067091970680919806909147 -:1067D00099060F94B139882309F461C08091510959 -:1067E0000E940CCD182F882331F00E940FD88BE91E -:1067F00094E10E94ACCE20918202309183024091BC -:10680000840250918502609196067091970680915E -:106810009806909199060F94073E6B017C0120E049 -:1068200030E0A9010F94684087FF04C0F7FAF094A4 -:10683000F7F8F094E091510984E0E89FF001112409 -:10684000EA5DFD4F2081318142815381C701B6014C -:106850000F94173A20E030E048E453E40F94684086 -:106860001816DCF40E940FD88CE794E10E94ACCE9D -:106870008091960690919706A0919806B0919906FE -:106880008093820290938302A0938402B093850246 -:1068900086E996E00E9498B102C01111E9CF2AE082 -:1068A00037ED43E25CE360915102709152028091B6 -:1068B0005302909154020F94173A6B017C0160913E -:1068C000200270912102072E000C880B990B0F9467 -:1068D000B8399B01AC01C701B6010F94173A6D8717 -:1068E0007E878F87988B19821A821B821C821D8259 -:1068F0001E821F82188619861A861B861C869E0198 -:106900002F5F3F4F40915109BE01635F7F4F8AE87F -:1069100096E00E94ACA680E1EAE8F6E0A6E7B2E0E5 -:1069200001900D928A95E1F760960FB6F894DEBF5C -:106930000FBECDBFDF91CF911F91FF90EF90DF9001 -:10694000CF900895CF92DF92EF92FF920F931F9313 -:106950006A01E0907E02F0907F0200918002109127 -:106960008102FB012081318142815381FC016081E0 -:106970007181828193810E94FCA61F910F91FF90EB -:10698000EF90DF90CF900895CF92DF92EF92FF9239 -:106990000F931F936B01FC01E080F1800281138152 -:1069A000E6E7F2E02481358146815781608171817B -:1069B000828193810E94FCA61F910F91FF90EF901E -:1069C000DF90CF9008958F929F92AF92BF92CF9217 -:1069D000DF92EF92FF92CF93DF93809051029090DD -:1069E0005202A0905302B0905402FC01C080D180AA -:1069F000E280F38020E030E0A901C701B6010F94E6 -:106A0000B139882341F0C0925102D0925202E092F3 -:106A10005302F0925402C0912002D091210284E6E8 -:106A200090E09093210280932002E091510984E04C -:106A3000E89FF0011124EA5DFD4FC080D180E28023 -:106A4000F38080E090E0A0E8BFE380839183A2839D -:106A5000B3830E94C2B38092510290925202A092DC -:106A60005302B0925402D0932102C0932002E091CD -:106A7000510984E0E89FF0011124EA5DFD4FC082D6 -:106A8000D182E282F382DF91CF91FF90EF90DF908D -:106A9000CF90BF90AF909F908F9008950F931F93CA -:106AA000CF93DF938B01C6E7D2E0E091510924E058 -:106AB000E29FF0011124EA5DFD4F20813181428186 -:106AC0005381FC0160817181828193810F94023F27 -:106AD0002C853D854E855F850F94083E6C877D87AC -:106AE0008E879F87C8010E94D3A6DF91CF911F9107 -:106AF0000F910C947F8F0D94BA114F925F926F9209 -:106B00007F928F929F92AF92BF92CF92DF92EF923D -:106B1000FF920F931F93CF93DF93CDB7DEB72C97E0 -:106B20000FB6F894DEBF0FBECDBF182F062F0E9400 -:106B30007F8F123048F10E940FD884E50E949FCECB -:106B4000612F70E090E080E00F94C00D80E20E9421 -:106B50009FCE86E793E20E94ACCE2C960FB6F894B7 -:106B6000DEBF0FBECDBFDF91CF911F910F91FF9080 -:106B7000EF90DF90CF90BF90AF909F908F907F90DD -:106B80006F905F904F900895011108C080910108A7 -:106B90008770873009F032C10E94446BF090510930 -:106BA0001F1509F422C180E1E6E7F2E0AAE8B6E0A9 -:106BB00001900D928A95E1F7209151023091520295 -:106BC000409153025091540229873A874B875C8742 -:106BD00080E090E0A5E0B3E48093510290935202EC -:106BE000A0935302B0935402412F6F2D80E00E9476 -:106BF0007872412F6F2D81E00E947872412F6F2DA6 -:106C000082E00E947872011146C020918606309180 -:106C10008706409188065091890660917E027091A6 -:106C20007F0280918002909181020F94083E6093D0 -:106C30007E0270937F028093800290938102809005 -:106C40004D0290904E02A0904F02B0905002A501CC -:106C500094010F946840181644F480927E0290923A -:106C60007F02A0928002B092810220E030E040E0FA -:106C70005FE360918109709182098091830990910D -:106C800084090F94173A69837A838B839C83CE019E -:106C900001960E94D3A68CE0189F90011124A901AF -:106CA0004259594F6A018F9DC0011124DC01A2593C -:106CB000B94F7D012D913D914D915C91F60160811F -:106CC0007181828193810F94073E2B013C01D70192 -:106CD00014962D913D914D915C911797F601648129 -:106CE0007581868197810F94073E4B015C01D70126 -:106CF00018962D913D914D915C911B97F601608501 -:106D00007185828593850F94073E6B017C011093FA -:106D10005109A301920160917602709177028091EE -:106D20007802909179020F94083E609376027093F6 -:106D300077028093780290937902A5019401609183 -:106D40007A0270917B0280917C0290917D020F9477 -:106D5000083E60937A0270937B0280937C0290934A -:106D60007D02A701960160917E0270917F02809161 -:106D70008002909181020F94083E60937E0270938E -:106D80007F0280938002909381020E947BB5011163 -:106D900020C0809135098330E0F08AE896E00E94B7 -:106DA0001AB388E0EAE8F6E0DE01119601900D9250 -:106DB0008A95E1F749E759E0BE016B5F7F4FCE014D -:106DC00001960E94A2B461E879E082E996E00E940F -:106DD000C4B429853A854B855C8520935102309354 -:106DE000520240935302509354020E947F8F60914D -:106DF000510988E893E20E947FD6AFCE01E0CECE63 -:106E000021E030E0082E02C0220F331F0A94E2F77F -:106E1000209530959091BF0729232093BF0781309B -:106E200061F020F0823071F081E008955F9A8091E6 -:106E3000E4088E7F8093E408F7CF8A9A8091E40873 -:106E40008D7FF8CF80910801809581708093060135 -:106E50008091E4088B7F8093E40880E090E0A6E1D5 -:106E6000B3E480937E0290937F02A0938002B0935C -:106E700081020E947BB5D8CF80E00E9400B781E0FC -:106E80000E9400B782E00E9400B70C94FE899091A6 -:106E9000091680910A16981308C080914C099091A8 -:106EA0004D09892B11F40C943CB780E00E94EADD77 -:106EB000EECF4F925F926F927F928F929F92AF929E -:106EC000BF92DF92EF92FF920F931F93CF93DF93C6 -:106ED000D82EC82FD0E0FE01E253F44C6491062E68 -:106EE000000C770B880B990B0F94B8392B013C01E0 -:106EF0007E01EE0CFF1CEE0CFF1CF701ED50FB4E6B -:106F00002591359145915491C301B2010F94173ADF -:106F10004B015C01F701E951FB4E6591759185913B -:106F2000949120E030E040EC5FE30F94173AA30126 -:106F300092010F94173AAB01BC0100E010E09801F8 -:106F40008D2D0F94811320E030E0A901C501B4011B -:106F50000F94B139882309F446C0B501A4017058D3 -:106F600000E010E098018D2D0F948113A50194018C -:106F7000C501B4010F94083E4B015C01CC51DB4EBE -:106F8000FE01C491C11107C00E940FD882EC94E1A8 -:106F90000E94ACCECAE0DD2039F0F1E060E070E0A4 -:106FA00080E793E4DF1204C060E070E88BE395E4CF -:106FB00020E030E040E752E40F94023F2B013C0117 -:106FC0006C2F70E090E080E00F94B6399B01AC012B -:106FD000C301B2010F94023F8B019C01B501A401D2 -:106FE0008D2D0F94811381E090E00D2C01C0880F4E -:106FF0000A94EAF79091E408982B9093E408909112 -:107000000108892B80930108F701EA54FB4E859112 -:107010009591A591B491E701CA58DD4F8883998372 -:10702000AA83BB83F701E655FA4F108211821282C0 -:1070300013828D2D0E94FAB20E947BB5F701E657AC -:10704000F94F88819981AA81BB8180839183A28332 -:10705000B383DF91CF911F910F91FF90EF90DF905D -:10706000BF90AF909F908F907F906F905F904F9068 -:1070700008954F925F926F927F928F929F92AF92FC -:10708000BF92CF92DF92EF92FF920E943C95F82E32 -:1070900080910A168093091680930816809307162C -:1070A00084E6809306160E94B4A780ED93E0909347 -:1070B0004D0980934C09F1100E94499581E080931D -:1070C000A2070E947F8F80E00E9485B22B013C01C5 -:1070D0004092090750920A0760920B0770920C07C2 -:1070E00081E00E9485B24B015C0180920D07909275 -:1070F0000E07A0920F07B092100782E00E9485B29F -:107100006B017C01C0921107D0921207E092130725 -:10711000F092140783E00E9485B24092760250926A -:107120007702609278027092790280927A0290924D -:107130007B02A0927C02B0927D02C0927E02D0922D -:107140007F02E0928002F09281026093820270934B -:1071500083028093840290938502FF90EF90DF90EA -:10716000CF90BF90AF909F908F907F906F905F90E7 -:107170004F900C947BB5CF93DF93CDB7DEB72C97B0 -:107180000FB6F894DEBF0FBECDBF0F94B2100E94B1 -:107190003C959CE0EFEAF7E0DE01119601900D923C -:1071A0009A95E1F781110E944995CE0101960E94BE -:1071B000E6872C960FB6F894DEBF0FBECDBFDF91E9 -:1071C000CF9108954F925F926F927F928F929F928C -:1071D000AF92BF92CF92DF92EF92FF92CF93409007 -:1071E00076025090770260907802709079028090D9 -:1071F0007A0290907B02A0907C02B0907D02C090B9 -:107200007E02D0907F02E0908002F09081020E9486 -:107210000D8F0E94E771C0E08C2F0E94FAB240E00F -:1072200060E08C2F0E947872CF5FC330A9F70E9474 -:107230005B8FA30192016091760270917702809139 -:107240007802909179020F94B13981111BC0A50188 -:10725000940160917A0270917B0280917C029091FE -:107260007D020F94B13981110DC020917E023091C1 -:107270007F024091800250918102C701B6010F94B4 -:10728000B13981110E94BBB88FEF80932E02CF914C -:10729000FF90EF90DF90CF90BF90AF909F908F9036 -:1072A0007F906F905F904F900C94BB3F8AE494E185 -:1072B0000E94ACCE8CB164E474E1829581700E942E -:1072C0003A77809103016EE374E1869581700E94A4 -:1072D0003A7789B168E374E183FB882780F90C94DD -:1072E0003A778091E308882331F062E070E080E033 -:1072F00090E00C9421CD0895A5E5B9E090E080E000 -:10730000FC01EC5AF54E45915591659174914D9360 -:107310005D936D937D93FC01EC5BF54E459155912A -:107320006591749150964D935D936D937C935397B3 -:10733000FC01EC5CF54E45915591659174919096E8 -:107340004D935D936D937C93939704968031910553 -:10735000B9F680E29EE4A0E0B0E0809365099093E6 -:107360006609A0936709B093680980E090E0AAE7F6 -:10737000B3E48093890990938A09A0938B09B09311 -:107380008C0980E090E4ACE9B5E480938D0990939A -:107390008E09A0938F09B093900980E090E0AAEF46 -:1073A000B3E48093910990939209A0939309B093C9 -:1073B00094091092950910929609109297091092CB -:1073C00098091092990910929A0910929B091092AB -:1073D0009C098AE097EDA3E2BFE38093FE059093BA -:1073E000FF05A0930006B09301061092EE081092DC -:1073F000EF081092F0081092F1081092EA0810922B -:10740000EB081092EC081092ED081092E60810922A -:10741000E7081092E8081092E90810926E061092A0 -:107420006F061092700610927106109272061092FA -:1074300073061092740610927506109276061092DA -:107440007706109278061092790610927A061092BA -:107450007B0610927C0610927D0610927E0610929A -:107460007F0610928006109281061092820610927A -:10747000830610928406109285061092860610925A -:107480008706109288061092890688EC90E0909307 -:10749000F3058093F20582E390E09093F5058093E5 -:1074A000F4051092F7051092F6058CED90E090939C -:1074B000F9058093F80584E690E09093FB058093AE -:1074C000FA051092FD051092FC0581E79DE3A0EA04 -:1074D000B1E480934A0690934B06A0934C06B09378 -:1074E0004D068AE99EEAACE4BEE380934E06909393 -:1074F0004F06A0935006B093510681E995E6AAEF96 -:10750000B3E48093520690935306A0935406B0932D -:1075100055068FEF80932E021092F10580E090E0E7 -:10752000A0EEBFE38093E9059093EA05A093EB05F5 -:10753000B093EC058093ED059093EE05A093EF05D5 -:10754000B093F0051092E3081092E2080E9471B91E -:107550000E949C8880E090E0A0EAB2E48093D90584 -:107560009093DA05A093DB05B093DC051092DD055E -:107570001092DE051092DF051092E0058093E10580 -:107580009093E205A093E305B093E4051092E5051E -:107590001092E6051092E7051092E8050E94E2B805 -:1075A0000E940FD88BEB98E10C9409DB8091340991 -:1075B000882319F010923409089540E070E060E0EB -:1075C00088E194E10C94E2DC0F931F938091860F85 -:1075D000813019F50F941E1D00913B0710913C0757 -:1075E00020913D0730913E07601B710B820B930B7E -:1075F00028EE33E040E050E00F94A43D60913F0757 -:10760000709140078091410790914207620F731F6C -:10761000841F951F1F910F910895609143077091EA -:1076200044078091450790914607D6CFCF92DF92CD -:10763000EF92FF92CF93C82F8091860F81508230B6 -:1076400008F067C01092860F0F941E1D60934307C9 -:10765000709344078093450790934607C090D505E3 -:10766000D090D605E090D705F090D8050E94E4BAF6 -:10767000AB01BC014093D5055093D6056093D70567 -:107680007093D8058091D6089091D708A091D8081A -:10769000B091D9088C199D09AE09BF09840F951FB7 -:1076A000A61FB71F8093D6089093D708A093D80839 -:1076B000B093D908C1110AC0C1E00E94BC8E8C2FC2 -:1076C000CF91FF90EF90DF90CF9008958091D408F4 -:1076D0009091D50801969093D5088093D4080E9484 -:1076E000E4BAC090DA08D090DB08E090DC08F090B3 -:1076F000DD08C616D706E806F906F0F60E94E4BAD9 -:107700006093DA087093DB088093DC089093DD08BF -:10771000D3CFC0E0D2CF1092860F10923B071092C9 -:107720003C0710923D0710923E07109243071092BB -:107730004407109245071092460710923F07109297 -:10774000400710924107109242070895CF93C091CD -:10775000860F80E0C13069F1C23069F50E94E4BA59 -:1077600060933F07709340078093410790934207CF -:1077700081E08093860F0F941E1D60933B077093EA -:107780003C0780933D0790933E07C23089F080917B -:10779000D2089091D30801969093D3088093D20891 -:1077A0001092D5051092D6051092D7051092D805E3 -:1077B00081E0CF9108950E948BBBDACF20914706DC -:1077C000309148062635310574F420915E063091DB -:1077D0005F06263531053CF4209136063091370698 -:1077E0002630310524F0882349F00C94A6BB66238B -:1077F00029F081E00E9416BB0D948E1008958091AF -:10780000860F813079F482E08093860F0F941E1DDD -:10781000609343077093440780934507909346070E -:1078200081E0089580E00895CF92DF92EF92FF9279 -:10783000FC01C080D180E280F38020E030E0A9012B -:10784000C701B6010F94B13987FF68C0C701B601FF -:10785000905820E030E040E251E40F94173A20E0E5 -:1078600030E040EA50E40F94083E20E030E040E28F -:1078700051E40F94023F0F94743F9B0160E220316A -:10788000F7E23F0730F0C90160E177E20F9434413D -:10789000605D6093A405283E83E0380708F445C086 -:1078A000C90168EE73E00F943441CB016AE070E0E7 -:1078B0000F943441805D8093A50580E22436310524 -:1078C00058F0C90164E670E00F943441CB016AE0DE -:1078D00070E00F943441805D8093A60580E22A30E9 -:1078E000310558F0EAE0F0E0C901BF010F943441DE -:1078F000CB01BF010F943441805D8093A705C9017E -:107900006AE070E00F943441805D8093A80584EABA -:1079100095E0FF90EF90DF90CF90089520E030E069 -:1079200040E251E4C701B60198CF80E2C4CF8F9204 -:107930009F92AF92BF92CF92DF92EF92FF92FC01A3 -:10794000C080D180E280F38020E030E040E251E46A -:10795000C701B6010F94173A20E030E040E251E44D -:107960000F94173A4B015C0120E030E0A901C701F8 -:10797000B6010F94B13920E030E040EA50E487FFCF -:1079800004C020E030E040EA50ECC501B4010F949F -:10799000083E20E030E040E251E40F94023F0F94B3 -:1079A000743F9B018BE237FF05C022273327261B3C -:1079B000370B8DE28093A305C90168EE73E00F9445 -:1079C0004841CB01EAE0F0E0BF010F944841805DFF -:1079D0008093A405C90164E670E00F944841CB018F -:1079E000BF010F944841805D8093A505C901BF0187 -:1079F0000F944841282FCB01BF010F944841805D6F -:107A00008093A6058EE28093A705205D2093A805AC -:107A100083EA95E0FF90EF90DF90CF90BF90AF901A -:107A20009F908F9008959C0197FF26C0EE27FF2717 -:107A3000E81BF90B2D398FEF38070CF05DC08DE294 -:107A40008093A505CF0164E670E00F944841CB0117 -:107A50002AE030E0B9010F944841805D8093A6058B -:107A6000CF01B9010F944841CB01B9010F944841AE -:107A7000805D8093A7052AC0283E83E03807B4F1D3 -:107A8000C90168EE73E00F944841CB01EAE0F0E0F1 -:107A9000BF010F944841805D8093A505C90164E64C -:107AA00070E00F944841CB01BF010F944841805DC5 -:107AB0008093A605C901BF010F944841CB01BF01C6 -:107AC0000F944841805D8093A705F901CF016AE0DA -:107AD00070E00F944841805D8093A80585EA95E0A9 -:107AE00008958DE237FDC5CF80E2C3CFF90180E272 -:107AF000243631050CF0A4CF80E28093A505809355 -:107B0000A605EA30F1056CF38DE237FF80E2809341 -:107B1000A605CF016AE070E00F944841605D609374 -:107B2000A705D4CF9C0197FD2DC080E224363105F6 -:107B30005CF0C90164E670E00F944841CB016AE053 -:107B400070E00F944841805D8093A60580E22A3062 -:107B500031055CF0EAE0F0E0C901BF010F94484153 -:107B6000CB01BF010F944841805D8093A705C901F7 -:107B70006AE070E00F944841805D8093A80586EA32 -:107B800095E008953195219531098DE2DDCF9C0175 -:107B9000283E83E03807D0F1C90168EE73E00F9406 -:107BA0003441CB016AE070E00F943441805D8093F2 -:107BB000A50580E22436310558F0C90164E670E07D -:107BC0000F943441CB016AE070E00F943441805D42 -:107BD0008093A60580E22A30310558F0EAE0F0E013 -:107BE000C901BF010F943441CB01BF010F9434414F -:107BF000805D8093A705C9016AE070E00F9434416D -:107C0000805D8093A80585EA95E0089580E2CFCF56 -:107C1000282F80E2243628F0822F64E60F941A4140 -:107C2000805D8093A60590E22A3040F03AE0822FF2 -:107C3000632F0F941A410F941A41905D9093A705FA -:107C4000822F6AE00F941A41905D9093A80586EA0E -:107C500095E0089524E6829FC001112481589F4F2A -:107C60006FEF70E00F944841262F81E3643609F0EE -:107C700080E28093A50590E22A3040F03AE0822F1E -:107C8000632F0F941A410F941A41905D9093A605AB -:107C9000822F6AE00F941A41905D9093A70585E2C8 -:107CA0008093A80585EA95E00895BC018AE197E2F2 -:107CB0000E94E0DD87E197E20C94ACCECF92DF9298 -:107CC000EF92FF920F931F93CF93DF9300D000D0DA -:107CD0001F92CDB7DEB72091A21724FF92C0F62ED7 -:107CE0008C0181E0681709F46DC0681708F463C05F -:107CF00082E0681709F405C18091A217877F8B7F06 -:107D00008093A2170E94677EA801BE016F5F7F4F1C -:107D100081E00F94BD0C8C01009709F472C0698159 -:107D20007A8121E0AC0180E594E10E946A80882399 -:107D300009F4EEC08091611490916214A0916314D3 -:107D4000B091641480939A1790939B17A0939C17FB -:107D5000B0939D1710929E1710929F171092A01724 -:107D60001092A117B80185E497E20E94E0DDC0906F -:107D70009A17D0909B17E0909C17F0909D178DE379 -:107D800097E20E94ACCEC701B6010F94C00D8AE005 -:107D90000E949FCE8EE297E20E94ACCEC8010E9464 -:107DA0000B838091FC11882311F00CEF11E1C801C5 -:107DB0000F94450E26C0B80182E00F94E72610927A -:107DC00099179ACF0E9473CD811105C0B80181E047 -:107DD0000F94E72691CFE0909917EE2009F10E94C9 -:107DE0000BD861E070E08EE997E20E9487DA8AE0C2 -:107DF0000E949FCE40E070E060E08DE897E20E9434 -:107E0000E2DC27960FB6F894DEBF0FBECDBFDF9140 -:107E1000CF911F910F91FF90EF90DF90CF90089539 -:107E200080EA96E09E838D838FE280939F06FF8297 -:107E3000CE0105969A83898302969C838B838BE17E -:107E4000F82E80919717E81658F4EF9CB001112492 -:107E50006757794ECE0101960E94317FE394F1CFAE -:107E60008F818B3558F460E574E1CE0101960E9454 -:107E7000317F8D819E8101979E838D83ED81FE816F -:107E80001082E091991784E0E89FF0011124E556F3 -:107E9000F94F80919E1790919F17A091A017B091D4 -:107EA000A11780839183A283B3830E940FD8B80166 -:107EB00084E797E20E94E0DD6091991789E6689F68 -:107EC000B00111246156794F89E697E20E94E0DD06 -:107ED000C0909E17D0909F17E090A017F090A11728 -:107EE00083E697E20E94ACCEC701B6010F94C00DA5 -:107EF0008AE00E949FCE809199178F5F8093991797 -:107F0000FBCE0E940FD883E597E20E94ACCEF4CE60 -:107F1000C8010E9455BE75CF0F931F93CF93DF9377 -:107F20001F921F92CDB7DEB72091A21724FF33C056 -:107F30008C01BC0182E00F94E72610929917809182 -:107F4000A217877F8B7F8093A2170E94677EA8016C -:107F5000BE016F5F7F4F80E00F94BD0C8C010097D6 -:107F6000D1F069817A8126E5AC0180E594E10E9437 -:107F70006A808823B9F08091A21781608093A2174C -:107F8000C8010E940B83B8018DEB97E20F94E226A3 -:107F9000C8010F94450E0F900F90DF91CF911F9164 -:107FA0000F910895C8010E9455BEF5CF6F927F9240 -:107FB0008F929F92AF92BF92CF92DF92EF92FF92F9 -:107FC0000F931F93CF93DF93CDB7DEB7C655D1097B -:107FD0000FB6F894DEBF0FBECDBF5C017B016DB65E -:107FE0007EB6BE016F5F7F4FC5010F946C0E1816F1 -:107FF0000CF06BC08C858871803109F081C08DB622 -:108000009EB610E000E0E114F10439F0F7010190B0 -:108010000020E9F78F010E191F09C8010D962DB731 -:108020003EB7281B390B0FB6F8943EBF0FBE2DBFCD -:108030008DB79EB701966C01080F191FE114F1046A -:1080400039F0B7010F94ED418FE2F8013197808349 -:10805000BE016F5F7F4FC8010E94127A19A21CA255 -:1080600021E0A801B501CE0181960E946A80882393 -:10807000E1F08BE1FE01B196DE01DC9601900D92FC -:108080008A95E1F7B601CE01CC960E94D6BFCE010B -:10809000CC960E946480CE0181960E9464800FB6C7 -:1080A000F8949EBE0FBE8DBE9CCF0E940FD8B80123 -:1080B0008AEA96E20F94E226CE0181960E946480BD -:1080C0000FB6F8949EBE0FBE8DBE0FB6F8947EBE5E -:1080D0000FBE6DBECA5ADF4F0FB6F894DEBF0FBE9B -:1080E000CDBFDF91CF911F910F91FF90EF90DF9067 -:1080F000CF90BF90AF909F908F907F906F9008959A -:10810000CE0101960E94F579882309F46ACFE11423 -:10811000F10431F0C7010F94D6268FE20E949FCE62 -:10812000BE016F5F7F4F89E79FE00E94127A0F9434 -:10813000D62680E20E949FCE6D8D7E8D8F8D98A178 -:108140000F94C00D8AE00E949FCE4BCF2F923F929A -:108150004F925F926F927F928F929F92AF92BF9257 -:10816000CF92DF92EF92FF920F931F93CF93DF9303 -:10817000CDB7DEB7C558D1090FB6F894DEBF0FBE34 -:10818000CDBF2DB73EB7CC57DF4F39832883C458B6 -:10819000D04001E025E537E044E050E0BE016758FB -:1081A0007F4F83E597E00E9461CE43E050E0BE013F -:1081B00067587F4F89E393E00F94F441892B09F4CA -:1081C00050C0ED968FADED97882339F08FE3EA9696 -:1081D0008FAFEA97EB961FAEEB970E940FD8BE01C8 -:1081E00067587F4F82E79AE10E94E0DD84E69AE1DA -:1081F0000E94ACCE81E080935707809102068111E6 -:1082000007C080913509833018F080E00E942E8AE3 -:108210009091570781E08927CC57DF4F288139811A -:10822000C458D0400FB6F8943EBF0FBE2DBFCB57F9 -:10823000DF4F0FB6F894DEBF0FBECDBFDF91CF91F9 -:108240001F910F91FF90EF90DF90CF90BF90AF9074 -:108250009F908F907F906F905F904F903F902F9066 -:10826000089501E025E537E042E050E0BE016358A3 -:108270007F4F83E597E00E9461CEE9961CAE1DAE6C -:108280001EAE1FAEE9971092560710925507CE0109 -:1082900081589F4F0E94F176ADB6BEB6C158DF4FF0 -:1082A000C880CF57D040D12C33E0C30ED11CCC0CAA -:1082B000DD1CCC0CDD1C8DB79EB78C199D090FB64B -:1082C000F8949EBF0FBE8DBFEDB7FEB73196CE5767 -:1082D000DF4FF983E883C258D0402DB73EB72C1941 -:1082E0003D090FB6F8943EBF0FBE2DBF8DB79EB7A8 -:1082F00001964C01EDB7FEB7EC19FD090FB6F894E5 -:10830000FEBF0FBEEDBF2DB73EB72F5F3F4F7901C8 -:10831000B601CE57DF4F88819981C258D0400E9464 -:10832000FE760091020681E0082725E537E044E06B -:1083300050E065E679E083E597E00E9461CEB60102 -:10834000C4010E94FE76B601C7010E94FE7600912C -:108350000206011157C0C158DF4F8881CF57D04066 -:1083600090E00296A5E5B9E050E040E030E020E082 -:1083700060E67AE1E0E5CE2EEAE1DE2E8217930791 -:108380000CF4A6C0CE57DF4FE881F981C258D04027 -:10839000E40FF51F40805180628073804D925D92A2 -:1083A0006D927D92821793070CF498C0F401E40F4C -:1083B000F51F208031801281E3812101612E7E2E04 -:1083C00050964D925D926D927C92539782179307CF -:1083D0000CF48DC0F701E40FF51F2080318012816D -:1083E000E3812101612E7E2E90964D925D926D92D9 -:1083F0007C9293972F5F3F4F4C5F5F4F2430310546 -:1084000009F0BCCF89E899E00E94E1768DE899E017 -:108410000E94E17681E999E00E94E17685E999E0A0 -:108420000E94E17689E999E00E94E176CE018B58BD -:108430009F4F0E94E176CE018B589F4F0E94E176BC -:10844000CE018B589F4F0E94E176CE018B589F4FF3 -:108450000E94E1768EEF95E00E94E1760FB6F894E7 -:10846000BEBE0FBEADBE86EE98E00E94D1768AE712 -:1084700096E00E94D176CE0183599F4F0E94A1764B -:10848000CE0101967C010E94E176CE018B589F4F70 -:108490000E94E176CE018B589F4F0E94E176C70182 -:1084A0000E94F176CE0183599F4F0E94F176C980D8 -:1084B000AE968FADAE97C89E6001112491E0C91AA7 -:1084C000D108F8F0CE018B589F4F0E94E176F6CF8D -:1084D000FB01459055906590749060CFF6014590F2 -:1084E0005590659074901201162DE72D66CFE0E44B -:1084F000FAE145905590659074901201162DE72D84 -:1085000070CFC7010E94D1761AE01150CE0129F038 -:108510008B589F4F0E94E176F8CF80589F4F0E9462 -:10852000F176CE018F579F4F0E94F176C7010E94CE -:10853000C176CE0183599F4F0E94C176C058DF4F4C -:10854000C880C058D040CF57DF4F8881C158D04035 -:10855000C89E60011124F1E0CF1AD10830F0CE019D -:108560008B589F4F0E94E176F6CFC7010E94B176EB -:10857000CE0183599F4F0E94A17611E0012725E586 -:1085800037E040E150E0B70183E597E00E9461CE1B -:10859000C7010E94B17600910206012725E537E068 -:1085A0004CE050E062EF75E083E597E00E9461CE19 -:1085B00012E0DD24D394009102060D2525E537E075 -:1085C00044E150E0B70183E597E00E9461CE00915D -:1085D0000206011138C089809A80AB80BC80A50159 -:1085E0009401C501B4010F94FA4081112CC080920E -:1085F0004A0690924B06A0924C06B0924D062CEA89 -:1086000035EC47E25EE36D817E818F8198850F9422 -:10861000173A60934E0670934F06809350069093DE -:1086200051062CEA35EC47E25EE369857A858B8555 -:108630009C850F94023F609352067093530680937B -:10864000540690935506113009F090C1012725E595 -:1086500037E042E050E0B70183E597E00E9461CE49 -:10866000C7010E949176C7010E949176C7010E94BE -:10867000A176C7010E94A17600910206011103C0F4 -:10868000898180932E02C7010E94A17685E0F701BF -:1086900011928A95E9F711E0012725E537E045E0D9 -:1086A00050E0B70183E597E00E9461CEC7010E94C8 -:1086B000B17600910206012725E537E040E250E05F -:1086C000B70183E597E00E9461CECE0183599F4FA9 -:1086D0000E94B17600910206012725E537E041E1CD -:1086E00050E0B70183E597E00E9461CE80910206D9 -:1086F00081110EC089818093F10588E0FE013296D8 -:10870000A9EEB5E001900D928A95E1F70E949C8850 -:108710000091020681E0082725E537E044E150E0BA -:10872000B70183E597E00E9461CE80910206811136 -:108730004BC069817A816115710511F460E273E0C3 -:108740007093E9156093E8158FEA95E10F940F2176 -:108750006B817C816115710511F460E273E07093A7 -:10876000AD156093AC1583E795E10F940F216D81F2 -:108770007E816115710511F460E273E070937115EB -:108780006093701587E395E10F940F2169897A89C9 -:108790006115710511F460E273E070933515609313 -:1087A00034158BEF94E10F940F216B897C8961154F -:1087B000710511F460E273E07093F9146093F8149A -:1087C0008FEB94E10F940F210091020611E0012735 -:1087D00025E537E048E250E0B70183E597E00E94E5 -:1087E00061CE00910206012725E537E040E150E027 -:1087F000B70183E597E00E9461CE00910206012750 -:1088000025E537E042E050E0B70183E597E00E94BC -:1088100061CE80910206811122C08981817080938E -:10882000EA150F9401128981869581708093AE15A7 -:108830000F940912898182FB882780F98093721531 -:108840000F9411128A818170809336150F9419123A -:108850008A81869581708093FA140F942112009179 -:10886000020611E0012725E537E048E050E0B701B6 -:1088700083E597E00E9461CE00910206012725E57D -:1088800037E040E150E0B70183E597E00E9461CE18 -:1088900000910206012725E537E04CE650E0B701DC -:1088A00083E597E00E9461CE19821A821B821C82A6 -:1088B0001D821E821F82188619861A861B861C86B8 -:1088C000C7010E94917600910206012725E537E055 -:1088D00040E150E069ED75E083E597E00E9461CEEC -:1088E00000910206012725E537E044E050E066E804 -:1088F00076E083E597E00E9461CEC7010E94D176C1 -:10890000CE0180589F4F0E94A176CE0183599F4F80 -:108910000E94E176809153079091540787319340EC -:1089200039F10E940BD88AEA99E10E94ACCE1093EB -:1089300057070E940FD860915307709154076456EF -:1089400071098CE29AE10E9487DA63EB72E084E2BB -:108950009AE10E9404DB8091020681114ECC809145 -:10896000570781114ACC0E94E2B847CC11E023CED0 -:10897000109257072091550730915607EF968EAD0C -:108980009FADEF9728173907C9F0109357070E943A -:108990000BD8EF966EAD7FADEF9784E09AE10E9421 -:1089A0007BDA60915507709156078FEF99E10E942D -:1089B0007BDA8FEE99E10E94ACCECDCF809102069A -:1089C0008111C9CF0E940FD889E393E00F94D62676 -:1089D00060915307709154076456710982ED99E1D3 -:1089E0000E9487DAC0905507D0905607F12CE12CF1 -:1089F00085EC99E10E94ACCEC701B6010F94C00D81 -:108A000082EC99E1D8CF84E690E09093540780936C -:108A1000530710925607109255070C94A6C081E098 -:108A2000809302060E9403C51092020681110C94E5 -:108A300003C50E947CB90E94648B0E940FD887EA0C -:108A400098E10E94ACCE80E008950F94D6268DE088 -:108A50000E949FCE8AE00C949FCECF93DF93C0916B -:108A60003606D091370681E0CE31D105E4F020E022 -:108A700030E040E05FE36091320670913306809110 -:108A80003406909135060F94083E0F94743F6C1B8A -:108A90007D0B77FF03C071956195710981E06330AB -:108AA00071050CF080E0DF91CF91089590E080E0B7 -:108AB0000895CF93DF93DB01F9019C919130C1F0D0 -:108AC000943080F094509C938830D1F480819181CF -:108AD000009771F0019791838083480F591FEA0135 -:108AE000188206C08C3539F49C5F9C93943041F415 -:108AF000DF91CF9108958B3339F781E08C93F8CFD4 -:108B000020813181B9016F5F7F4F71836083420F94 -:108B1000531FEA018883808191818F3591056CF71D -:108B2000E7CF0F931F9381E000919E1710919F173D -:108B30002091A0173091A11740919A1750919B173F -:108B400060919C1770919D1704171507260737072A -:108B500008F480E01F910F9108952091A1088330BF -:108B600021F425FD0CC024FD0CC030E0A90102C099 -:108B7000559547958A95E2F7CA018170089581E07D -:108B8000089580E008958091BC0884FD0BC0809119 -:108B9000BE0887FD07C09091BF08937081E019F46B -:108BA00080E0089581E008952FEB280F2A3108F026 -:108BB00047C0E22FF0E08091BC089091BD08A091E1 -:108BC000BE08B091BF0804C0B695A7959795879544 -:108BD0002A95D2F780FD02C081700895EE55F74FB7 -:108BE000E081EE2341F18091530990915409E80FFF -:108BF000F92FF11D808190ED980F9A3030F08E3270 -:108C000051F4818180538A3098F4F0939F08E09367 -:108C10009E0881E008958D3211F08B3249F48181F4 -:108C200090ED980F9A3088F38E3211F48281EACF5A -:108C3000F0E0E0E0EACF10929F0810929E08E9CFA2 -:108C400080E00895CF93DF93C0913606D091370628 -:108C5000209729F160913206709133068091340695 -:108C6000909135060F94743F6E5F7F4F24976C1779 -:108C70007D07ACF470930D0660930C060F941E1DD7 -:108C8000605A75418F4F9F4F60930E0670930F0689 -:108C90008093100690931106DF91CF910895109262 -:108CA0000E0610920F061092100610921106F4CFC5 -:108CB0002F923F924F925F926F927F928F929F92EC -:108CC000AF92BF92CF92DF92EF92FF920F931F93DA -:108CD000CF93DF93D62FC72FFC0180809180A28095 -:108CE000B380C501B40120E831E541E050E00F94C4 -:108CF000A43DC9016DE671E00F9434416B017C0124 -:108D0000C501B40120E13EE040E050E00F94A43DF5 -:108D1000CA01B90128E130E040E050E00F94A43DE1 -:108D2000362E272E062F172F8CE3482E512C612C20 -:108D3000712CC501B401A30192010F94A43DB62E7C -:108D4000A72ECA01B901A30192010F94A43DCB0142 -:108D5000C114D10479F1AF92BF927F936F932F9298 -:108D60003F92FF92EF92DF92CF928EE895E39F932E -:108D70008F93CF93DF930F9448398DB79EB70E969C -:108D80000FB6F8949EBF0FBE8DBF8D2F9C2FDF9125 -:108D9000CF911F910F91FF90EF90DF90CF90BF90F8 -:108DA000AF909F908F907F906F905F904F903F908B -:108DB0002F900895E114F104C9F0AF92BF927F9310 -:108DC0006F932F923F92FF92EF928EE795E39F93DE -:108DD0008F93CF93DF930F944839EDB7FEB73C964E -:108DE0000FB6F894FEBF0FBEEDBFCFCF012BB9F089 -:108DF000AF92BF927F936F932F923F9282E795E35A -:108E00009F938F93CF93DF930F9448398DB79EB77D -:108E10000A960FB6F8949EBF0FBE8DBFB6CF892BB2 -:108E2000A9F0AF92BF927F936F938AE695E39F93E9 -:108E30008F93CF93DF930F944839EDB7FEB73896F1 -:108E40000FB6F894FEBF0FBEEDBF9FCFAF92BF929B -:108E500086E695E39F938F93CF93DF930F944839E2 -:108E60000F900F900F900F900F900F908ECF8091DA -:108E70009E0890919F08009731F04AE050E070E022 -:108E800060E00D94D33760E070E0CB0108958091ED -:108E90009E0890919F08009731F04AE050E070E002 -:108EA00060E00D94A53660E070E0CB0108950E946B -:108EB00047C7CB0108950E9447C797FD0CC00E9489 -:108EC00047C76F3F71058105910509F034F40E9491 -:108ED00047C7862F089580E008958FEF0895809109 -:108EE0009E0890919F08892B41F00E945BC791E0FA -:108EF000811101C090E0892F089591E0FCCFCF92BD -:108F0000DF92EF92FF920F931F93CF93DF93CDB732 -:108F1000DEB72C970FB6F894DEBF0FBECDBFF09032 -:108F20008016E09081162091FA0321111DC042E9BC -:108F300057E36E2D8F2D0F94DD2590E080E0F80E25 -:108F4000F0928016E092811699272C960FB6F8942D -:108F5000DEBF0FBECDBFDF91CF911F910F91FF906C -:108F6000EF90DF90CF900895C0904D16D0904E16A0 -:108F700029E436E13A8329832F2D30E03C832B838B -:108F80002E2D30E03E832D8318861F827A876987D5 -:108F90001C861B8607EA18E29E012F5F3F4F41EABD -:108FA00054E2BC01C6010F945010B60189E496E169 -:108FB0000F9419258F819885C2CFCF92DF92EF92BF -:108FC000FF920F931F93CF93DF93CDB7DEB72C970C -:108FD0000FB6F894DEBF0FBECDBFF0908016E090C4 -:108FE00081162091FA0321111DC042E757E36E2D2F -:108FF0008F2D0F94DD2590E080E0F80EF092801622 -:10900000E092811699272C960FB6F894DEBF0FBE1A -:10901000CDBFDF91CF911F910F91FF90EF90DF9027 -:10902000CF900895C0904D16D0904E1629E436E1A9 -:109030003A8329832F2D30E03C832B832E2D30E083 -:109040003E832D8318861F827A8769871C861B863C -:1090500007EA18E29E012F5F3F4F44EA54E2BC0149 -:10906000C6010F945010B60189E496E10F941925BA -:109070008F819885C2CFCF93609136067091370665 -:10908000072E000C880B990B0F94B839C1E0209182 -:1090900032063091330640913406509135060F94D4 -:1090A000684018160CF0C0E08C2FCF9108958F9275 -:1090B0009F92AF92BF92CF92DF92EF92FF920F9367 -:1090C0001F93CF93DF931092C1081092C0082FE333 -:1090D0002093C4081092C3081092C2081092BC08D2 -:1090E0001092BD081092BE081092BF089C01F901B1 -:1090F00090812F5F3F4F9032D1F39E34C9F481812C -:1091000090ED980F9A3020F08D3211F08B3281F46F -:1091100032969F012F5F3F4F808180538A3008F441 -:109120006BC09F012F5F3F4F8081803209F466C082 -:10913000F0935409E09353098F010F5F1F4FC081D3 -:109140006AE270E0C8010F94E241009731F0FC013F -:10915000319780818032E1F31182CD3421F0C43522 -:1091600011F0C734E1F5F80180810F5F1F4F8032A5 -:10917000D1F380538A3098F5C093C40830E020E0E2 -:109180006AE0AF014F5F5F4F629FC001639F900D28 -:1091900011249C01205331098081280F311D87FD46 -:1091A0003A95FA01808180538A3058F33093C3088E -:1091B0002093C208DF0131968C918032D9F3CD34EF -:1091C00049F52E31310539F0D8F42731310519F040 -:1091D0002C313105F9F4B093C108A093C008DF9198 -:1091E000CF911F910F91FF90EF90DF90CF90BF90A4 -:1091F000AF909F908F900895F9018BCFF90191CF97 -:109200002537310538F02737310528F3203A83E038 -:10921000380709F3D091530940E050E0BA0110E05B -:1092200000E0C12CD12C7601C394FD0131968C91C4 -:10923000882309F47FC08132E1F4CD34D1F42032A7 -:109240003105B9F44093BC085093BD086093BE0843 -:109250007093BF08F093C108E093C00863E270E028 -:10926000CF010F94E241009709F4B9CFFC011082BD -:10927000B6CF81548A3108F058C0DF019D919032F9 -:1092800091F0A0EDA90FAA30E8F09E3271F491811F -:1092900090539A30B8F00115110519F48F0101505F -:1092A000110990E013C0FD01E8CF9D3211F09B320F -:1092B00091F79181A0EDA90FAA3020F09E3259F7C5 -:1092C0009281E6CF9E2F9D1B309759F3A82FB0E0D7 -:1092D0004601570104C0880C991CAA1CBB1C8A9526 -:1092E000D2F7482959296A297B29AE55B74F9C9353 -:1092F00080818154DF018A3108F497CFDF018191A9 -:10930000882309F492CF90ED980F9A30B8F393ED3B -:10931000980F923098F38B3289F3CD010196EC913E -:10932000E03209F082CFDC01F8CF0115110501F719 -:109330008D01DECF1093C1080093C0084093BC0894 -:109340005093BD086093BE087093BF0848CF0F9339 -:109350001F93CF9380919E0890919F080097E9F00A -:10936000FC018F01C1912C2F2F7D81F0C53411F0AC -:10937000C536B9F7F801108270E060E00F94473508 -:10938000F801C083CF911F910F91089570E060E0C4 -:10939000CF911F910F910D94473560E070E0CB01A4 -:1093A000F1CF0E94D4C5882341F081E020919E082E -:1093B00030919F08232B09F480E008954F925F922B -:1093C0006F927F92AF92BF92CF92DF92EF92FF9215 -:1093D0000F931F93CF938CE9A82E82E0B82E9AE8C2 -:1093E000E92E96E0F92E06E712E02DE6C22E2FE0D8 -:1093F000D22EC0E0F50181915F010E94D1C988237E -:1094000009F4A6C00E94A7C92B013C018C2F0E9421 -:10941000ADC5882309F492C0F801208131814281D1 -:109420005381C301B2010F94083EF7016083718339 -:1094300082839383CF5FF4E0EF0EF11C0C5F1F4F2C -:1094400084E0C80ED11CC330A9F685E40E94D1C9BE -:10945000882309F488C00E94A7C96B017C0183E0BE -:109460000E94ADC5882371F0209182023091830261 -:109470004091840250918502C701B6010F94083EC5 -:109480006B017C01C0929606D0929706E0929806F6 -:10949000F092990686E40F94841220E030E0A9014E -:1094A0000F946840181684F40E94A7C920E030E0A9 -:1094B00040E752E40F94023F6093510270935202CE -:1094C00080935302909354028091D40583FD28C069 -:1094D0008091D108882321F120918202309183026A -:1094E0004091840250918502609196067091970692 -:1094F00080919806909199060F94073E2091DE087E -:109500003091DF084091E0085091E1080F94083E47 -:109510006093DE087093DF088093E0089093E10881 -:10952000CF911F910F91FF90EF90DF90CF90BF9060 -:10953000AF907F906F905F904F900895F6012081DB -:10954000318142815381C301B2010F94073E6DCF37 -:10955000F80180819181A281B381F7018083918399 -:10956000A283B38367CF8091820290918302A091FE -:109570008402B09185028093960690939706A093FB -:109580009806B093990686CFCF93DF93EB010E94A4 -:10959000D1C9882321F0DF91CF910C9457C7CE0118 -:1095A000DF91CF910895CF93DF93EB010E94D1C952 -:1095B000882319F00E9447C7EB01CE01DF91CF91BC -:1095C0000895CF93DF93C82FD62F0E94D1C9882347 -:1095D00021F0DF91CF910C946FC78C2F0E94D4C5DE -:1095E000811101C08D2FDF91CF910895FF920F93CC -:1095F0001F93CF93DF93EC019A81A9812881AA233D -:1096000031F08A2F42E0AF3F21F441E001C040E059 -:1096100080E0222351F02F3F59F0882359F0622F28 -:1096200073E028130AC072E001C070E060E005C07A -:1096300071E0FCCF60E0822F72E0992309F44FC003 -:109640009F3FE9F18823E9F1981761F16623D9F189 -:10965000961799F1B0E0092F10E0FD01E01BF10B26 -:10966000F7FF03C0F195E195F109FE2E30E0FD0111 -:10967000E21BF30BF7FF03C0F195E195F1095E2FB3 -:10968000F801E21BF30BF7FF03C0F195E195F10937 -:10969000F51650F4FE16C8F49D01200F311F3695C3 -:1096A0002795822F92E01BC05E1788F0FE1678F097 -:1096B000200F311F36952795622F93E010C091E05F -:1096C0000EC0892FEFCF692FF8CF5E1788F72A0FCA -:1096D0003B1F36952795822F692F93E072E024E097 -:1096E000429FA0011124472B50E1959F9001112426 -:1096F000422B0F94D61988819981482F490F5527FD -:10970000551F8A81840F952F911D21E0833091058B -:109710000CF420E020930B0603974CF0888199818C -:10972000AA818093831690938416A0938516DF9167 -:10973000CF911F910F91FF9008958F929F92AF92BA -:10974000BF92CF92DF92EF92FF92CF93DF9300D040 -:10975000CDB7DEB72FEF8417950731F16A01052EDB -:10976000000CEE08FF084C01092E000CAA08BB08EB -:10977000681779072CF0CB01461757070CF4CA017C -:109780009C01990F440B550B281939094A095B09AB -:10979000AFEFB0E00F94E53DA70196012819390914 -:1097A0004A095B090F94C63D80913A06821759F029 -:1097B00020933A068FEF89831A8220952B83CE015E -:1097C00001960E94F6CA0F900F900F90DF91CF91F3 -:1097D000FF90EF90DF90CF90BF90AF909F908F90D1 -:1097E000089586E896E10C94F6CACF93DF9300D0F3 -:1097F000CDB7DEB719828FEF8A831B82CE01019627 -:109800000E94F6CA0F900F900F90DF91CF910895AC -:1098100083E896E10C94F6CACF93DF9300D0CDB7DE -:10982000DEB780910B06882369F019821A821B82A9 -:10983000CE0101960E94F6CA0F900F900F90DF9113 -:10984000CF9108950E9408CCF7CFCF92DF92EF928C -:10985000FF920F931F93CF9390911A02913009F4C6 -:1098600061C0662351F010927E0810927A0810921F -:109870007B0810927C0810927D08C82F0F941E1D43 -:10988000C0907A08D0907B08E0907C08F0907D082A -:109890009B01AC012C193D094E095F0969017A0150 -:1098A000F7FC40C020917E08C7FD15C04C2F0C2E40 -:1098B000000C550B4C5F5F4FE22F022E000CFF0B8C -:1098C0004E175F077CF144EFC42EDD24D394E12CC6 -:1098D000F12C2C1734F438EEC32E33E0D32EE12CC8 -:1098E000F12CC60ED71EE81EF91EC0927A08D0923F -:1098F0007B08E0927C08F0927D08022F017010E056 -:1099000084E2809FB001819F700D701B112460590B -:109910007C4F82E390E00E948D2B80917E088F5FC8 -:1099200080937E08CF911F910F91FF90EF90DF9071 -:10993000CF9008950F931F93CF93DF93082F10E0DC -:1099400097E1899FF0011124E15CF94FC085D18531 -:10995000209729F164817581868197810F94743FE6 -:109960006E5F7F4F24976C177D07CCF486E0809F55 -:10997000E001819FD00D1124CE5ED94F7983688399 -:109980000F941E1D605E714B8F4F9F4F6A837B83C8 -:109990008C839D83DF91CF911F910F91089586E075 -:1099A000809FF001819FF00D1124EE5EF94F12822D -:1099B000138214821582EECFE62FF0E027E1629F3A -:1099C000D0011124A15CB94FEE0FFF1FE054FD4FF1 -:1099D000208131812F503109821793070CF49C01AB -:1099E00019963C932E931897862F0C949ACCAC0121 -:1099F0008091A00881110EC09091010491110BC0BB -:109A000020916002309161022150310981E04217BA -:109A100053070CF080E0089597E1899FF00111242D -:109A2000E15CF94F20E030E040E05FE36481758164 -:109A3000868197810F94083E0F94743FCB010C945C -:109A4000F7CCCF92DF92EF92FF926B017C0183E320 -:109A5000C816D104E104F10470F082E3C81AD108F9 -:109A6000E108F10862E370E080E090E00F94911C5F -:109A70000E94A591ECCFC701B6010F94911CFF90F5 -:109A8000EF90DF90CF900C94A591809151090E94A6 -:109A9000E48964E670E080E090E00C9421CD809150 -:109AA000860F813069F09091A21792FB882780F988 -:109AB00092FF07C097FB882780F991E089270895D6 -:109AC00081E008958091091690910A16891B8F7084 -:109AD00031F480919A06811104C00C944FCD81E03D -:109AE000089580E008959091A21794FB882780F94B -:109AF00094FF06C081E090915314911101C080E061 -:109B0000089580919A06811110C08091860F82304D -:109B100061F00E9473CD882349F08091A21782FBE7 -:109B2000882780F991E08927089581E00895E2ED82 -:109B3000F5E010821182089581E00895CF93DF93BC -:109B4000EC01E62F660FFF0BE151F84CE491E25077 -:109B5000E13108F0B0C0F0E08827EE54F2438F4FB7 -:109B60000D945C41C3CD5BCE5BCE5BCE5BCEEDCDC9 -:109B7000CFCD11CE0FCEEFCD35CE33CE13CE5BCEC3 -:109B800059CE57CE37CE82E1E5E4F3E0DE01019015 -:109B90000D928A95E1F7CE01DF91CF91089581E092 -:109BA00020EB30E03983288321EB30E03B832A83AC -:109BB0001D821C8223EB30E03F832E8324EB30E0B8 -:109BC000398728871B861A861D861C8692E09E8709 -:109BD0008F8781E0888B198ADECF80E0E1CF81E03A -:109BE0008F5F20E930E03983288321E930E03B832F -:109BF0002A8322E930E03D832C8328E930E03F834B -:109C00002E832AE930E0398728872CE930E03B872A -:109C10002A8726E930E03D872C8793E0D8CF80E083 -:109C2000DFCF80E0DECF81E08F5F20EA30E0398354 -:109C3000288321EA30E03B832A8322EA30E03D8317 -:109C40002C8328EA30E03F832E832AEA30E03987EC -:109C500028872CEA30E03B872A8726EA30E03D87D8 -:109C60002C8794E0B4CF80E0DFCF80E0DECF81E0CE -:109C70008F5F20E231E03983288321E231E03B83AA -:109C80002A8322E231E03D832C8328E231E03F83C6 -:109C90002E832AE231E0398728872CE231E03B87A6 -:109CA0002A8726E231E03D872C8795E090CF80E03F -:109CB000DFCF80E0DECF82E1FE0111928A95E9F7E5 -:109CC0006ACF8F929F92AF92BF92CF92DF92EF9224 -:109CD000FF920F93CF93DF931F92CDB7DEB75C0156 -:109CE0007B0149016B01C40ED51EF5018081918174 -:109CF0000F947E3D8983002311F0F7018083BE011C -:109D00006F5F7F4FC4010F94C40AF5018081918178 -:109D1000019691838083FFEFEF1AFF0AEC14FD0494 -:109D200021F780E00F90DF91CF910F91FF90EF909E -:109D3000DF90CF90BF90AF909F908F9008959091BB -:109D4000C00095FFFCCF8093C600089585E40E9473 -:109D50009FCE81E30C949FCECF93DF93EC01FE0165 -:109D600084912196882319F00E949FCEF8CFDF912D -:109D7000CF9108950F931F93CF938C01C62F89E63F -:109D800092E30E94ACCEC8010E94ACCE8AE30E944E -:109D90009FCE80E38C0F0E949FCE8AE0CF911F91CF -:109DA0000F910C949FCE89E594E30E94ACCE60E0C5 -:109DB00089E494E30E94BACE60E084E394E30E94D5 -:109DC000BACE61E08DE294E30E94BACE61E082E215 -:109DD00094E30E94BACE60E083E194E30E94BACE9D -:109DE00061E083E094E30E94BACE60E08AEF93E3FF -:109DF0000E94BACE61E080EF93E30E94BACE60E0A9 -:109E000086EE93E30E94BACE60E08FED93E30E946A -:109E1000BACE60E087ED93E30E94BACE60E089ECB1 -:109E200093E30E94BACE60E08BEB93E30E94BACE3C -:109E300060E08CEA93E30E94BACE60E08EE993E39F -:109E40000E94BACE60E088E893E30E94BACE60E058 -:109E500087E793E30E94BACE60E082E693E30E9434 -:109E6000BACE60E083E593E30E94BACE61E08CE471 -:109E700093E30E94BACE60E08FE393E30E94BACEF0 -:109E800060E088E393E30E94BACE61E08FE293E35F -:109E90000E94BACE60E08AE193E30E94BACE60E00D -:109EA0008CE093E30E94BACE60E082E093E30E94EC -:109EB000BACE60E08BEE92E30E94BACE60E08EED07 -:109EC00092E30E94BACE61E08BEC92E30E94BACE9C -:109ED00060E08EEB92E30E94BACE61E089EB92E300 -:109EE0000E94BACE60E08CEA92E30E94BACE60E0B3 -:109EF00088E992E30E94BACE60E085E892E30E948E -:109F0000BACE60E08BE89FE00E9456C5682F617072 -:109F10008CE792E30E94BACE60E08EE692E30C9466 -:109F2000BACEE091761081E6E89FF0011124E85264 -:109F3000FF4E8081811107C08AEA9AE30E94ACCE6D -:109F40008AE00C949FCE0895CF92DF92EF92FF9219 -:109F50006A017B010E94ACCE42E0C701B601FF90CE -:109F6000EF90DF90CF900C94FA834F925F926F92B4 -:109F70007F928F929F92AF92BF92CF92DF92EF9299 -:109F8000FF92CF93DF93CDB7DEB72C970FB6F8943F -:109F9000DEBF0FBECDBF83E50E94D4C58823C9F0C4 -:109FA0000E946FC7809337022C960FB6F894DEBFDD -:109FB0000FBECDBFDF91CF91FF90EF90DF90CF909C -:109FC000BF90AF909F908F907F906F905F904F90D9 -:109FD000089562E97DE281E00F94291280913702B1 -:109FE000805D898389E89DE20E94ACCE89810E94D0 -:109FF0009FCE85E89DE20E94ACCE80913702811110 -:10A00000C6C08CE69DE20E94ACCE8AE00E949FCE44 -:10A0100040906D0F50906E0F60906F0F7090700FAA -:10A020002091390230913A0240913B0250913C021A -:10A03000C301B2010F94083E69837A838B839C83AA -:10A040008090710F9090720FA090730FB090740F6A -:10A0500020913D0230913E0240913F0250914002DA -:10A06000C501B4010F94083E6D837E838F8398876A -:10A07000C090750FD090760FE090770FF090780F2A -:10A08000209141023091420240914302509144029A -:10A09000C701B6010F94083E69877A878B879C8732 -:10A0A000209145023091460240914702509148026A -:10A0B000C301B2010F94083E2B013C0120914902DB -:10A0C00030914A0240914B0250914C02C501B401BB -:10A0D0000F94083E4B015C0120914D0230914E02DD -:10A0E00040914F0250915002C701B6010F94083EB3 -:10A0F0006B017C018DE79DE20E94ACCE49815A81C3 -:10A100006B817C818EE499E10E94A4CF4D815E81B8 -:10A110006F8178858FE09CE30E94A4CF49855A85A2 -:10A120006B857C858CE09CE30E94A4CF8BE79DE24D -:10A130000E94ACCE83E79DE20E94ACCEB301A201A7 -:10A140008EE499E10E94A4CFB501A4018FE09CE3C5 -:10A150000E94A4CFB701A6018CE09CE30E94A4CF8B -:10A160008AE02C960FB6F894DEBF0FBECDBFDF910C -:10A17000CF91FF90EF90DF90CF90BF90AF909F90E6 -:10A180008F907F906F905F904F900C949FCE80E760 -:10A190009DE239CF0E94A4CF8AE00C949FCE2F92EB -:10A1A0003F924F925F926F927F928F929F92AF9267 -:10A1B000BF92CF92DF92EF92FF920F931F93CF93B4 -:10A1C000DF93CDB7DEB7CE55D1090FB6F894DEBF19 -:10A1D0000FBECDBF70E060E085E40E94C4CA082FC6 -:10A1E0008EA3823008F042C083E40E94D1C981115D -:10A1F0005FC025E02BAB83E50E94D1C9882309F419 -:10A200005BC00E9457C79A8B898B60E085E50E94EE -:10A21000E1CA2F968FAF2F9760E085E697E30E9403 -:10A220001D3B0F941E1D6B8B7C8B8D8B9E8BE02EAC -:10A23000002E000CFF08F701A3E0EE0FFF1FAA9508 -:10A24000E1F7EC59FD4F868197810E9789889A88AE -:10A2500088169906B4F188E597E30E94ACCE89E3AD -:10A2600097E30E94ACCE0F948E1008C08AEE95E35F -:10A270000E94ACCE82ED95E30E94ACCEC25ADF4F75 -:10A280000FB6F894DEBF0FBECDBFDF91CF911F9107 -:10A290000F91FF90EF90DF90CF90BF90AF909F9085 -:10A2A0008F907F906F905F904F903F902F90089588 -:10A2B0000E9457C78BAB9FCF48EC50E05A8B498B1D -:10A2C000A4CF2B893C894D895E89205E314B4F4F4D -:10A2D0005F4F27962CAF3DAF4EAF5FAF27978CE215 -:10A2E00097E30E94ACCE84E297E30E94ACCE0E943A -:10A2F000B48587E18E9D90018F9D300D1124A901B9 -:10A30000415C594F5A019FE7DA011A969C93089FC6 -:10A3100080011124F801E15CF94F4F01248135815E -:10A320004681578163962CAF3DAF4EAF5FAF6397C9 -:10A3300010923A060E9479862B966DAF7EAF8FAF52 -:10A340002B9760E089E197E30E941D3B81E08093B9 -:10A3500074022B893C894D895E892FA338A749A7B0 -:10A360005AA72AAF3BAF4CAF5DAF1FA618AA19AAD8 -:10A370001AAA1BA61CA61DA61EA61F821886198631 -:10A380001A868FE790E0A0E0B0E08F8B988FA98FBE -:10A39000BA8F1D8690E49C8FACE1AD8FB6E4BE8F82 -:10A3A0001F8E18A219A21AA2FFE7CF2ED12CE12CE2 -:10A3B000F12C1EAE23961CAE1DAE1EAE1FAE239713 -:10A3C0001EAA1FAA18AE19AEE1E0EB8F1C861B86F1 -:10A3D00010E000E0212C312C94012C5F3F4F3DAB6D -:10A3E0002CABA501465F5F4F2D965FAF4EAF2D970B -:10A3F00089899A894E964C01990FAA08BB086796DD -:10A400008CAE9DAEAEAEBFAE679789899A894E97E6 -:10A410004C01990FAA08BB086B968CAE9DAEAEAEF0 -:10A42000BFAE6B9789899A8906974C01990FAA0844 -:10A43000BB086F968CAE9DAEAEAEBFAE6F978091EF -:10A440007402882309F421C20F941E1D2B013C01C4 -:10A4500090902D0628969FAE2897992009F4FEC16A -:10A460000E94E59010922D06ACA9BDA91C911196F1 -:10A470000C91119712962C90129713963C902F8D59 -:10A4800038A149A15AA1612F702FC1010F946840D2 -:10A49000181624F41F8F08A329A23AA22D853C8DFB -:10A4A0004D8D5E8D612F702FC1010F94B13987FFE3 -:10A4B00004C01D870C8F2D8E3E8E612F702FC10121 -:10A4C0000F94743F4B0163966CAD7DAD8EAD9FAD27 -:10A4D00063970F94743FCB0149895A89B4010E9454 -:10A4E0009DCBE989FA894F01FF0FAA08BB08FB8DB4 -:10A4F000FF2309F449C0C501B4010F94B8396BA317 -:10A500007CA38DA32E969FAF2E979B01AC01612F4C -:10A51000702FC1010F94684018160CF09FC1B30151 -:10A52000A2018FA198A5A9A5BAA5481B590B6A0B32 -:10A530007B0BDB01CA0188589341A109B109B7FD22 -:10A540008DC18F89988DA98DBA8D8C199D09AE0901 -:10A55000BF09B595A795979587952D96EEADFFAD5B -:10A560002D9780834EAB5FAB68AF79AFFBA1FF8FB8 -:10A570002CA128A33DA139A32E964FAD2E974AA317 -:10A580004B8A5C8A6D8A7E8AC501B4010F94B83902 -:10A590006B8F7BA38CA39DA39B01AC01612F702FBC -:10A5A000C1010F94B13987FD02C01B8E57C1D30181 -:10A5B000C2018B889C88AD88BE8888199909AA0930 -:10A5C000BB09AC01BD01485853416109710977FDD0 -:10A5D000ECCFAB84BC84AB2809F4FEC08EA89FA846 -:10A5E000A8ACB9AC880E991EAA1EBB1E2EA93FA905 -:10A5F00048AD59AD281B390B4A0B5B0BC701B6019F -:10A600000F94943DA50194010F94C63DCF88D88C3A -:10A61000E98CFA8CC20ED31EE41EF51E24E1C2168C -:10A62000D104E104F1040CF445C13CEEC316D1049D -:10A63000E104F1040CF038C140E8C416D104E1048F -:10A64000F1040CF445C1CF8AD88EE98EFA8E8EEFD4 -:10A6500090E0A0E0B0E09C01AD012C193D094E094D -:10A660005F0969017A0181E197E30E94ACCE6F89AD -:10A67000788D898D9A8D0F942A0E8CE097E30E9435 -:10A68000ACCEC701B6010F942A0E4D855C8D6D8D41 -:10A690007E8D85E097E30E94A4CF4F8D58A169A1DC -:10A6A0007AA18EEF96E30E94A4CFAB85BC85139769 -:10A6B0000CF492C0C701B6010F94B83920E030E025 -:10A6C00040E850E40F94173A6F83788789879A8718 -:10A6D0002D853C8D4D8D5E8D6F8D78A189A19AA1C0 -:10A6E0000F94073E2BED3FE049E450E40F94173AF6 -:10A6F00020E030E040E05FE30F94173A9B01AC01AB -:10A700006F81788589859A850F94023F6D877E8752 -:10A710008F87988BC501B4010F94B8392FE632E1C9 -:10A7200043E85AE30F94173A4B015C012AE939E9EF -:10A7300049E15FE36D857E858F8598890F94173A8F -:10A740006F83788789879A879B01AC010F94083EB5 -:10A75000A50194010F94023F6BA77CA78DA79EA72C -:10A760002F81388549855A85C501B4010F94173A60 -:10A7700020E030E040E05EE30F94173A6FA778AB3B -:10A7800089AB9AAB4D855E856F85788988EF96E3B6 -:10A790000E94A4CFB501A40182EF96E30E94CAD023 -:10A7A00083EE96E30E94ACCE4F81588569857A8509 -:10A7B0008DED96E30E94A4CF4BA55CA56DA57EA56B -:10A7C00087ED96E30E94A4CF4FA558A969A97AA95D -:10A7D00081ED96E30E94CAD08F89988DA98DBA8D9C -:10A7E0008C0D9D1DAE1DBF1DB595A79597958795A1 -:10A7F0002D96EEADFFAD2D9780838BA8882D082C6C -:10A80000000C990B9F938F929C849F92AB84AF9284 -:10A810008DEB96E39F938F9388EC96E39F938F93B2 -:10A820001F920E94FA3A2B853C852F5F3F4F3C8751 -:10A830002B870FB6F894DEBF0FBECDBF8B8C8D86F5 -:10A840009BA09C8EACA0AD8EBDA0BE8E4FA258A684 -:10A8500069A67AA628968FAC28978B8E67966CADE2 -:10A860007DAD8EAD9FAD67970F94B839212F302FF6 -:10A87000A1010F94B13987FF30C080EB96E30E94AD -:10A88000ACCE81E996E30E94ACCE109274020E9495 -:10A89000B4852B968DAC9EACAFAC2B978C829D82F1 -:10A8A000AE82CE0104963AC14BEEC42ED12CE12CDF -:10A8B000F12CC9CE84E190E0A0E0B0E08F8B988FBE -:10A8C000A98FBA8F34E1C32ED12CE12CF12CCBCE41 -:10A8D000CF8AD88EE98EFA8EC6CED301C2018AAC59 -:10A8E0009BACACACBDAC88199909AA09BB09B7FDF2 -:10A8F0004DC08EA10E949E848AE00E949FCEA3013B -:10A9000092012053384F4F4F5F4F2AAF3BAF4CAFB0 -:10A910005DAF8EAC811072C023962CAD3DAD4EADB7 -:10A920005FAD2397612F702FC1010F9468401816F7 -:10A930000CF04EC020E030E040E050E4612F702F7A -:10A94000C1010F94083E23966CAF7DAF8EAF9FAFD1 -:10A950002397A3019201205E314B4F4F5F4F279603 -:10A960002CAF3DAF4EAF5FAF27976F966CAD7DAD0F -:10A970008EAD9FAD6F970F94B839212F302FA10165 -:10A980000F94B139881F8827881F8EAF8B899C89C7 -:10A99000AD89BE898FA098A4A9A4BAA488169906E7 -:10A9A000AA06BB0610F4D501C401481A590A6A0A5E -:10A9B0007B0A21E842162FE4520622E16206710466 -:10A9C00098F184E896E30E94ACCE82E796E35BCFF1 -:10A9D000D301C20127968CAC9DACAEACBFAC27971F -:10A9E00088199909AA09BB094AE053E269E173E2AF -:10A9F000B7FDCCCF8EA10E94908FC8CF6B966CAD67 -:10AA00007DAD8EAD9FAD6B970F94B8399B01AC01B6 -:10AA1000612F702FC1010F94B13987FFB7CF47E481 -:10AA200053E267E573E2E6CF8BA8882D880C990B7B -:10AA3000AB84BC848A159B050CF073C09501233050 -:10AA400031050CF46EC085E696E30E94ACCE84E13D -:10AA500096E30E94ACCE87EF95E30E94ACCE4F8187 -:10AA6000588569857A8580E196E30E94CAD087EF90 -:10AA700095E30E94ACCE4BA55CA56DA57EA58CE0B0 -:10AA800096E30E94CAD087EF95E30E94ACCE4FA513 -:10AA900058A969A97AA988E096E30E94CAD02F969E -:10AAA0008FAC2F97882081F18F809884A984BA84F5 -:10AAB00080924A0690924B06A0924C06B0924D06A8 -:10AAC0002CEA35EC47E25EE36BA57CA58DA59EA53F -:10AAD0000F94173A60934E0670934F06809350067A -:10AAE000909351062CEA35EC47E25EE36FA578A916 -:10AAF00089A99AA90F94023F609352067093530656 -:10AB000080935406909355062B968DAC9EACAFACBB -:10AB10002B9789829A82AB82CE0101960E94F6CA57 -:10AB2000A2CB0E94446B8BCCCF93DF936DE572E395 -:10AB30000F942912C6EED8E0488159816A817B8141 -:10AB400084E592E30E94A4CF4C815D816E817F8178 -:10AB50008FE09CE30E94A4CF488559856A857B8558 -:10AB60008CE09CE3DF91CF910C94CAD060ED7CE245 -:10AB70000F942912609165097091660980916709A7 -:10AB8000909168090F94B639AB01BC0187EC9CE247 -:10AB90000E94A4CF40919509509196096091970920 -:10ABA0007091980984EC9CE20E94A4CF409199098D -:10ABB00050919A0960919B0970919C0981EC9CE2EB -:10ABC0000E94A4CF4091FE055091FF0560910006C0 -:10ABD000709101068EEB9CE20C94CAD0CF93DF9368 -:10ABE00064E77CE20F942912C5E5D9E04CA95DA980 -:10ABF0006EA97FA98BE69CE20E94A4CF48AD59AD17 -:10AC00006AAD7BAD88E69CE20E94A4CF4CAD5DAD01 -:10AC10006EAD7FAD81EC9CE2DF91CF910C94CAD0F8 -:10AC2000CF93DF9360E57CE20F942912C5E5D9E06C -:10AC30004CA15DA16EA17FA187E49CE20E94A4CFFC -:10AC400048A559A56AA57BA58FE09CE30E94A4CFE7 -:10AC50004CA55DA56EA57FA58CE09CE30E94A4CFCA -:10AC600048A959A96AA97BA989E09CE3DF91CF9102 -:10AC70000C94CAD0CF93DF936BE27CE20F9429123D -:10AC8000C5E5D9E0688179818A819B810F94B639C5 -:10AC9000AB01BC0182E29CE20E94A4CF6C817D8169 -:10ACA0008E819F810F94B639AB01BC018FE09CE38C -:10ACB0000E94A4CF688579858A859B850F94B639D3 -:10ACC000AB01BC018CE09CE30E94A4CF6C857D8528 -:10ACD0008E859F850F94B639AB01BC0189E09CE35A -:10ACE000DF91CF910C94CAD0CF93C62F0E94ACCEE7 -:10ACF0006C2F70E090E080E0CF910D94C00D0E9429 -:10AD000074D68AE00C949FCE69E375E30F94291200 -:10AD100060912E0280E395E30C947FD66CE27DE295 -:10AD20000F94291285E29DE20E94ACCE40918606E6 -:10AD30005091870660918806709189068CE09CE3AB -:10AD40000C94CAD0CF93C62F0E94ACCE6C2FCC0FE0 -:10AD5000770B880B990BCF910D942A0EEF92FF92EF -:10AD60000F931F93CF93DF9361E87FEF8FE40E94EF -:10AD7000C4CAD82F813879F18FEF8D0F8F3058F1F9 -:10AD800080E79FE20E94ACCE11E061E87FEF80E5B2 -:10AD90000E94C4CAC82F813849F083E08C0F8031EB -:10ADA00028F086E59FE20E94ACCE11E061E87FEFDB -:10ADB00083E50E94C4CA813881F09FEF980F9830D4 -:10ADC00060F08EE39FE2DF91CF911F910F91FF9092 -:10ADD000EF900C94ACCE10E0D8CF111115C1D13842 -:10ADE00009F4D3E0C13809F4CFEF182F813809F402 -:10ADF00011E08CE9E82E82E0F82E00E081E0F70116 -:10AE000091917F0191544091BC085091BD0860918F -:10AE1000BE087091BF0804C0769567955795479511 -:10AE20009A95D2F740FF19C06D2F023009F4C3C0C4 -:10AE3000033009F4CDC0013009F4B0C08FEA95E1C8 -:10AE40000F94EA216C2F8FEA95E10F94F020612F87 -:10AE50008FEA95E10F94DF2080E00F5F043079F6F0 -:10AE6000882309F4D1C088E50E949FCE8FEA95E13E -:10AE70000F94E521682F8DE99EE20E9474D68FEA37 -:10AE800095E10F94E720682F84E99EE20E94A2D604 -:10AE90008FEA95E10F94D620682F8AE89EE20E94FF -:10AEA0007FD689E50E949FCE83E795E10F94E52147 -:10AEB000682F81EC9EE20E9474D683E795E10F949F -:10AEC000E720682F88EB9EE20E94A2D683E795E1F7 -:10AED0000F94D620682F8EEA9EE20E947FD68AE5E4 -:10AEE0000E949FCE87E395E10F94E521682F85EEC0 -:10AEF0009EE20E9474D687E395E10F94E720682FC5 -:10AF00008CED9EE20E94A2D687E395E10F94D620B5 -:10AF1000682F82ED9EE20E947FD685E40E949FCE3C -:10AF20008BEF94E10F94E521682F89E09FE20E9466 -:10AF300074D68BEF94E10F94E720682F80E09FE2B6 -:10AF40000E94A2D68BEF94E10F94D620682F86EF53 -:10AF50009EE20E947FD60E94A6CE8FEB94E10F94D2 -:10AF6000E521682F8DE29FE20E9474D68FEB94E179 -:10AF70000F94E720682F84E29FE20E94A2D68FEB15 -:10AF800094E10F94D620682F8AE19FE2DF91CF9160 -:10AF90001F910F91FF90EF900C947FD683E795E17E -:10AFA0000F94EA216C2F83E795E10F94F020612F35 -:10AFB00083E795E14FCF87E395E10F94EA216C2F6A -:10AFC00087E395E10F94F020612F87E395E142CF6D -:10AFD0008BEF94E10F94EA216C2F8BEF94E10F94A7 -:10AFE000F020612F8BEF94E10F94DF206D2F8FEB1A -:10AFF00094E10F94EA216C2F8FEB94E10F94F020F1 -:10B00000612F8FEB94E126CFDF91CF911F910F91AC -:10B01000FF90EF90089585E79AE20C94ACCE8FE60E -:10B020009AE20C94ACCECF9384E50E94D1C9C09132 -:10B0300051098823D9F00E945BC7C82F8230B4F031 -:10B040000E940FD88DE40E949FCE6091C20870913B -:10B05000C30890E080E00F94C00D6C2F8CE89FE255 -:10B060000E94A2D68AE00E949FCECFEF8C2FCF9174 -:10B0700008954F925F926F927F928F929F92AF92BC -:10B08000BF92CF92DF92FF920F931F93CF93DF93E4 -:10B090009091D40593FD13C1D82F0E9413D8C82FC7 -:10B0A00087FD0DC189E40E94D1C9882309F47CC0C1 -:10B0B0000E945BC790E01816190614F481E090E036 -:10B0C00026E0289FF001299FF00D1124EE50FA4F41 -:10B0D00080819181F12C6C2F0E94DCCC61E08D2F5E -:10B0E0000E94DEBB0C2F0C2E000C110B37E1C302AB -:10B0F000C0011124FC01E15CF94F6F01608571858D -:10B10000072E000C880B990B0F94B8394B015C018A -:10B11000F6014480558066807780A30192010F94E8 -:10B120006840181614F0F11039C00F5C1F4FD11190 -:10B13000BAC0A3019201C501B4010F94684018166A -:10B140000CF084C0DD24D39489E197E39F938F931F -:10B150001F930F938DEA95E39F938F931F920E9405 -:10B16000FA3A2DB73EB7295F3F4F0FB6F8943EBF6E -:10B170000FBE2DBFDD2041F0C09339068DE490E76E -:10B18000909318128093171211E017C082E50E9465 -:10B19000D1C9882389F00E9457C79DCF1F2D0DC0AC -:10B1A00060E070E0CB0126C083E50E94D1C9F82E93 -:10B1B0008111F1CFD111EACF10E083E50E94D1C90E -:10B1C000882331F00E9457C7909319028093180288 -:10B1D00082E40E94D1C9882331F00E9457C790931E -:10B1E00017028093160286E40E94D4C58823C1F218 -:10B1F0000E94A7C9609312027093130280931402F5 -:10B200009093150201E020E030E0A9010F94B139DC -:10B21000811101C000E000936D06DD2309F44FC0E9 -:10B22000112309F44CC06F2D8C2FDF91CF911F910A -:10B230000F91FF90DF90CF90BF90AF909F908F9035 -:10B240007F906F905F904F900C94888682EA95E390 -:10B250009F938F931F930F938DEA95E39F938F9303 -:10B260001F920E94FA3A2DB73EB7295F3F4F0FB6A3 -:10B27000F8943EBF0FBE2DBF7FCF89E197E39F9328 -:10B280008F931F930F938DEA95E39F938F931F9254 -:10B290000E94FA3A8DB79EB707960FB6F8949EBFF4 -:10B2A0000FBE8DBF71CFA3019201C501B4010F94F0 -:10B2B0006840181614F3D12C82EA95E347CFDF914A -:10B2C000CF911F910F91FF90DF90CF90BF90AF90E3 -:10B2D0009F908F907F906F905F904F9008950F9305 -:10B2E0001F93CF93811116C0C42F8B010E940FD8DA -:10B2F00089E89FE20E94ACCEC8010E94ACCECC236C -:10B3000049F08AE30E949FCE8AE0CF911F910F916E -:10B310000C949FCECF911F910F910895811102C07F -:10B320000C940FD808951F93CF93DF93D82F162F27 -:10B3300041E061E67DE20E946FD9C0E01C1711F088 -:10B340001F3FD1F58D2F0E948ED940914A06509112 -:10B350004B0660914C0670914D0688E59DE20E9477 -:10B36000A4CF2CEA35EC47E25EE360914E06709183 -:10B370004F0680915006909151060F94023FAB0109 -:10B38000BC0185E59DE20E94A4CF2CEA35EC47E2A2 -:10B390005EE360915206709153068091540690913D -:10B3A00055060F94173AAB01BC0182E59DE20E945D -:10B3B000A4CF8AE00E949FCEC13021F4DF91CF91CB -:10B3C0001F910895C1E0BACFCF93DF93C82F63E4F4 -:10B3D0007DE20F9429128C2F0E948ED961E08AE3BE -:10B3E0009DE20E9474D6CEE6D6E04C855D856E85E2 -:10B3F0007F858EE499E10E94A4CF488959896A89A2 -:10B400007B898FE09CE30E94A4CF8CE09CE30E94A8 -:10B41000ACCE6C897D898E899F8943E00E94FA8336 -:10B420008AE0DF91CF910C949FCECF93DF93C82F0A -:10B43000811113C040E060E17CE280E00E946FD99E -:10B440008091F105811104C083E09CE20E94ACCEA2 -:10B450008AE00E949FCE0E940FD8D091F1058AEF1A -:10B460009BE20E94ACCE6D2F70E090E080E00F94E4 -:10B470002A0E8AE00E949FCE8C2F0E948ED960E017 -:10B4800081EF9BE20E94A2D64091E9055091EA0526 -:10B490006091EB057091EC058EEE9BE20E94CAD0A4 -:10B4A0008C2F0E948ED961E081EF9BE20E94A2D690 -:10B4B0004091ED055091EE056091EF057091F0051A -:10B4C0008EEE9BE2DF91CF910C94CAD0CF93C82F20 -:10B4D0004091510982E0C11184E060E00E94092E90 -:10B4E0000E940FD88DE89AE2CC2311F085EA9AE207 -:10B4F000CF910C94ACCECF93DF93EB010E94ACCEF6 -:10B50000BE0190E080E0DF91CF910D94C00DCF930C -:10B51000DF93EB010E94ACCEBE01DD0F880B990BCF -:10B52000DF91CF910D942A0E5F926F927F928F924E -:10B530009F92AF92BF92CF92DF92EF92FF920F93C2 -:10B540001F93CF93DF931F92CDB7DEB77C013901F4 -:10B550008B015B01A40EB51ED12CC12CA016B10627 -:10B5600009F450C0F70180809180F80151908F015B -:10B570005982C4010F947E3D5816B9F1652DC4015E -:10B580000F94863DFFEFCF1ADF0AC6018F77992708 -:10B59000892B21F162E070E080E090E00F94911C33 -:10B5A000C4010F947E3D99818917F9F00E940FD84C -:10B5B00085EF97E20E94ACCE81E00F90DF91CF91B2 -:10B5C0001F910F91FF90EF90DF90CF90BF90AF90C1 -:10B5D0009F908F907F906F905F90089562E070E0F1 -:10B5E00080E090E00E9421CDDBCFBE016F5F7F4FF6 -:10B5F000C3010F94C40AF701808191810196918360 -:10B600008083ACCF80E0D9CF0E947BDA8AE00C94B3 -:10B610009FCE0E94ACCE8AE00C949FCEEF92FF9218 -:10B620001F93CF93DF9383E50E94D4C5882309F449 -:10B6300045C06EEF7FEF84E50E94C4CA182F8230A8 -:10B6400008F01EEF0E946FC7D82F8CE9E82E82E029 -:10B65000F82EC0E0F70181917F010E94D4C58823B4 -:10B6600051F0C23089F0C330A1F0C13041F0D09325 -:10B67000EA150F940112CF5FC43061F719C0D0935F -:10B68000AE150F940912F7CFD09372150F941112C3 -:10B69000F2CF11163CF4113059F4D093FA140F94F0 -:10B6A0002112E9CFD09336150F9419121111F5CF4D -:10B6B000DF91CF911F91FF90EF90089588E50E9450 -:10B6C0009FCE8FED9DE20E94ACCE8FEA95E10F9464 -:10B6D000C221882309F44CC087EC9DE20E9409DB5B -:10B6E00089E50E949FCE86E09EE20E94ACCE83E771 -:10B6F00095E10F94C2218823F1F18EEE9DE20E9424 -:10B7000009DB8AE50E949FCE8DE29EE20E94ACCECC -:10B7100087E395E10F94C221882381F185E19EE2C0 -:10B720000E9409DB85E40E949FCE84E59EE20E9490 -:10B73000ACCE8BEF94E10F94C221882311F18CE3FE -:10B740009EE20E9409DB0E94A6CE8BE79EE20E9449 -:10B75000ACCE8FEB94E10F94C2218823A9F083E64D -:10B760009EE2DF91CF911F91FF90EF900C9409DB47 -:10B7700083ED9DE2B3CF8AEF9DE2C1CF81E29EE2ED -:10B78000CFCF88E49EE2DDCF8FE69EE2EACF0F9333 -:10B790001F93CF93DF93082F41E062EB7DE20E947D -:10B7A0006FD9C9EDD5E010E0802F0E948ED9612FAE -:10B7B00089EA9DE20E94A2D64C815D816E817F81E3 -:10B7C00086EA9DE20E94A4CF488159816A817B81EB -:10B7D00083EA9DE20E94A4CF80EA9DE20E94ACCE63 -:10B7E0008DED98E10E9409DB2896113029F4DF9154 -:10B7F000CF911F910F91089511E0D6CFFF920F9333 -:10B800001F93CF93DF93F62E042F122F882329F155 -:10B810008CE09BE20E94ACCE88E50E949FCE8CEF2C -:10B820009AE20E94ACCE8FEA95E10F94F820D82FCF -:10B83000882361F080EF9AE20E94ACCE88EE9AE213 -:10B84000D13031F084EE9AE2D23011F08DEE9AE2EE -:10B850000E9409DBC1E0D11101C0C0E0FF2039F135 -:10B860008DE39BE20E94ACCE89E50E949FCE8DE2E3 -:10B870009BE20E94ACCE83E795E10F94F820D82F8D -:10B88000882361F081E29BE20E94ACCE89E19BE2D9 -:10B89000D13031F085E19BE2D23011F08EE19BE2B4 -:10B8A0000E9409DB81E0D11101C080E0C80F0023B4 -:10B8B00039F18EE69BE20E94ACCE8AE50E949FCED3 -:10B8C0008EE59BE20E94ACCE87E395E10F94F820D1 -:10B8D000D82F882361F082E59BE20E94ACCE8AE4F7 -:10B8E0009BE2D13031F086E49BE2D23011F08FE45C -:10B8F0009BE20E9409DB81E0D11101C080E0C80F0A -:10B90000112309F44DC08FE99BE20E94ACCE85E47F -:10B910000E949FCE8FE89BE20E94ACCE8BEF94E119 -:10B920000F94F820D82F882361F083E89BE20E94CF -:10B93000ACCE8BE79BE2D13031F087E79BE2D2308F -:10B9400011F080E89BE20E9409DB81E0D11101C087 -:10B9500080E0C80F80ED9BE20E94ACCE0E94A6CE94 -:10B9600080EC9BE20E94ACCE8FEB94E10F94F82028 -:10B97000D82F882361F084EB9BE20E94ACCE8CEA46 -:10B980009BE2D13031F088EA9BE2D23011F081EBBA -:10B990009BE20E9409DB81E0D11101C080E0C80F69 -:10B9A000CC2351F060E089ED9BE2DF91CF911F91B4 -:10B9B0000F91FF900C941D3BDF91CF911F910F9140 -:10B9C000FF900895CF93DF9300D0CDB7DEB78C0101 -:10B9D0007B01D42E0E94B4850115110509F481C0A4 -:10B9E0000E940FD8C8010E9409DBE114F10421F480 -:10B9F0009EE6E92E9AE2F92E0E945940FF92EF92BC -:10BA00001F930F938EE39AE29F938F9381E08F931E -:10BA10000E94FA3A0E945E2D8FEF89831A821B8260 -:10BA2000CE0101960E94F6CA10914A1616951695F7 -:10BA300085E496E10E94126B012F000FF02EF10EAB -:10BA40000FB6F894DEBF0FBECDBF83E00E94AA3FC1 -:10BA5000109280161093811689E192E10E94AD4206 -:10BA60004FE25AE2602F80E00E94C46442E25AE250 -:10BA70006F2D80E00E94C46489E496E10F94E7246E -:10BA80008111E3CF0E940BD88EE49AE20E94ACCEE3 -:10BA900089EE93E0019739F000C00000EEE5F9E08F -:10BAA0003197F0F7F7CFF89489EE93E0019739F0EA -:10BAB00000C00000E6EEF3E03197F0F7F7CF0E9408 -:10BAC000B485DD2031F00E943CB7909905C0A8955F -:10BAD000FCCF0E94FE89F9CF909B02C0A895FCCFB5 -:10BAE000FFCFE114F10421F48EE6E82E8AE2F82E6D -:10BAF00005E41AE281CF80918C0F90918D0F2FEF8A -:10BB00003FEF981751F0E92FF0E0E457F04F228112 -:10BB100030E09F5F9F7790938D0FC90108951F922A -:10BB20000F920FB60F9211240F900FBE0F901F901F -:10BB300018951F920F920FB60F9211240BB60F9209 -:10BB40002F938F939F93EF93FF939091C600209133 -:10BB50008D0FE0918C0F81E08E0F8F77281729F0E1 -:10BB6000F0E0E457F04F9283E82FE0938C0FFF91C1 -:10BB7000EF919F918F912F910F900BBE0F900FBE61 -:10BB80000F901F9018958EBD0DB407FEFDCF089540 -:10BB90008FEF8EBD0DB407FEFDCF8EB50895909149 -:10BBA00064009B7F90936400982F906A96959CBD4B -:10BBB00080FD03C091E0863009F490E09DBD0895BA -:10BBC000CF93DF93EB010E94ACCECE01DF91CF91FA -:10BBD0000D94D6262F923F924F925F926F927F9252 -:10BBE0008F929F92AF92BF92CF92DF92EF92FF928D -:10BBF0000F931F93CF93DF9300D000D01F921F921B -:10BC0000CDB7DEB7B82E80917510843008F0E7C14B -:10BC100061E6D62E80917510843008F025C18091A0 -:10BC20008C0F90918D0F891B8F7709F41DC10E9495 -:10BC30007BDD97FF0BC00E940BD88BE399E20E943B -:10BC4000ACCE80918C0F80938D0FE4CF8A3019F0A9 -:10BC50008D3009F000C110927410809112109091F3 -:10BC60001310FC01E25FFF4E1682892B19F40E942B -:10BC7000A591D0CF109213101092121004E110E190 -:10BC8000F8018191803209F446C08E3409F09DC0DC -:10BC900066E379E2C8010F942E397C01892B41F0CB -:10BCA0006EE470E0C80104960F94E241009709F435 -:10BCB000C8014AE050E070E060E001960F94A536BC -:10BCC0002B013C0180910E1090910F10A09110104B -:10BCD000B09111100196A11DB11D481659066A06B2 -:10BCE0007B0629F060E083E099E2EF2851F16AE2F7 -:10BCF00070E0C8010F9411429C01009729F1982F20 -:10BD0000901BF12C992349F09150F801E90FF11D96 -:10BD10008081F826F7CF8F01B3CF4AE050E070E082 -:10BD200060E0C90101960F94A5362F2D30E050E058 -:10BD300040E0621773078407950751F060E084EED6 -:10BD400098E20F945B0F66CF60E08AEB98E2F9CF40 -:10BD500040920E1050920F106092101070921110BD -:10BD6000809135098130E1F467E470E0C8010F94F7 -:10BD7000E2410097A9F04AE050E070E060E00196EF -:10BD80000F94A536643071058105910548F489E169 -:10BD900098E20E94ACCE60E08FE098E20E941D3BEA -:10BDA000F80180818D3489F58381823309F446C09E -:10BDB000883309F1803349F58181843331F58281FB -:10BDC000813319F50E9439B820C08091A21780FFF5 -:10BDD000C7CF67ED7AE3C8010F942E39009739F089 -:10BDE000DC0113968C9180538A3008F0B9CF60E063 -:10BDF00080E998E2A6CF8281803339F48181813352 -:10BE000021F41092740210924F09809114108B3318 -:10BE100009F400CF80917510843008F0FBCE80913A -:10BE200077108D9DC001112464E170E188589F4E08 -:10BE30000F94ED4180E00F941C0FECCE8281813392 -:10BE400021F78181813309F741E070E060E084EF00 -:10BE500090E30E94E2DC22E130E144E150E164E75A -:10BE600070E10E9459C5D6CE8091A21783FDB7C05C -:10BE700082FFB5C087FDB3C01A82198231E6F32E66 -:10BE800044E0E42E59E6D52E80917510843008F0F8 -:10BE9000A6C00E9491C58111A2C041E050E0BE0140 -:10BEA0006D5F7F4F80E594E10E94167D0B8110E06D -:10BEB000019711F00FEF1FEF8091581490915914D2 -:10BEC000A0915A14B0915B1480939E1790939F1782 -:10BED000A093A017B093A1170E9491C50F3F100720 -:10BEE00049F4811107C00E940BD883E599E20E94B2 -:10BEF000ACCECACF40917710242F30E00A3061F0E9 -:10BF00000D3051F0882309F45CC089819A81009733 -:10BF100019F001969A8389831092620889819A8127 -:10BF2000F29EF001F39EF00D1124EB58FF4EE80F46 -:10BF3000F91F1382892BA9F50E94A5910E9491C532 -:10BF4000882309F4A1CF80E594E10E945E7E809170 -:10BF50009917882361F18150809399178D9DC001B5 -:10BF6000112462E08156994F0E945EBEE0919917BC -:10BF700024E0E29FF0011124E556F94F4081518100 -:10BF80006281738140939E1750939F176093A0170F -:10BF90007093A11780E594E10E94827C0E949279BF -:10BFA00073CF1A82198281E00F941C0FC7CF0E94B1 -:10BFB000677E8091A21788608093A217E09235096E -:10BFC00063CF4F9DA001112448585F4E9E012F5F03 -:10BFD0003F4F62E678E0802F0E9459C555CF0F94FD -:10BFE0001E1D6B017C01B11004C080919A0688234C -:10BFF00051F0C0923B06D0923C06E0923D06F09292 -:10C000003E06BB24B39480919A0890919B08A0911E -:10C010009C08B0919D080097A105B10551F1409190 -:10C020003B0650913C0660913D0670913E06840FA0 -:10C03000951FA61FB71FA7019601281B390B4A0B96 -:10C040005B0BDA01C901B7FD14C00E940BD881EB6C -:10C0500099E20E94ACCE609153097091540986E830 -:10C0600099E20F94E22640E070E060E090E080E02A -:10C07000F0CE9091091680910A16981741F0C0925F -:10C080003B06D0923C06E0923D06F0923E0640917F -:10C090005A0250915B0260915C0270915D02452BE7 -:10C0A000462B472B21F0981701F110926D088091D3 -:10C0B0006B0890916C08909946C0019690936C081B -:10C0C00080936B0880916B0890916C088E3E924033 -:10C0D0000CF43FC00E940BD883E799E20E94ACCEDB -:10C0E00082E699E20E94ACCEBECFB110DECF0F94B3 -:10C0F0001E1D00913B0610913C0620913D0630919B -:10C100003E0680905A0290905B02A0905C02B09034 -:10C110005D02080D191D2A1D3B1D601B710B820B52 -:10C12000930B97FDC2CF80916D088111C0CF81E044 -:10C1300080936D0880E00E9400B781E00E9400B704 -:10C140000E94FE89B4CF181619060CF0BBCF0197D8 -:10C15000B5CF8091670890916808A0916908B09167 -:10C160006A0846015701881A990AAA0ABB0AD5012A -:10C17000C401B7FD72C19091091680910A165091C1 -:10C1800056024091570298131EC08091D20558174D -:10C19000C1F08093560281E02091D305421779F1D6 -:10C1A000209357020F941E1D6091560270E084E0A8 -:10C1B0000F94E9186091570270E089E00F94E91834 -:10C1C00020C080E0E9CFE0910A162E2F30E08DE507 -:10C1D000E89FF0011124EC50F64F8081581769F068 -:10C1E0008093560281E09DE5929FF001939FF00DB0 -:10C1F0001124EB50F64F2081D1CF80E0F4CF811194 -:10C20000D1CF80916D06882309F41AC1809051091D -:10C2100088868090180290901902A88427E1A29E37 -:10C22000F0011124E15CF94FC401029720853185AA -:10C23000281739070CF404C110910A16712C00E07C -:10C240001C82612C80910916811709F45FC0812F2F -:10C2500090E02DE5B22EB89EF001B99EF00D1124AC -:10C26000E356F64F458956896789708D452B462BD5 -:10C27000472B81F4418D528D638D748D452B462B58 -:10C28000472B41F4458D568D678D70A1452B462B6C -:10C29000472BC9F14DE5489F9001499F300D11246E -:10C2A000C9018356964F5C01DC0191966D917D9199 -:10C2B0008D919C9194970F94B6391B012C01F50137 -:10C2C00065A176A187A190A50F94B6399B01AC0119 -:10C2D000C201B1010F94023FD50111962D913D91FC -:10C2E0004D915C9114970F94173A2B015C01272D07 -:10C2F000302F4C81562D0F946840181624F4742C5E -:10C30000052DAC826B2C1F5F1F709CCFB401990C64 -:10C31000880B990B0F94B839562EA72EB82E192FCB -:10C320002091120230911302409114025091150293 -:10C33000672D702F8C81962D0F94173A252D3A2D4D -:10C340004B2D512F0F94083E362E472E782E092F55 -:10C350008090160290901702262F372F482F592FC2 -:10C36000652D7A2D8B2D912F0F9468401816D4F0DF -:10C37000B401990C880B990B0F94B839562EA72E3F -:10C38000B82E192F262F372F482F592F632D742D94 -:10C39000872D902F0F946840181624F0532CA42C4E -:10C3A000B72C102F209163083091640840916508E4 -:10C3B000509166082C833D834E835F83252D3A2D53 -:10C3C0004B2D512F6C817D818E819F810F94684010 -:10C3D000181604F520E037ED43EA5CE3652D7A2D6D -:10C3E0008B2D912F0F94173A4B015C0128E431EE0D -:10C3F0004AE75FE36C817D818E819F810F94173ABC -:10C400009B01AC01C501B4010F94083E562EA72E26 -:10C41000B82E192F852D9A2DAB2DB12F809363083F -:10C4200090936408A0936508B0936608652D7A2DF3 -:10C430008B2D912F0F94743FCB0168850E94DCCC2B -:10C4400034E6C30ED11CE11CF11CC0926708D092E7 -:10C450006808E0926908F0926A080E94A5918091AC -:10C460003509882309F42BC190910901892F809502 -:10C470008170109158021817D1F12091A2172064F1 -:10C480002093A2178093580290FD0FC064EF71E0D3 -:10C4900080E090E00E9421CD0E948F7E8091A217C3 -:10C4A00084FD46C1112319F102C00E94777E12302B -:10C4B00008F41EC100E00E94DE3F83E08093750215 -:10C4C0000F941E1D6C597F4F8F4F9F4F6093FB033E -:10C4D0007093FC038093FD039093FE03002339F0D7 -:10C4E000123029F481E0809398170F9413270F944A -:10C4F0001E1D6B017C01109159021123F1F08091F6 -:10C5000050098823D1F040917608509177086091C6 -:10C5100078087091790846015701841A950AA60A8D -:10C52000B70AB501A40177FD1AC0833009F4FBC036 -:10C530000CF0EAC081300CF0EFC0212F30E0A8EE03 -:10C54000B3E00F94F83DC60ED71EE81EF91EC09248 -:10C550007608D0927708E0927808F0927908809176 -:10C56000860F813009F073C00F941E1D6B017C0192 -:10C570008091720890917308A0917408B091750829 -:10C58000A7019601281B390B4A0B5B0BDA01C90185 -:10C59000B7FD3AC0D701C601805F984DAF4FBF4F7E -:10C5A0008093720890937308A0937408B0937508F1 -:10C5B0008090D5059090D605A090D705B090D8056D -:10C5C0000E94E4BAAB01BC014093D5055093D60557 -:10C5D0006093D7057093D8058091D6089091D708BD -:10C5E000A091D808B091D90888199909AA09BB095E -:10C5F000840F951FA61FB71F8093D6089093D70866 -:10C60000A093D808B093D90880916E0890916F08D4 -:10C61000A0917008B091710846015701881A990AD3 -:10C62000AA0ABB0AD501C401B7FD11C020E8C20E99 -:10C630002EEED21E26E3E21EF11CC0926E08D092AE -:10C640006F08E0927008F09271080E94BC8E0E9400 -:10C65000312B0E94446B80919908882381F10F94BB -:10C660001E1D6B017C018091950890919608A09108 -:10C670009708B091980846015701881A990AAA0AA2 -:10C68000BB0AD501C401B7FD1AC02091990830E05A -:10C69000A8EEB3E00F94F83DC60ED71EE81EF91EB3 -:10C6A000C0929508D0929608E0929708F092980868 -:10C6B000809151090E949E848AE00E949FCE289614 -:10C6C0000FB6F894DEBF0FBECDBFDF91CF911F91A3 -:10C6D0000F91FF90EF90DF90CF90BF90AF909F9021 -:10C6E0008F907F906F905F904F903F902F90089524 -:10C6F00060E085E09AE20E941D3B80914009811133 -:10C70000D9CE0E945E2DD6CE843009F016CF0E947D -:10C710000FD884EC99E204C00E940FD883EF99E20D -:10C720000E94ACCE0ACF0E940FD88CED99E2F8CFD0 -:10C73000123028F460E083E19AE20E941D3B01E0A0 -:10C74000BACE2F923F924F925F926F927F928F92CA -:10C750009F92AF92BF92CF92DF92EF92FF920F9390 -:10C760001F93CF93DF93CDB7DEB76B970FB6F894D7 -:10C77000DEBF0FBECDBF9091D40593FD47C1182FEA -:10C7800089E40E94D1C9882309F46DC10E945BC766 -:10C7900090E01816190614F481E090E026E0289F36 -:10C7A000F001299FF00D1124EE50FA4F8281938100 -:10C7B0001F828436910514F084E690E0909337064A -:10C7C000809336060E9422C60E943BC860E0882300 -:10C7D00009F40DC183EC95E30E941D3B01E0612F3C -:10C7E0006027812F0E94DEBB112309F435C1C09060 -:10C7F0003206D0903306E0903406F0903506CC8AAD -:10C80000DD8AEE8AFF8A8FE780933A0600937402EE -:10C81000412C512C3201188619861A861B86188ADB -:10C820002CE3298B3CE13A8B46E44B8B212C1C8278 -:10C8300050E85D838FEB8E83312C609136067091CA -:10C840003706072E000C880B990B0F94B8397B0123 -:10C850008C01222D3C814D815E810F94B13988235A -:10C86000B9F0209132063091330640913406509150 -:10C870003506CF80B701C801C110BCC00F94B139D3 -:10C88000382E331C3324331C2E2CFC820D831E8344 -:10C890000F941E1D4B015C01DC01CB01C884D984BF -:10C8A000EA84FB848C199D09AE09BF09B7FD11C04C -:10C8B000A501940128513C4F4F4F5F4F288739877E -:10C8C0004A875B87809151090E949E848AE00E947A -:10C8D0009FCE80E00E94EADD0F941E1D60933B0610 -:10C8E00070933C0680933D0690933E06109132066D -:10C8F00000913306D0903406C09035063110C3C085 -:10C90000622D7C818D819E810F94743F4B01612F3C -:10C91000702F8D2D9C2D0F94743F6C877D878E8793 -:10C920009F870C851D856C897D898E899F890F94D1 -:10C93000743F9B018616970609F487C06401092C91 -:10C94000000CEE08FF08C88ED98EEA8EFB8E6B01B4 -:10C95000072E000CEE08FF08061717072CF09401AD -:10C96000081519050CF49801032E000C440B550B07 -:10C970002C193D094E095F09AFEFB0E00F94E53D7A -:10C98000288D398D4A8D5B8D2C193D094E095F0923 -:10C990000F94C63D80913A06821759F020933A06CB -:10C9A00029831A82DD24DA94DB82CE0101960E946B -:10C9B000F6CA80917402882309F1332009F447C034 -:10C9C0006091360670913706072E000C880B990B84 -:10C9D0000F94B839209132063091330640913406D5 -:10C9E000509135060F94B13987FD27CF07C084EBEE -:10C9F00095E3F2CE0F94B13987FF21C08091740284 -:10CA0000882321F0109274020F948E106B960FB64B -:10CA1000F894DEBF0FBECDBFDF91CF911F910F9174 -:10CA2000FF90EF90DF90CF90BF90AF909F908F904E -:10CA30007F906F905F904F903F902F9008952E2C95 -:10CA4000FC820D831E83312C23CF2FEFA3CF0E94B6 -:10CA50003BC88111F2CED2CF8DE295EC90931812A3 -:10CA600080931712D3CF83E50E94D1C98F838111A0 -:10CA700007C0112359F282E50E94D1C9882331F2FF -:10CA80000E9457C796CE411451046104710441F0CD -:10CA9000D501C40184199509A609B709B7FD89CF45 -:10CAA000212F302F4D2D5C2D688979898A899B89AA -:10CAB0000F94073E20E030E040E85FE30F94B13987 -:10CAC00087FD9CCF2401350120E6420E2AEE521E3E -:10CAD000611C711C188B098BDA8ACB8A6ACF1F9371 -:10CAE000CF93DF93D82F162F8091D40583FD15C0E7 -:10CAF000C091510987E1C89FF0011124E15CF94F11 -:10CB0000808591850E94F7CC882339F06C2F809125 -:10CB10006002909161020E94DCCC40915109612F2A -:10CB20008BE00E94092EDD2341F061E080915109E4 -:10CB3000DF91CF911F910C9488868091A00891E09D -:10CB400089278093740217E1809174028823F9F099 -:10CB5000C09151091C9FE0011124C15CD94F20E014 -:10CB600030E040E05FE36C817D818E819F810F9496 -:10CB7000083E0F94743F28853985621B730B77FF3D -:10CB800003C07195619571096230710544F410928A -:10CB900074028091D40583FF06C081E019C080E053 -:10CBA0000E94EADDD1CFE091510987E1E89FF001D1 -:10CBB0001124E15CF94F808591850E94F7CC882390 -:10CBC00061F30E940FD88CE79AE20E94ACCE80E01D -:10CBD000DF91CF911F9108956F927F928F929F92D4 -:10CBE000AF92BF92CF92DF92EF92FF920F931F937B -:10CBF000CF93DF9300D000D01F921F92CDB7DEB746 -:10CC00005C014B013A01F22E68011091220610924C -:10CC10001E0610921F0610922006109221061092F6 -:10CC2000220680E00E949ACC00912706012B1092E8 -:10CC300023061092240610922506109226061092C2 -:10CC4000270681E00E949ACC6091510987E1689F94 -:10CC5000F0011124E15CF94F808591858C159D05CB -:10CC60001CF4C6010E94DCCCE12C2F2DA301B401E1 -:10CC7000C5010F948D121C141D0454F460915109C8 -:10CC8000C6010E94DCCC60E0809151090E94888638 -:10CC90004091510960E088E00E94092E60E081E047 -:10CCA0000E946FE580E090E0A0E7B2E489839A8378 -:10CCB000AB83BC8380E090E0A0E0B0EC8D839E83EA -:10CCC000AF83B887BE016F5F7F4FCE0105960E948C -:10CCD0004EB50F941711811168C080918202909116 -:10CCE0008302A0918402B091850240917E0250910E -:10CCF0007F02609180027091810280908308909001 -:10CD00008408A0908508B090860800917F08109153 -:10CD10008008209181083091820800938A06109340 -:10CD20008B0620938C0630938D0680928E0690920F -:10CD30008F06A0929006B09291064093920650936F -:10CD4000930660939406709395068093960690934D -:10CD50009706A0939806B093990680E090E0A8EC1F -:10CD6000B2E489839A83AB83BC83CE0101960E948F -:10CD7000E3B48091870890918808A0918908B091C8 -:10CD80008A088093920690939306A0939406B0939A -:10CD9000950680E090E0A0EAB0E489839A83AB83B3 -:10CDA000BC83CE0101960E94E3B4812C912C80E7D4 -:10CDB000A82E82E4B82E89829A82AB82BC8280E05F -:10CDC00090E0A0E0B0E48D839E83AF83B887BE017E -:10CDD0006F5F7F4FCE0105960E944EB520E030E098 -:10CDE000A90160918B0870918C0880918D089091B9 -:10CDF0008E080F94B13987FF0BC089829A82AB826B -:10CE0000BC82BE016F5F7F4F8BE898E00E944EB5F9 -:10CE100080918B0890918C08A0918D08B0918E081C -:10CE20008093820290938302A0938402B093850240 -:10CE30008093960690939706A0939806B0939906D0 -:10CE400086E996E00E9498B1809151098093000490 -:10CE50000E945E2D80919A06815080939A0680915F -:10CE6000860F823011F40E94A6BB80919A06882317 -:10CE700029F0815080939A060E9492790F948E1027 -:10CE80000E945E2D28960FB6F894DEBF0FBECDBF70 -:10CE9000DF91CF911F910F91FF90EF90DF90CF9096 -:10CEA000BF90AF909F908F907F906F9008954F921A -:10CEB0005F926F927F92AF92BF92CF92DF92EF928A -:10CEC000FF921F93CF93DF9300D000D01F921F9249 -:10CED000CDB7DEB75C01E62EF42E642F80E00E9411 -:10CEE0006FE5182F81111DC0EE2031F0809151099E -:10CEF000809300040E945E2D812F28960FB6F8942F -:10CF0000DEBF0FBECDBFDF91CF911F91FF90EF909D -:10CF1000DF90CF90BF90AF907F906F905F904F90D9 -:10CF20000895EE2031F0409151096F2D83E00E9469 -:10CF3000092E80E090E0A0E7B2E48D839E83AF836A -:10CF4000B88780E090E0A0E5B1EC89839A83AB8359 -:10CF5000BC83BE016B5F7F4FCE0101960E944EB530 -:10CF600068E873E180E090E00E9421CDC12CD12CD3 -:10CF700088ECE82E81E4F82ECD82DE82EF82F886FE -:10CF800080E090E0A8EAB1E489839A83AB83BC8314 -:10CF9000BE016B5F7F4FCE0101960E944EB540905F -:10CFA0008D0950908E0960908F0970909009C09201 -:10CFB0008D09D0928E09E0928F09F092900980E05D -:10CFC00090E0A0E2B1E48D839E83AF83B887F50142 -:10CFD00080819181A281B38189839A83AB83BC8351 -:10CFE000BE016B5F7F4FCE0101960E944EB540920D -:10CFF0008D0950928E0960928F09709290090E945B -:10D0000045CD7ACFAF92BF92CF92DF92EF92FF924F -:10D010000F931F93CF93DF9300D01F92CDB7DEB74E -:10D020007C015B01D42E890181E080939A06809176 -:10D03000A21782FF08C087FD06C08B7F8093A217CE -:10D0400082E080939A060E94FFBB80E1E6E7F2E06F -:10D05000AFE7B8E001900D928A95E1F70F941711B0 -:10D06000C82E0E947F8F20E030E0A901F701608187 -:10D070007181828193810F94B1398823A1F08091CD -:10D0800051090E940CCD81110EC080E090E0A0E714 -:10D09000B2E489839A83AB83BC83BE016F5F7F4F09 -:10D0A000C7010E944EB5C11004C0B50180E00E94C6 -:10D0B0007C2A20E030E0A901F80160817181828141 -:10D0C00093810F94B139882329F042E06D2DC80176 -:10D0D0000E9457E70E9445CD81E00F900F900F907E -:10D0E0000F90DF91CF911F910F91FF90EF90DF9004 -:10D0F000CF90BF90AF900895CF92DF92EF92FF92C2 -:10D10000CF93DF936B017C01D42FC091500983E052 -:10D110008093500981E080934F09C114D104E10448 -:10D12000F10431F00F941E1DC60ED71EE81EF91E25 -:10D1300080914F09882389F0C114D104E104F104DE -:10D1400021F48D2F0E94EADDF3CF0F941E1D6C1980 -:10D150007D098E099F0997FDF4CF10924F098091A8 -:10D16000FF0382FF07C062E370E080E090E00E946E -:10D1700021CDF5CFC0935009DF91CF91FF90EF9073 -:10D18000DF90CF9008951F93CF93DF93D82FC62FB2 -:10D190000E9466DA61E08C2F0E9425CC0F941E1D40 -:10D1A000685370458F4F9F4F60931E0670931F0604 -:10D1B0008093200690932106109222060F941E1D44 -:10D1C000685370458F4F9F4F6093230670932406DA -:10D1D00080932506909326061092270610915009F9 -:10D1E00083E08093500981E080934F0980914F093B -:10D1F000882309F46BC060E08C2F0E9425CC8091BD -:10D200002206811105C080912706882309F45AC09F -:10D210004091510960E08AE00E94092E0E940FD8D7 -:10D2200087EC9AE20E94ACCE41E060E070E0CB0176 -:10D230000E947CE810921E0610921F061092200693 -:10D24000109221061092220680E00E949ACC109241 -:10D25000230610922406109225061092260610929C -:10D26000270681E00E949ACC60E080E00E946FE592 -:10D270008D2F0E9466DA0F941E1D685370458F4FE4 -:10D280009F4F60931E0670931F0680932006909315 -:10D290002106109222060F941E1D685370458F4F71 -:10D2A0009F4F6093230670932406809325069093E6 -:10D2B00026061092270681E080934F0961E08C2FAB -:10D2C0000E9425CC81E00E94EADD90CF10935009A6 -:10D2D000DF91CF911F910895AF92BF92CF92DF92CD -:10D2E000EF92FF920F931F93CF93DF93CDB7DEB7EB -:10D2F000A0970FB6F894DEBF0FBECDBF0E9413D823 -:10D30000182F87FD30C1482F61E081E00E94092E6F -:10D31000B0905109812F012E000C990BB8161906F7 -:10D3200021F060E0812F0E947DB585E40E94D1C983 -:10D33000C12CD12CE12C90E4F92E882379F00E94A5 -:10D34000A7C96B017C0120E030E0A9010F9468407F -:10D3500087FF04C0F7FAF094F7F8F094F7FAF09426 -:10D36000F7F8F094C98EDA8EEB8EFC8E8CE0E7E550 -:10D37000F3E0DE01119601900D928A95E1F788E5C0 -:10D380000E94D1C9882339F088E50F9484126983FB -:10D390007A838B839C8389E50E94D1C9882339F0E5 -:10D3A00089E50F9484126D837E838F8398878AE545 -:10D3B0000E94D1C9882339F08AE50F9484126987C5 -:10D3C0007A878B879C8700915109E02EF12C8CE0A5 -:10D3D000089F800111240259194FF80120813181E1 -:10D3E0004281538169817A818B819C810F94083EAF -:10D3F00069837A838B839C83F801248135814681FC -:10D4000057816D817E818F8198850F94083E6D8351 -:10D410007E838F839887F8012085318542855385E7 -:10D4200069857A858B859C850F94083E69877A8704 -:10D430008B879C87F70183E0EE0FFF1F8A95E1F74A -:10D44000E752FA4FC080D180E280F38085E50E94E8 -:10D45000D1C9882321F00E94A7C96B017C0120E07B -:10D4600030E0A901C701B6010F94684087FF04C0EE -:10D47000F7FAF094F7F8F094F7FAF094F7F8F094DC -:10D48000CD8EDE8EEF8EF8A26AE070E082E40E941C -:10D49000C4CAA82E80919A0681115DC09E01235EA8 -:10D4A0003F4F41E0BE016F5F7F4FCE0149960E9422 -:10D4B00002E8882309F44FC06A2D81E00E94C3E886 -:10D4C00070E060E082E50E94C4CA8C0180E090E0D8 -:10D4D000A8E4B2E48D8B9E8BAF8BB88FE09151099D -:10D4E00088E0E89FF0011124E752FA4FC480D5800C -:10D4F000E680F7808CE40E94D1C9882321F00E9445 -:10D50000A7C96B017C0120E030E0A901C701B60189 -:10D510000F94684087FF04C0F7FAF094F7F8F0948E -:10D52000C98ADA8AEB8AFC8A80E090E0A0EAB2E459 -:10D530008D879E87AF87B88B80919A06882359F094 -:10D540002A2DAE014B5E5F4FBE016F5E7F4FCE0155 -:10D550000D960E94ECE5809151098B1521F060E059 -:10D560008B2D0E947DB5A0960FB6F894DEBF0FBE3E -:10D57000CDBFDF91CF911F910F91FF90EF90DF9082 -:10D58000CF90BF90AF900895CF92DF92EF92FF922D -:10D590000F931F93CF93DF93CDB7DEB76C970FB682 -:10D5A000F894DEBF0FBECDBF8CE40E94D1C98823A2 -:10D5B00009F4F1C00E94A7C96B017C0120E030E0B2 -:10D5C000A9010F94684087FF04C0F7FAF094F7F8B8 -:10D5D000F094F7FAF094F7F8F094C98EDA8EEB8EA7 -:10D5E000FC8E8CE0E7E5F3E0DE01119601900D92F0 -:10D5F0008A95E1F788E50E94D1C9882389F088E5FA -:10D600000F94841220916D0F30916E0F40916F0F27 -:10D610005091700F0F94073E69837A838B839C83AC -:10D6200089E50E94D1C9882389F089E50F94841285 -:10D630002091710F3091720F4091730F5091740FC0 -:10D640000F94073E6D837E838F8398878AE50E94BF -:10D65000D1C9882339F08AE50F94841269877A87C3 -:10D660008B879C87F09051098CE0F89E80011124F3 -:10D670000259194FF801208131814281538169811A -:10D680007A818B819C810F94083E69837A838B8396 -:10D690009C83F80124813581468157816D817E818B -:10D6A0008F8198850F94083E6D837E838F83988742 -:10D6B000F801208531854285538569857A858B857A -:10D6C0009C850F94083E69877A878B879C87809119 -:10D6D000A21782FB112710F982FF05C087FB1127D3 -:10D6E00010F981E018274F2D61E080E00E94092E9B -:10D6F00060E080E50E94E1CA082F1D861E861F8615 -:10D70000188A80919A06811137C09E01235F3F4F8E -:10D71000402FBE016F5F7F4FCE0149960E9402E805 -:10D72000882351F1112311F0002331F160E080E0F2 -:10D730000E94C3E8898D9A8DAB8DBC8DB0588D8BBE -:10D740009E8BAF8BB88F198A1A8A1B8A1C8A1D86FA -:10D750001E861F86188A80919A06882369F010E039 -:10D7600000E020E0AE014B5E5F4FBE016F5E7F4F79 -:10D77000CE010D960E94ECE56C960FB6F894DEBFD4 -:10D780000FBECDBFDF91CF911F910F91FF90EF9012 -:10D79000DF90CF900895C12CD12CE12C80E4F82E9D -:10D7A00018CF2F923F924F925F926F927F928F92FB -:10D7B0009F92AF92BF92CF92DF92EF92FF920F9320 -:10D7C0001F93CF93DF93CDB7DEB7CD58D1090FB6F6 -:10D7D000F894DEBF0FBECDBFC357DF4F8883CD584F -:10D7E000D040C0905009E196CFAEE19721E0209360 -:10D7F00050098091C4088D3409F4E1C4843511F4D2 -:10D800000D94CA00873409F041C10091C2081091FB -:10D81000C3080531110509F401C308F03AC1043009 -:10D82000110508F02FC1809135090230110508F467 -:10D83000EFC2833008F4F2C233243394023011056E -:10D8400009F0312C0E94DEC982E50E94D1C98823EB -:10D8500009F4FDC20E94A7C96B017C0120E030E001 -:10D86000A9010F94B139882309F405C140907602CB -:10D8700050907702609078027090790220917A023D -:10D8800030917B0240917C0250917D0228AF39AFEC -:10D890004AAF5BAF80908A0690908B06A0908C0672 -:10D8A000B0908D0680918E0690918F06A091900683 -:10D8B000B09191068CAF9DAFAEAFBFAFA501940103 -:10D8C000C301B2010F94B13981110DC02CAD3DAD32 -:10D8D0004EAD5FAD68AD79AD8AAD9BAD0F94B139FA -:10D8E000882309F4C8C0A3019201C501B4010F94B3 -:10D8F000073E20E030E040E05FE30F94173A6CAB66 -:10D900007DAB8EAB9FAB28AD39AD4AAD5BAD6CAD99 -:10D910007DAD8EAD9FAD0F94073E20E030E040E03E -:10D920005FE30F94173A68AF79AF8AAF9BAF20E0FF -:10D9300030E0A901C701B6010F94B139881F8827CB -:10D94000881F381609F47AC220E030E040E85FEB27 -:10D950002CAF3DAF4EAF5FAF2CA93DA94EA95FA93B -:10D96000CA01B9010F94173A4B015C0128AD39ADDA -:10D970004AAD5BADCA01B9010F94173A9B01AC01E6 -:10D98000C501B4010F94083E0F94B6404B015C01F1 -:10D99000AC019B01C701B6010F94073E2B013C016E -:10D9A000A5019401C701B6010F94083E9B01AC018B -:10D9B000C301B2010F94173A6B017C0120E030E003 -:10D9C000A9010F946840412C512C320187FD06C0FB -:10D9D000C701B6010F94B6402B013C0168AD79AD8B -:10D9E0008AAD9BAD9058A50194010F94023F2CADD8 -:10D9F0003DAD4EAD5FAD0F94173AA30192010F9468 -:10DA0000173A2CA93DA94EA95FA90F94083E6B01B6 -:10DA10007C01A50194016CA97DA98EA99FA90F94F1 -:10DA2000023F2CAD3DAD4EAD5FAD0F94173AA30153 -:10DA300092010F94173A28AD39AD4AAD5BAD0F9402 -:10DA4000083E6CAB7DAB8EAB9FAB20E030E0A90114 -:10DA5000C701B6010F94B13981110D941F0120E067 -:10DA600030E0A9016CA97DA98EA99FA90F94B139B5 -:10DA700081110D941F010E940BD88FE99FE20E9433 -:10DA8000ACCECCC10430110509F431C30F94761229 -:10DA9000C5C10A35110509F481C308F048C10B312D -:10DAA000110509F45EC30C31110581F70F941711AC -:10DAB000811111C08091BC089091BD08A091BE0851 -:10DAC000B091BF08FEE0B695A79597958795FA9512 -:10DAD000D1F780FDA3C10E947F8F109238020F946E -:10DAE0001E1D60933B0670933C0680933D06909309 -:10DAF0003E06D090510961E080E00E947DB58091A2 -:10DB0000510290915202A0915302B091540280931D -:10DB1000910890939208A0939308B09394088091F1 -:10DB20002002909121029093900880938F0884E6C0 -:10DB300090E0909321028093200281E08093E3089B -:10DB40000E9471B98091BC089091BD08A091BE0857 -:10DB5000B091BF08A7FBFF24F0F80B2F0170B1FBB9 -:10DB6000882780F9F01203C08F1509F412C3182F0B -:10DB700082E50E94D1C9882311F40D94EB000E9424 -:10DB8000A7C93B014C0120E030E0A9010F94B13955 -:10DB90008823D9F1A0907E02B0907F02C0908002CD -:10DBA000E090810295014C2D5E2DB301C4010F94CC -:10DBB000B13987FD03C05301C82CE92C80E090E007 -:10DBC000A0E8B0E48C8F9D8FAE8FBF8F20E030E057 -:10DBD00046E153E4B5018C2D9E2D0F94B13987FD9C -:10DBE00006C0A12CB12C56E1C52E63E4E62EC5017A -:10DBF000AC2DBE2D89839A83AB83BC83BE01645E4A -:10DC00007F4FCE0101960E94C4B4FF2009F45DC08D -:10DC1000002309F457C010927602109277021092F6 -:10DC200078021092790210927A0210927B0210927E -:10DC30007C0210927D020E947BB58EED9BE6ADE8E2 -:10DC4000B2E488A799A7AAA7BBA7EBEEF4E1659178 -:10DC500075918591949120E030E040EC5FE30F9462 -:10DC6000173A905869837A838B839C83E7EEF4E1BB -:10DC7000659175918591949120E030E040EC5FE3EF -:10DC80000F94173A6C8F7D8F8E8F9F8FAE01485DFA -:10DC90005F4FBE016F5F7F4FCE014C960E94A2B4D2 -:10DCA0000E94D6BA109276021092770210927802F1 -:10DCB0001092790210927A0210927B0210927C02EA -:10DCC00010927D0280E00E9459B7002319F081E094 -:10DCD0000E9459B7112319F082E00E9459B70E949F -:10DCE0007BB58091E2088093E30880919108909140 -:10DCF0009208A0919308B091940880935102909358 -:10DD00005202A0935302B093540280918F089091D5 -:10DD10009008909321028093200261E08D2D0E9453 -:10DD20007DB583E0809375020E94BBB877C00B3548 -:10DD3000110509F436C20C35110509F0A7CE4CE9DE -:10DD4000C42E42E0D42EF12CE12C00E010E0D601EC -:10DD50008D916D010E94D1C9382E882309F448C0E5 -:10DD60000E94A7C94B015C01133059F0F701E35938 -:10DD7000F04F20813181428153810F94073E4B0146 -:10DD80005C01F701EA58FD4F2081318142815381C6 -:10DD9000C501B4010F94073E2B013C012DEB37E385 -:10DDA00046E855EB0F94684087FD0AC02DEB37E33A -:10DDB00046E855E3C301B2010F94B1391816C4F413 -:10DDC000133009F4F2C1F701E655FA4F5F01A301E0 -:10DDD000920160817181828193810F94083ED50107 -:10DDE0006D937D938D939C931397812F0E94FAB22C -:10DDF0001F5FB4E0EB0EF11C143009F0A8CF002334 -:10DE000021F082E892E00E9498B10E94BBB806C05F -:10DE1000833020F00E94DEC90E94C2B3C357DF4F97 -:10DE2000C880CD58D040C11002C00E9491CFE19669 -:10DE3000DFACE197D09250090C944AF780E090E073 -:10DE4000A0E8BFE38CAF9DAFAEAFBFAF85CD89E497 -:10DE50000E94D1C9C12CD12C7601882321F00E94C7 -:10DE6000A7C96B017C018AE40E94D1C9882311F4FF -:10DE70000D9410010E94A7C9E4CD28962CAD3DADAC -:10DE80004EAD5FAD289768AD79AD8AAD9BAD0F946F -:10DE9000173A6B017C012C962CAD3DAD4EAD5FADBC -:10DEA0002C976CAD7DAD8EAD9FAD0F94173A9B0155 -:10DEB000AC01C701B6010F94083E6B017C012C96A2 -:10DEC0002CAD3DAD4EAD5FAD2C9768AD79AD8AAD53 -:10DED0009BAD0F94173A4B015C0128962CAD3DADDC -:10DEE0004EAD5FAD28976CAD7DAD8EAD9FAD0F94FF -:10DEF000173A9B01AC01C501B4010F94073EA7017D -:10DF000096010F94873E6B017C0120E030E0A9016F -:10DF10000F94B139882311F40D94B60520E030E058 -:10DF2000A901C701B6010F94B13987FF2CC082E067 -:10DF300090E083298130910549F1029791F120E029 -:10DF400030E0A901C701B6010F94684026013701EE -:10DF500087FF04C077FA709477F870942BED3FE058 -:10DF600049EC50E4C301B2010F94023F20E030E0DD -:10DF700040E952E40F94173A0F94E63E0F947B3F2A -:10DF80008B010D94040290E080E0D3CF2BED3FE0B5 -:10DF900049EC50E4C701B6010F94073E6B017C01C8 -:10DFA000CECF2BED3FE049EC50E4C701B6010F9412 -:10DFB000083EF4CF08E410E0BBED4B2EBFE05B2E33 -:10DFC000B9EC6B2EB0E47B2E730162010D94040258 -:10DFD0002DEC3CEC4CEC5DE3C201B1010F94B13986 -:10DFE00087FF28C02DEC3CEC4CEC5DE321966FAD37 -:10DFF000219725967FAD259729968FAD2997659610 -:10E000009FAD65970F94023F0F94AA3F2B013C01EF -:10E0100020E030E040E85FE30F94B13987FF06C0AD -:10E02000412C512CA0E86A2EAFE37A2EC301B20135 -:10E030000D94D102B301C8010D94D1026796CEAC04 -:10E04000DFAC6797B60190E080E00F94B6396F9629 -:10E050002CAD3DAD4EAD5FAD6F970F94173A4B01B0 -:10E060005C010F94FD3E6B017C01C501B4010F946E -:10E07000A8404B015C01A701960168AD79AD8AAD5E -:10E080009BAD0F94173A2B013C01A50194016CA99B -:10E090007DA98EA99FA90F94173A9B01AC01C301DA -:10E0A000B2010F94083E2B013C01A501940168AD1B -:10E0B00079AD8AAD9BAD0F94173A4B015C01A70176 -:10E0C00096016CA97DA98EA99FA90F94173A9B016F -:10E0D000AC01C501B4010F94073E6CAF7DAF8EAFAC -:10E0E0009FAF29E1A0962FAFA0970D94BA0480E5C9 -:10E0F0000E94D1C9C12CD12C7601882321F00E9425 -:10E1000037C76B017C0183E50E94D1C9882361F088 -:10E110000E94A7C920E030E04AE754E40F94173A80 -:10E120000F947B3F6B017C010E947F8F80911912BD -:10E13000811105C060E085EB9FE20E941D3B0F94BA -:10E140001E1DC60ED71EE81EF91E0F941E1D6C194B -:10E150007D098E099F0997FF61CE80E00E94EADD6C -:10E16000F4CF0F943211811159CE8CE0E3E6F3E045 -:10E17000DE01119601900D928A95E1F770E060E062 -:10E1800080E50E94D3CABE016F5F7F4F0E947C2A48 -:10E1900045CEFF24F39401E011E0EACC1092A108EF -:10E1A0003DCE8FE08093A10839CE8092820290927A -:10E1B0008302A0928402B0928502032D19CE809131 -:10E1C000C2089091C3088837910511F40C9480F926 -:10E1D00008F097C18E34910509F4B5C508F0FDC06B -:10E1E0008931910509F4ABC408F094C084319105DC -:10E1F00009F44DC408F05EC08131910509F4F7C3FC -:10E2000098F5029708F042CC80E50E94D1C9C12C54 -:10E21000D12C7601882321F00E9437C76B017C0145 -:10E2200083E50E94D1C9882361F00E94A7C920E03C -:10E2300030E04AE754E40F94173A0F947B3F6B01A8 -:10E240007C010E947F8F8091C0089091C108009747 -:10E2500009F4C7C30F94450E40E0C701B6010E9400 -:10E260007CE80F948E10DACD429709F00FCC83E54D -:10E270000E94D1C9882309F401C70F941E1D609321 -:10E280003B0670933C0680933D0690933E060E94A9 -:10E29000A7C920E030E04AE754E40F94173A0F94FE -:10E2A0007B3F60935A0270935B0280935C02909371 -:10E2B0005D02B4CD8631910509F41BC408F416C47F -:10E2C0008731910509F41EC4489709F0DFCB80918E -:10E2D0009A06882309F428C480E090E0A8E4B2E418 -:10E2E00088A799A7AAA7BBA71C8E1D8E1E8E1F8E5E -:10E2F00019821A821B821C8210E000E020E0AE012D -:10E30000485D5F4FBE01645E7F4FCE0101960E9463 -:10E31000ECE584CD8E31910509F490C498F48B31ED -:10E32000910509F42AC408F40DC48C31910509F44F -:10E330007EC44D9709F0AACB8091A2178E7F80935F -:10E34000A2176CCD8B34910509F4F7C4D0F58F3149 -:10E35000910509F4D7C4809709F098CB8091A21752 -:10E3600082FF03C087FF0E947F8F8091A21784FFE6 -:10E3700055CD60E080E50E94E1CA182F682F80919A -:10E38000C0089091C1080E945EBE83E50E94D1C979 -:10E39000882381F00E9447C7AB01BC0140939E17C0 -:10E3A00050939F176093A0177093A11780E594E195 -:10E3B0000E94827C0E949279111130CD0E94A6BBEE -:10E3C0002DCD8C34910509F4BBC48D34910509F031 -:10E3D0005DCB81E00E9416BB21CD8C36910509F4FE -:10E3E00016C608F059C08535910509F485C638F57B -:10E3F0008235910509F432C6C8F48135910509F0DA -:10E4000045CB0E9447B70E9497CD0E94B48581E01A -:10E410000E9416BB68EE73E080E090E00E9421CD80 -:10E4200060E089E091E30E941D3BF8CC83359105C3 -:10E4300009F41CC68435910509F419CF27CB893618 -:10E44000910509F413C560F48C35910509F479C67A -:10E450008836910509F01ACB80E00E9439D8DECCCD -:10E460008A36910509F430C58B36910509F00ECB3B -:10E470001091510980E50E94D1C9811172C5812F87 -:10E4800090E01816190614F481E090E0E82FF0E00F -:10E49000EE52FA4F1082C2CC8137910509F4BDC506 -:10E4A000A8F48E36910509F463C508F4DAC48F36F2 -:10E4B000910509F470C58037910509F0E7CA41E07C -:10E4C00070E060E084EF90E30E94E2DC8537910524 -:10E4D00009F4CBC658F48237910509F4BEC68337D8 -:10E4E000910509F0D3CA0E94D3CE98CC8637910506 -:10E4F00009F4CBC68737910509F0C8CA0E9456B9FE -:10E500008DCC8D32E1E09E0711F40C94C9FC08F02B -:10E51000F4C08B3C910511F40C94E5FA08F064C04A -:10E520008139910509F4FCC698F48A37910511F4F4 -:10E530000C94DCFF08F4ECC68D37910509F4FFC29A -:10E540008C38910509F0A2CA80E00E94A1E366CC54 -:10E550008E3B910509F47DC568F58639910509F46E -:10E5600058C78B39910509F091CA83E50E94D1C93A -:10E57000882309F453CC0E945BC7182F8C3308F012 -:10E580008CE3809399080F941E1D6B017C01212F51 -:10E5900030E0A8EEB3E00F94F83DC60ED71EE81E9B -:10E5A000F91EC0929508D0929608E0929708F092D2 -:10E5B000980834CC883C910509F465C7893C9105DD -:10E5C00009F064CA8091BC0884FDD4C78091BE085C -:10E5D000887809F0CFC78091BF08837009F0CAC757 -:10E5E00081E00E943AD61ACC893D910511F40C9431 -:10E5F0000EFCA0F48D3C910511F40C946EFB10F40C -:10E600000C9419FB8E3C910511F40C94DBFB833DBB -:10E61000910509F03BCA0E94B5CF00CC8D3D910514 -:10E6200011F40C9471FC08F04AC08A3D910511F474 -:10E630000C9422FC8C3D910509F028CA82E40E94CA -:10E64000D4C5882341F080912002909121029093BB -:10E650005F0280935E0282E50E94D4C5882341F068 -:10E6600080915E0290915F0290932102809320023C -:10E6700083E50E94D1C9882331F00E9457C7909347 -:10E680002102809320028091BC089091BD08A09146 -:10E69000BE08B091BF08892B8A2B8B2B09F0BECB0B -:10E6A000609120027091210286E691E30E9487DA50 -:10E6B00085E20E949FCE8AE00E949FCEAFCB8A3F28 -:10E6C000910511F40C9427FD8C32914009F0DEC9BC -:10E6D00064E071E083E50E94D3CA8C0168EE73E0C8 -:10E6E00080E50E94D3CA8938B3E19B0710F088E81F -:10E6F00093E1B8010E948D2B91CB8C3032E09307CF -:10E7000011F40C9448FE08F04CC08C3A51E0950787 -:10E7100011F40C947AFDB0F48F32B1E09B0711F440 -:10E720000C9472FD10F40C942CFD8039F1E09F07DD -:10E7300011F40C9476FD8A39914009F0A7C90E9422 -:10E7400039B86CCB863F31E0930711F40C943AFE54 -:10E7500068F4843F51E0950711F40C9436FE853F30 -:10E76000914009F093C90E940FC558CB873FB1E093 -:10E770009B0711F40C943EFE883F914009F086C936 -:10E7800081E0809302060E9403C51092020688234E -:10E7900009F444CB0E940FD88FEE91E30E94ACCED7 -:10E7A0003DCB8E3BF2E09F0711F40C9405FF08F07F -:10E7B000F8C0883532E0930711F40C945EFE38F40B -:10E7C0008933924009F062C90E940EDB27CB8B355A -:10E7D000A2E09A0711F40C9462FE8D3B924009F07E -:10E7E00055C90E9413D8082F87FD18CB8AE50E94CF -:10E7F000D1C9882311F40C94EFFE8AE50F9484129A -:10E80000762E872E982EC92E402F63E085E00E9439 -:10E81000092E10915109A02E002E000CBB081A15CC -:10E820001B0421F060E0802F0E947DB520917E02C4 -:10E8300030917F02409180025091810260E070E04F -:10E8400086E193E40F94073ED62EE72EF82E092F8B -:10E85000272D382D492D5C2D0F94684018161CF477 -:10E86000D72C74010C2D8D2D9E2DAF2DB02F88AB84 -:10E8700099ABAAABBBAB20E030E0A9016D2D7E2D9A -:10E880008F2D902F0F94B139882321F0CE01C0969F -:10E890000F94862780E090E0A8E4B2E48CA79DA7BF -:10E8A000AEA7BFA780E090E0A0EAB2E488A799A74E -:10E8B000AAA7BBA78CE40E94D1C9882311F40C94A9 -:10E8C000F7FE0E94A7C96B017C0120E030E0A9019E -:10E8D000C701B6010F94684087FF04C0F7FAF094AF -:10E8E000F7F8F094CC8EDD8EEE8EFF8E87E18A9D58 -:10E8F000F0018B9DF00D1124E15CF94FE084F1846F -:10E9000034E0E316F104BCF020E030E040E05FE3E7 -:10E9100064817581868197810F94083E0F94743FBE -:10E920006E197F0977FF03C071956195710901E048 -:10E93000643071050CF400E053E0E52E2AE0AE01EE -:10E94000445D5F4FBE01645E7F4FCE0188960F9499 -:10E950008D1268A979A98AA99BA96B017C01F7FA94 -:10E96000F094F7F8F094C982DA82EB82FC8220E01E -:10E9700030E0A9010F94B139882321F0CE0101962E -:10E980000F94862780915109181721F060E0812F9C -:10E990000E947DB580915109809300040E945E2DF4 -:10E9A0003DCA803AE3E09E0709F49FC168F48A38C3 -:10E9B00023E0920711F40D942B008739934009F05E -:10E9C00065C80E94AED62ACA873E43E0940711F478 -:10E9D0000D94BA00893E934009F058C80F9434064C -:10E9E0001DCA60E08EEB9FE20E941D3B35CC0E9469 -:10E9F000C3C58823B9F185E40E94D4C5882361F09A -:10EA000080919E0890919F08892B39F10E9457C7E9 -:10EA1000823010F40E94048A3CE9E32E32E0F32EA7 -:10EA200010E0D7012D917D0121548091BC08909177 -:10EA3000BD08A091BE08B091BF0804C0B695A795C7 -:10EA4000979587952A95D2F780FF03C0812F0E9462 -:10EA5000138A1F5F133029F7E1C980E00E94D8872D -:10EA600081E0D8CF60E081ED9FE20E941D3B80E015 -:10EA70000E94138A81E00E94138A82E00E94138A16 -:10EA800080E00E94D88781E00E94048AC7C98091F3 -:10EA9000A21784FF24C089EE9FE20E94ACCE809131 -:10EAA000A21784FF17C084EA94E10E945F808BE183 -:10EAB000E4EAF4E1DE01119601900D928A95E1F706 -:10EAC00070E060E0CE0101960E94D6BFCE010196B3 -:10EAD0000E9464808AED9FE20E94ACCE9FC90E9492 -:10EAE0000FD88AEF9FE20E94ACCE98C90E948F7E19 -:10EAF00095C98091A21782FF02C087FF8FC90E942B -:10EB0000777E8CC98091C0089091C108FC01219149 -:10EB1000222331F02032D9F7DF0111971C92F7CF71 -:10EB200060E00E945EBE7AC90E9473CD882321F006 -:10EB30000E9492790E94A6BB0F948E106FC90E940A -:10EB4000C4EA6CC98091A21784FF68C983E50E945A -:10EB5000D1C9882309F462C90E9447C7AB01BC012F -:10EB600040939E1750939F176093A0177093A1171F -:10EB700080E594E10E94827C51C98091BC0890910B -:10EB8000BD08A091BE08B091BF0822E0B695A79538 -:10EB9000979587952A95D1F780FF1CC08EE090E36A -:10EBA0000E94ACCE80915314882379F0BE016F5F30 -:10EBB0007F4F80E594E10E94F77ECE0101960F948D -:10EBC000D6268AE00E949FCE29C984E090E30E9465 -:10EBD000ACCEF7CF8091A21782FF24C0C0909E17C1 -:10EBE000D0909F17E090A017F090A1178DE190E3CF -:10EBF0000E94ACCEC701B6010F94C00D8FE20E94F7 -:10EC00009FCE60919A1770919B1780919C1790915D -:10EC10009D170F94C00D8DE00E949FCE8AE00E9448 -:10EC20009FCEFCC88FE290E30E94ACCEF7C88091E3 -:10EC3000C0089091C1080E948CBFF0C88091A217B3 -:10EC400084FFECC80F945F128091A21784FFE6C87E -:10EC50004091C0085091C108BE01645E7F4F80E0C2 -:10EC60000F94BD0C8C01009709F4D8C86C8D7D8D74 -:10EC700019821C8222E0AC01CE0101960E946A80BA -:10EC8000811115C0F12CCE0101960E946480B8015B -:10EC9000FF2011F18BE590E30F94E22610929E176E -:10ECA00010929F171092A0171092A117B7C8CE010B -:10ECB00001960F94290C882329F361E0CE01019677 -:10ECC0000E940F7E0097F1F225EEFC0120831C824A -:10ECD0000E94287AF82ED7CF83E490E30E94E0DDEB -:10ECE00080E490E30E94ACCE99C82091C008309196 -:10ECF000C1089091A21792609093A217C9010E9437 -:10ED00008CBF8CC80E94E4BA6C8F7D8F8E8F9F8FD2 -:10ED1000BE016F5F7F4FCE014C960E9458C6CE0158 -:10ED200001960F94450E0E940FD8BE016F5F7F4F72 -:10ED300089E690E30F94E22671C80E94A6BB6EC8D4 -:10ED40000E94FFBB6BC870E060E083E50E94C4CA0C -:10ED50008E34910529F40E94DE8E0F948E105EC8C9 -:10ED600084ED90E30E94ACCE6091D2087091D308FC -:10ED70008BEC90E30E947BDA6091D4087091D50807 -:10ED80008EEB90E30E947BDA6091D2087091D308F9 -:10ED90008091D4089091D508681B790B8091860FDB -:10EDA000815021E030E0823010F030E020E0621B42 -:10EDB000730B83EB90E30E9404DB8BEA90E30E94E9 -:10EDC000ACCE8091D6089091D708A091D808B09188 -:10EDD000D9088C8F9D8FAE8FBF8FBE016F5F7F4F25 -:10EDE000CE014C960E9458C6BE016F5F7F4F8EE9E0 -:10EDF00090E30E94E0DD8091DA089091DB08A09119 -:10EE0000DC08B091DD088C8F9D8FAE8FBF8FBE0167 -:10EE10006F5F7F4FCE014C960E9458C6BE016F5F58 -:10EE20007F4F8EE890E30E94E0DD20E030E04AE78B -:10EE300054E46091DE087091DF088091E0089091C1 -:10EE4000E1080F94023FAB01BC0186E790E30E940A -:10EE5000A4CF8DE60E949FCE8AE00E949FCE0C94A4 -:10EE60000EEF81E00E9439D80C940EEF0E9413D867 -:10EE7000182F87FD0AC08CED90E30E94ACCE812F45 -:10EE80000E949E848AE00E949FCEE196CFACE197DB -:10EE9000C0925009C357DF4F0FB6F894DEBF0FBEC4 -:10EEA000CDBFDF91CF911F910F91FF90EF90DF9039 -:10EEB000CF90BF90AF909F908F907F906F905F901A -:10EEC0004F903F902F9008951091510980E50E9436 -:10EED000D1C981113EC0812F90E01816190614F493 -:10EEE00081E090E0182F8091BC08EE24EA94F12C88 -:10EEF00080FF08C0E0915109F0E0EE52FA4F6081C6 -:10EF0000E62EF12C89E40E94D1C9882311F40D94D6 -:10EF1000F9000E945BC790E01816190614F481E00E -:10EF200090E026E0289FF001299FF00D1124EE507B -:10EF3000FA4FE480F580E12FF0E0EE52FA4FB7018E -:10EF40006F3F710519F010F06FEF70E060830C9463 -:10EF50000EEF0E945BC7182F823010F00C940EEF5A -:10EF6000C2CF0E945BC7823010F00C940EEF8ECAA5 -:10EF70008EE40E94D1C9882311F40C940EEF0E94F4 -:10EF800047C760930E1070930F10809310109093EA -:10EF900011100C940EEF83E50E94D1C9882321F053 -:10EFA0000E945BC78093D4050E940FD88DEE90E33A -:10EFB0000E94ACCE8091D405882331F110E000E0AE -:10EFC00020E08091D40590E0002E02C095958795B1 -:10EFD0000A94E2F780FF12C0FF24F394F20E22237A -:10EFE00019F08CE20E949FCEF801EE0FFF1FED5149 -:10EFF000FF4C859194910E94ACCE2F2D0F5F1F4F37 -:10F0000005301105F1F6DDCD8FED90E3E0CD1092E6 -:10F010004F09109274020C940EEF83E50E94D1C93F -:10F02000882369F00E945BC78D3320F480935902D6 -:10F030000C940EEF8CE3809359020C940EEF0E9417 -:10F040000FD86091590282E091E30E947FD60C9420 -:10F050000EEF81E00E94A1E30C940EEF8091A108D5 -:10F060008F7D80618093A1080C940EEF8091A108A0 -:10F070008F7E80628093A1080C940EEF0E94C3C51E -:10F080008823B1F10E947F8F85E40E94D4C5882334 -:10F0900051F080919E0890919F08892B31F10E9438 -:10F0A00057C70E94E489BCE9EB2EB2E0FB2E10E0CA -:10F0B000D7012D917D0121548091BC089091BD080C -:10F0C000A091BE08B091BF0804C0B695A7959795CA -:10F0D00087952A95D2F780FF03C0812F0E9400B741 -:10F0E0001F5F133029F70C940EEF0E94FE89DBCFCF -:10F0F0000E9447B70C940EEF83E50E94D4C5882385 -:10F1000011F40C940EEF0F941E1D60933B06709348 -:10F110003C0680933D0690933E060E94A7C920E0DE -:10F1200030E04AE754E40F94173A0F947B3F609322 -:10F130009A0870939B0880939C0890939D080C9468 -:10F140000EEF0E9413D887FF02C00C940EEF80913F -:10F15000BC0884FD09C08091BE0887FD05C0809170 -:10F16000BF08837009F474C0FCE9CF2EF2E0DF2EF3 -:10F17000A5E5EA2EA9E0FA2E10E0F60181916F01D3 -:10F180000E94D1C9882359F0133099F00E94A7C971 -:10F19000D70154966D937D938D939C9357971F5FE2 -:10F1A000B4E0EB0EF11C143041F70E945B8F0C941D -:10F1B0000EEF0E94A7C94B015C0120E030E040EA5D -:10F1C00051E40F94B13987FF3AC0A50194016091D1 -:10F1D00075097091760980917709909178090F945B -:10F1E000023F2B013C01AC019B01609185097091AC -:10F1F000860980918709909188090F94173A609346 -:10F200008509709386098093870990938809609196 -:10F21000CA057091CB058091CC059091CD050F94D6 -:10F22000B639A30192010F94173A0F947B3F609374 -:10F23000CA057093CB058093CC059093CD05809241 -:10F24000750990927609A0927709B0927809A7CFB4 -:10F2500081E00F9432120C940EEF0F94B2108FE1F4 -:10F2600096E10E94E6870C940EEF8091C008909181 -:10F27000C108009709F460CCFC012081222309F425 -:10F280005BCC0F94450E0C940EEF0091C0081091CA -:10F29000C10894E0F12C40E0915009F1D8018C9123 -:10F2A000282F2B7F2134A1F411962C912133B9F40E -:10F2B000813419F1853409F441E098012E5F3F4F04 -:10F2C00089012F5F3F4FD8018C918032C9F3E4CF81 -:10F2D000803529F4F801818180538A3070F341111F -:10F2E0000E940FD8FF2021F082E291E30E94ACCE71 -:10F2F000C8010E9425C50C940EEFFF24F394DDCFC6 -:10F300002093E3082093E2080E9471B90C940EEF59 -:10F310001092E3081092E2080E9471B90C940EEF6B -:10F3200070E060E083E50E94C4CA823040F00E9431 -:10F330000BD885E291E30E94ACCE0C940EEF8C01C9 -:10F34000112788E40E94D1C98823C1F00E9457C7C1 -:10F350008A3A91050CF44BC00E9457C7863F91052D -:10F360000CF048C00E9457C726E0209FF001219F63 -:10F37000F00D1124EE50FA4F9183808382E40E94B5 -:10F38000D1C98823A9F00E9457C70597B4F10E94FC -:10F3900057C785369105A4F50E9457C726E0209FE0 -:10F3A000F001219FF00D1124EE50FA4F93838283D8 -:10F3B00086E40E94D1C9882311F40C940EEF0E94B8 -:10F3C00057C797FD20C00E9457C78F3F910509F08E -:10F3D000ECF40E9457C726E0209FF001219FF00D1A -:10F3E0001124EE50FA4F958384830C940EEF8AEA31 -:10F3F00090E0BACF85EF90E0B7CF85E090E0CECF38 -:10F4000084E690E0CBCF90E080E0E5CF8FEF90E016 -:10F41000E2CF82E40E94D4C510E0882351F08091AD -:10F420009E0890919F081FEF892B19F00E945BC7DF -:10F43000182F85E50E94D4C500E0882351F0809103 -:10F440009E0890919F080FEF892B19F00E945BC7CF -:10F45000082F82E50E94D4C5882389F080919E08F8 -:10F4600090919F08892B69F00E945BC789830A836A -:10F470001B83CE0101960E94F6CA0C940EEF80E029 -:10F48000F5CF8FEFF3CF8091BC0883FD09C0809149 -:10F49000BE088C7029F481E00E9415DA0C940EEFFE -:10F4A0000E9413D8182F87FF02C00C940EEFF09023 -:10F4B000F10584E40E94D1C9082F882309F456C0BD -:10F4C0000E94A7C96B017C0120E030E0A9010F94E4 -:10F4D000B139882309F44CC0B4E01B02F0011124B7 -:10F4E000E751FA4FC082D182E282F38220E030E01D -:10F4F000A9016091E9057091EA058091EB05909171 -:10F50000EC050F94B13981110CC080E090E0A0EEC1 -:10F51000BFE38093E9059093EA05A093EB05B093D0 -:10F52000EC0520E030E0A9016091ED057091EE0559 -:10F530008091EF059091F0050F94B13981110CC0C5 -:10F5400080E090E0A0EEBFE38093ED059093EE05A0 -:10F55000A093EF05B093F005602F83E50E94E1CA08 -:10F560008093F1050E94E7710C940EEF0F2DF4CFFC -:10F5700080E0F6CF0E9413D887FF02C00C940EEFF4 -:10F580000CE912E075E5E72E79E0F72EE0EACE2EE1 -:10F59000E2E0DE2EF80181918F010E94D1C988231B -:10F5A00061F00E94A7C90F947B3FD7016D937D93B3 -:10F5B0008D939C9313970E940D8FB4E0EB0EF11C7A -:10F5C000C016D10639F70C940EEF8091BC0884FD6B -:10F5D0000DC08091BE08887849F48091BF0883707F -:10F5E00029F481E00E9410D60C940EEF0E9413D8EB -:10F5F00087FF02C00C940EEF6CE9E62E62E0F62E57 -:10F6000010E000E0F70181917F010E94D1C98823B9 -:10F6100049F00E94A7C9F801EB5AF64F64A375A3FD -:10F6200086A397A30C5F1F4F0031110559F70C9467 -:10F630000EEF8091BD0887FD09C08091BE088E70D5 -:10F6400029F481E00E94EED50C940EEF83E50E9430 -:10F65000D1C9882391F00E94A7C96093890970934A -:10F660008A0980938B0990938C0960939109709318 -:10F670009209809393099093940980E50E94D1C9DF -:10F68000882351F00E94A7C96093890970938A0961 -:10F6900080938B0990938C0982E50E94D1C98823BD -:10F6A00051F00E94A7C960938D0970938E098093D1 -:10F6B0008F099093900984E50E94D1C9882311F4A1 -:10F6C0000C940EEF0E94A7C9609391097093920960 -:10F6D00080939309909394090C940EEF8091BC0849 -:10F6E00081FD0DC08091BD0881FD09C08091BE08DB -:10F6F0008C7029F481E00E94B6D50C940EEF82E460 -:10F700000E94D1C9882351F00E9437C760936509D0 -:10F7100070936609809367099093680983E50E9456 -:10F72000D1C9882351F00E94A7C9609395097093AD -:10F730009609809397099093980984E50E94D1C90E -:10F74000882351F00E94A7C96093990970939A0980 -:10F7500080939B0990939C098AE40E94D1C98823D5 -:10F7600011F40C940EEF0E94A7C96B017C012AE0F2 -:10F7700037ED43E25CE30F94684087FD14C02AE94B -:10F7800039E949E95EE3C701B6010F94B1391816AA -:10F7900054F0C092FE05D092FF05E0920006F09270 -:10F7A00001060C940EEF0E940BD887E491E30E94AF -:10F7B000ACCE0C940EEF8091BC089091BD08A09146 -:10F7C000BE08B091BF084CE9C42E42E0D42E56EEDC -:10F7D000E52E58E0F52E10E0892B8A2B8B2B29F48F -:10F7E00081E00E9494D50C940EEFD6018D916D01AD -:10F7F0000E94D1C9882351F00E94A7C9F7016083F4 -:10F80000718382839383812F0E94FAB21F5FF4E099 -:10F81000EF0EF11C133049F70C9405EF8AE50E94B6 -:10F82000D1C9882351F00E94A7C9609386067093BE -:10F830008706809388069093890681E00E948ED681 -:10F840000C940EEF8091BC089091BD08A091BE0869 -:10F85000B091BF08892B8A2B8B2B29F481E00E9461 -:10F86000E4D90C940EEF0E9413D8182F87FF02C022 -:10F870000C940EEF88E50E94D1C9882361F00E94A4 -:10F88000A7C92CE01202F0011124E259F94F60835C -:10F8900071838283938389E50E94D1C9882361F0B3 -:10F8A0000E94A7C93CE01302F0011124E259F94F6C -:10F8B00064837583868397838AE50E94D1C98823F0 -:10F8C00011F40C940EEF0E94A7C94CE01402F00151 -:10F8D0001124E259F94F60877187828793870C94CE -:10F8E0000EEF0E9413D8082F87FF02C00C940EEF72 -:10F8F00083E50E94D1C9002E000C110B7801EE0C9B -:10F90000FF1C882361F10E9457C7F701EE5DFD4F90 -:10F9100091838083000F111F000F111FD801AA5D72 -:10F92000BD4F7D01BC01990F880B990B0F94B8391D -:10F930002AE037ED43E25CE30F94173A0A541A4F7A -:10F94000F80120813181428153810F94173AD70108 -:10F950006D937D938D939C9313970C940EEF0E945F -:10F960000FD885E40E949FCE80E3800F0E949FCE37 -:10F97000F701EE5DFD4F608171818AE691E30E949F -:10F9800087DA85E20E949FCE8AE00E949FCE0C9487 -:10F990000EEF85E40E94D1C9882381F00E945BC7E5 -:10F9A0009091BC0893FD0CC09091BD08917841F4F2 -:10F9B000682F81E00E9493D90C940EEF8FEFF0CF67 -:10F9C0008230ECF580E50E94D1C9882351F00E9475 -:10F9D000A7C960934A0670934B0680934C06909398 -:10F9E0004D0689E40E94D1C9882381F00E94A7C9ED -:10F9F0002CEA35EC47E25EE30F94173A60934E062B -:10FA000070934F06809350069093510684E40E94B1 -:10FA1000D1C9882311F40C940EEF0E94A7C92CEAD7 -:10FA200035EC47E25EE30F94023F60935206709319 -:10FA3000530680935406909355060C940EEF0E9443 -:10FA40000BD882E791E30E94ACCE0C940EEF81E0DC -:10FA50000E9484D60C940EEF83E50E94D4C5182F23 -:10FA6000882369F00E9457C79C019093610280939C -:10FA7000600291E0232B09F090E09093A00880E5CC -:10FA80000E94D4C5882361F0209160023091610208 -:10FA9000232B11F00E946FC78093A0080C940EEFE7 -:10FAA00011110C940EEF0E940FD880EA91E30E948E -:10FAB000ACCE8091A008882391F088E891E30E9461 -:10FAC000ACCE60916002709161028FE891E30E9478 -:10FAD00087DA8BE891E30E94ACCE0C940EEF84E8B9 -:10FAE00091E3EDCF0E94CFD00C940EEF0E947F8F58 -:10FAF0000C940EEF0F94321181110C940EEFB6EBB3 -:10FB0000CB2EB4E1DB2EE6E7F2E0FDABECAB9E01E1 -:10FB10002F5F3F4F19018901F12CE12CF60165910E -:10FB2000759185919491ACA9BDA98D909D90AD9052 -:10FB3000BD90BDABACABA50194010F94073E2B016A -:10FB40003C01F801408251826282738220E030E001 -:10FB500040EA51EC0F94684087FD0AC020E030E095 -:10FB600040EA51E4C301B2010F94B139181684F48C -:10FB7000F701E253F44CE4911E1654F4B7FAB09432 -:10FB8000B7F8B094D8018D929D92AD92BC92139724 -:10FB9000F80180809180A280B38020E030E040EACC -:10FBA00051ECC501B4010F94684087FD4AC020E0C4 -:10FBB00030E040EA51E4C501B4010F94B1391816A0 -:10FBC0000CF43FC0FFEFEF1AFF0A24E0C20ED11C75 -:10FBD0000C5F1F4F33E0E316F10409F09FCFA6EE50 -:10FBE000EA2EA8E0FA2E10E0F10181919191A19105 -:10FBF000B1911F01F70181939193A193B1937F017B -:10FC0000812F0E94FAB21F5F133071F70E94BBB8B8 -:10FC100060E083EB91E30E941D3B63E972E084E6C0 -:10FC200090E00E948D2B70E060E08AE090E00E94FE -:10FC30008D2B6AEB72E084E690E00E948D2B0C9491 -:10FC40000EEF0E940BD881ED91E30E94ACCE61E0F3 -:10FC500083EC91E30E941D3B0E945E2D68E270E000 -:10FC600080E991E00E948D2B0C940EEF0E94648B32 -:10FC70000C940EEF0E947CB90C940EEF61E083E5CA -:10FC80000E94E1CA91E089270E942E8A0C940EEF0F -:10FC90001091A21712FF0AC017FD08C00E9473CD71 -:10FCA00080FB17F91093A2170C940EEF14FD02C0FD -:10FCB0000C940EEF0F945F120C940EEF0E946CE9FF -:10FCC0000C940EEF8091BD0883FD09C08091BE08A1 -:10FCD000887129F481E00E94C7DB0C940EEF0E942A -:10FCE00013D8082F87FF02C00C940EEF85E50E9401 -:10FCF000D1C9882359F10E94A7C94B015C01E02EAC -:10FD0000002E000CFF0820E030E0A9010F946840AD -:10FD100087FF04C0B7FAB094B7F8B09420E030E0A1 -:10FD200048E453E4C501B4010F9468409701F3E03F -:10FD3000220F331FFA95E1F727523A4F1816D4F1E4 -:10FD4000D9018D929D92AD92BC9213978CE40E9442 -:10FD5000D1C9882311F40C940EEF0E94A7C96B013E -:10FD60007C01002E000C110B20E030E0A9010F9463 -:10FD7000684087FF04C0F7FAF094F7F8F09420E0A9 -:10FD800030E048E453E4C701B6010F94684098019D -:10FD9000E3E0220F331FEA95E1F727523A4F181696 -:10FDA0009CF0D9011496CD92DD92ED92FC921797BA -:10FDB0000C940EEF80E090E0A8E4B3E4F9018083B6 -:10FDC0009183A283B383C2CF80E090E0A8E4B3E440 -:10FDD000F90184839583A683B7830C940EEF712C6D -:10FDE000812C60EA962E71E4C72E0C9404F4E09105 -:10FDF000510928E0E29FF0011124E752FA4FC48034 -:10FE0000D580E680F7800C9465F40E9413D8082F03 -:10FE100087FF02C00C940EEF8AE50E94D1C9812CA5 -:10FE2000912C40EAA42E41E4B42E882329F08AE5DF -:10FE30000F9484124B015C01402F64E083E00E9428 -:10FE4000092E10915109E02E002E000CFF081E15FE -:10FE50001F0421F060E0802F0E947DB520E030E09B -:10FE6000A901C501B4010F94684018167CF580E023 -:10FE700090E0A0EAB0E489839A83AB83BC832091AD -:10FE80007E0230917F024091800250918102C50133 -:10FE9000B4010F94083E2B013C0120E030E046E124 -:10FEA00053E40F94B13987FD06C0412C512C36E143 -:10FEB000632E33E4732E4C8E5D8E6E8E7F8EBE016C -:10FEC0006F5F7F4FCE014C960E94C4B485E50E94BF -:10FED000D4C5882309F463C00E94A7C96B017C01C3 -:10FEE00020E030E0A901C701B6010F94684087FF08 -:10FEF00004C0F7FAF094F7F8F094F7FAF094F7F8F2 -:10FF0000F094C982DA82EB82FC8244E061E0CE01A7 -:10FF100001960E9457E720E030E0A901C501B40135 -:10FF20000F94684018165CF580E090E0A0EAB0E419 -:10FF300089839A83AB83BC83A501940160917E027F -:10FF400070917F0280918002909181020F94073E10 -:10FF50006B017C0120E030E0A9010F946840181685 -:10FF60001CF0C12CD12C7601CC8EDD8EEE8EFF8E56 -:10FF7000BE016F5F7F4FCE014C960E94C4B480914A -:10FF80005109181721F060E0812F0E947DB5809102 -:10FF90005109809300040E945E2D0C940EEFF7012E -:10FFA00023E0EE0FFF1F2A95E1F7E752FA4FC080DA -:10FFB000D180E280F38094CF19821A821B821C8246 -:10FFC0004091BC085091BD086091BE087091BF0877 -:10FFD000ECE9F2E0DE01119691E021E0819181549B -:10FFE0006A017B0104C0F694E794D794C7948A957C -:10FFF000D2F7C0FE02C02C9390E0119682E0E03A66 -:020000040002F8 -:10000000F80761F7992329F081E089838A838B833C -:100010008C8360E089E40E94E1CA8823A1F08FEA22 -:1000200095E10F94843383E795E10F94843387E35C -:1000300095E10F9484338BEF94E10F9484338FEB2D -:1000400094E10F9484332C814B816A8189810E94D1 -:10005000FEDB0C940EEF9CE9C92E92E0D92EEE2423 -:10006000E394F12C70E060E0D6018D916D010E9467 -:10007000C4CA8C010097D9F1B2E0FB16C1F0E3E0ED -:10008000FE16E9F0F1E0FF1651F09093E915809328 -:10009000E815BC018FEA95E10F940F2127C09093DA -:1000A000AD158093AC15BC0183E795E1F5CF909336 -:1000B000711580937015BC0187E395E1EDCF6EEF6C -:1000C0007FEF84E50E94C4CA823008F050C0E82E59 -:1000D00018160CF49AC01093351500933415B80116 -:1000E0008BEF94E10F940F21E11092C0E12CF39477 -:1000F00024E0F212B7CFEE2011F40C940EEF88E555 -:100100000E949FCE6091E8157091E9158AEF91E306 -:100110000E9404DB89E50E949FCE6091AC1570912E -:10012000AD158CE092E30E9404DB8AE50E949FCE2D -:1001300060917015709171158EE192E30E9404DB5D -:1001400085E40E949FCE609134157091351580E34F -:1001500092E30E9404DB0E94A6CE6091F814709195 -:10016000F91482E492E30E9404DB0C940EEF8EEF0C -:10017000E82EB1CF83E0809335091092441260E0FD -:1001800083E50E94E1CA81110C940EEF0F94330FA6 -:100190000C940EEF1091C2080F941E1D60933B0645 -:1001A00070933C0680933D0690933E06812F012E6E -:1001B000000C990B209151092817190651F060E0A5 -:1001C00083E50E94E1CA682F812F0E947DB50C94BF -:1001D0000EEF81E0F8CFF11004C0002311F40C946D -:1001E0006AEE612C712C70EA872EE0E49E2E0C944E -:1001F000CAED83E50E94D1C9882311F40C949BF7C2 -:100200000E9447C77B010C949BF7813009F06ECFA9 -:100210001093F9140093F814B8018FEB94E13CCFDC -:1002200020E030E0A901C701B6010F94B13988235D -:1002300011F40C943BED1CAA1DAA1EAA1FAAA7012B -:100240009601505828AF39AF4AAF5BAF8CA99DA932 -:10025000AEA9BFA9B0588CAF9DAFAEAFBFAFA701DD -:100260009601C701B6010F94173A4B015C012CA906 -:100270003DA94EA95FA9CA01B9010F94173A9B0184 -:10028000AC01C501B4010F94083E0F94B640A89686 -:100290006CAF7DAF8EAF9FAFA897809076029090A5 -:1002A0007702A0907802B0907902A7019601C5016B -:1002B000B4010F94083EE9966CAF7DAF8EAF9FAF4F -:1002C000E997C0907A02D0907B02E0907C02F09097 -:1002D0007D022496CCAEDDAEEEAEFFAE2497A70134 -:1002E00096016CA97DA98EA99FA90F94083EED9651 -:1002F0006CAF7DAF8EAF9FAFED9740908A06509068 -:100300008B0660908C0670908D06E9962CAD3DAD05 -:100310004EAD5FADE997C301B2010F94073E289639 -:100320006CAF7DAF8EAF9FAF2897C0908E06D090F8 -:100330008F06E0909006F0909106ED962CAD3DADC5 -:100340004EAD5FADED97C701B6010F94073E2C96F9 -:100350006CAF7DAF8EAF9FAF2C97A3019201C5010B -:10036000B4010F94073E4B015C012DEB37E346E8E7 -:1003700055EB0F94684087FF02C00C943DEF2DEBC6 -:1003800037E346E855E3C501B4010F94B1391816B7 -:1003900014F40C943DEFA701960124966CAD7DAD4D -:1003A0008EAD9FAD24970F94073E6B017C012DEB22 -:1003B00037E346E855EB0F94684087FF02C00C9482 -:1003C0003DEF2DEB37E346E855E3C701B6010F9447 -:1003D000B139181614F40C943DEF0230110511F0E8 -:1003E0000C94DAEF08E410E08BED482E8FE0582EE5 -:1003F00089EC682E80E4782E9BEDC92E9FE0D92EE3 -:1004000099ECE92E90ECF92E20917E0230917F023A -:10041000409180025091810260962CAF3DAF4EAF6B -:100420005FAF6097609192067091930680919406F9 -:10043000909195060F94073E4B015C01A301920138 -:10044000A8966CAD7DAD8EAD9FADA8970F94173A71 -:1004500021966FAF219725967FAF259729968FAF6D -:10046000299765969FAF659727E137EB41ED58E3F4 -:100470000F94B13987FF0AC027E137EB41ED58E30C -:10048000C501B4010F94B13987FD70C38091960600 -:1004900090919706A0919806B091990669968CAFB5 -:1004A0009DAFAEAFBFAF69972091820230918302BA -:1004B000409184025091850264962CAF3DAF4EAFBF -:1004C0005FAF64972AE037ED43E25CE3609151024D -:1004D0007091520280915302909154020F94173AF6 -:1004E0002B013C016091200270912102072E000C2B -:1004F000880B990B0F94B8399B01AC01C301B20171 -:100500000F94173A68A779A78AA79BA721966FAD82 -:10051000219725967FAD259729968FAD29976596CA -:100520009FAD65970F94AA3F1B012C01B80190E085 -:1005300080E00F94B6393B018C019B01AC01B10105 -:10054000C2010F946840181614F43101820193011E -:10055000A80121966FAD219725967FAD2597299605 -:100560008FAD299765969FAD65970F94023F1B014C -:100570002C0120E030E040E85FE30F94684018165B -:1005800014F00C94E8EF21966FAD219725967FAD7E -:10059000259729968FAD299765969FAD65970F94FE -:1005A000E63E0F947B3F6B967FAF6EAF6B971C8ED2 -:1005B0001D8E1E8E1F8E18A219A21AA21BA21CA28B -:1005C0001DA21EA21FA26B964EAD5FAD6B9742306F -:1005D000510508F4A1C2BA0190E080E00F94B63949 -:1005E000A4966CAF7DAF8EAF9FAFA4979B01AC017B -:1005F000C701B6010F94023F6F966CAF7DAF8EAF0F -:100600009FAF6F979B01AC010F94173A6B017C0170 -:10061000AC019B016F966CAD7DAD8EAD9FAD6F97BC -:100620000F94173A20E030E040EC50E40F94023F82 -:100630009B01AC016F966CAD7DAD8EAD9FAD6F979C -:100640000F94073EC358DF4F688379838A839B8367 -:10065000CD57D04020E030E040E05FE3C701B60175 -:100660000F94173A9B01AC0160E070E080E89FE3D3 -:100670000F94073ECF57DF4F688379838A839B832C -:10068000C158D040A4962CAD3DAD4EAD5FADA49702 -:10069000C501B4010F94023FCB57DF4F68837983C4 -:1006A0008A839B83C558D04064962CAD3DAD4EAD3A -:1006B0005FAD649769966CAD7DAD8EAD9FAD69976A -:1006C0000F94073EA4962CAD3DAD4EAD5FADA49703 -:1006D0000F94023FC757DF4F688379838A839B83D8 -:1006E000C958D0406096CCACDDACEEACFFAC6097A6 -:1006F000C986DA86EB86FC866496CCACDDACEEACC3 -:10070000FFAC6497CD86DE86EF86F88A0F941E1DB7 -:100710009B01AC0128533F4F4F4F5F4FE5962CAFE5 -:100720003DAF4EAF5FAFE597C0905909D0905A09E1 -:10073000E0905B09F0905C09609155097091560951 -:100740008091570990915809C616D706E806F90610 -:1007500010F4C701B6010F94B639AC966CAF7DAFFB -:100760008EAF9FAFAC97A0907909B0907A090091B5 -:100770007B0910917C09C701B6010F94B6396B0152 -:100780007C019B01AC01B501C8010F94B13987FF11 -:1007900002C06501780168A579A58AA59BA59B0182 -:1007A000AC010F94173A2D966FAF2D9761967FAFDE -:1007B00061971C01AC962CAD3DAD4EAD5FADAC97D5 -:1007C000A8966CAD7DAD8EAD9FADA8970F94173AEE -:1007D0005B018C019601A701B601C7010F94173A7E -:1007E0006B017C019501A8012D966FAD2D97619647 -:1007F0007FAD6197C1010F94684018163CF42D96A7 -:10080000AFAE2D976196BFAE619718012D962FADB3 -:100810002D9761963FAD6197A101B601C7010F9475 -:10082000B13987FF07C02D96CFAE2D976196DFAE09 -:10083000619717012196CFAC2197AD96CFAEAD97BA -:100840002596DFAC2597AE96DFAEAE972996EFAC36 -:100850002997AF96EFAEAF976596FFAC6597E09698 -:10086000FFAEE09748AC59AC6AAC7BAC29E1A096EE -:100870002FAFA09741E050E067965FAF4EAF67970C -:100880000E94A5910F941E1D8B019C01E596CCAC96 -:10089000DDACEEACFFACE5970C191D092E093F0944 -:1008A00037FD0FC09B01AC0128533F4F4F4F5F4FA7 -:1008B000E5962CAF3DAF4EAF5FAFE59780E00E946D -:1008C000EADDA0963FADA0973150A0963FAFA0972C -:1008D000332311F40C941EF0C358DF4F2881398163 -:1008E0004A815B81CD57D040B201C3010F94173AC2 -:1008F0006B017C01CF57DF4F288139814A815B81B1 -:10090000C158D0406CAD7DAD8EAD9FAD0F94173A00 -:100910009B01AC01C701B6010F94083E7B018C011D -:10092000CF57DF4F288139814A815B81C158D04040 -:10093000B201C3010F94173A4B015C01C358DF4F5A -:10094000288139814A815B81CD57D0406CAD7DAD26 -:100950008EAD9FAD0F94173A9B01AC01C501B40158 -:100960000F94073E2B013C01C701D8018CAF9DAF0E -:10097000AEAFBFAF9201A301E9966CAD7DAD8EAD78 -:100980009FADE9970F94083E69837A838B839C839C -:100990002CAD3DAD4EAD5FADED966CAD7DAD8EAD8C -:1009A0009FADED970F94083E6D837E838F8398876C -:1009B000CB57DF4F288139814A815B81C558D040B0 -:1009C00069857A858B859C850F94083E69877A872F -:1009D0008B879C87C757DF4F288139814A815B818C -:1009E000C958D0406D857E858F8598890F94083EC3 -:1009F0006D877E878F87988BCE0101960E941AB3F0 -:100A0000A4962CAD3DAD4EAD5FADA49721966FADD4 -:100A1000219725967FAD259729968FAD29976596C5 -:100A20009FAD65970F94023F9B01AC01AD966FADF2 -:100A3000AD97AE967FADAE97AF968FADAF97E09680 -:100A40009FADE0970F94073EAD966FAFAD97AE9612 -:100A50007FAFAE97AF968FAFAF97E0969FAFE0971F -:100A6000AC962CAD3DAD4EAD5FADAC97CA01B901B2 -:100A70000F94083EAD962FADAD97AE963FADAE97B5 -:100A8000AF964FADAF97E0965FADE0970F94173AF2 -:100A90007B018C012D962FAD2D9761963FAD61970F -:100AA000A1010F94684018163CF42D96EFAC2D97D9 -:100AB0006196FFAC61978101C701D8018CA39DA30A -:100AC000AEA3BFA39E01245E3F4F40915109BE01DA -:100AD000685D7F4FCE0101960E94ACA68823E1F0AD -:100AE000A896CCACDDACEEACFFACA897C8A2D9A25E -:100AF000EAA2FBA267962EAD3FAD67972F5F3F4FEF -:100B000067963FAF2EAF67976B96CEACDFAC6B9717 -:100B1000C216D30609F0B4CE80E1EAE8F6E0DE01C1 -:100B2000119601900D928A95E1F7CE0101960E94EF -:100B30001AB318A219A21AA21BA21CA21DA21EA2BD -:100B40001FA29E01245E3F4F40915109BE01685D86 -:100B50007F4FCE0101960E94ACA680E1FE01319646 -:100B6000A6E7B2E001900D928A95E1F70F941E1D61 -:100B700060933B0670933C0680933D0690933E063F -:100B80000C940EEF4F925F926F927F928F929F9292 -:100B9000AF92BF92CF92DF92EF92FF920F931F938B -:100BA000CF93DF93CDB7DEB77C014DB65EB66090D4 -:100BB0005309709054098DB69EB66AE070E0C70183 -:100BC0000F94F3386C018C010E191F09892B21F445 -:100BD000C7010F94FE388C01C80101962DB73EB7AE -:100BE000281B390B0FB6F8943EBF0FBE2DBF8DB733 -:100BF0009EB701965C01A801B7010F941F39F5015A -:100C0000E00FF11F1082C5010E9457C881E00E94C9 -:100C1000D1EBC114D10451F076019FEFE91AF90A22 -:100C20000FB6F8949EBE0FBE8DBEC5CF0FB6F8941A -:100C30009EBE0FBE8DBEC3010E9457C80FB6F8946A -:100C40005EBE0FBE4DBEDF91CF911F910F91FF9001 -:100C5000EF90DF90CF90BF90AF909F908F907F905C -:100C60006F905F904F900895CF92DF92EF92FF9236 -:100C70000E947F8F8091A217877F8B7F8093A2171E -:100C800080919817811138C00E94E4BA6B017C01F1 -:100C90008DE3C816D104E104F10420F082E695E367 -:100CA0000F94C2058EE595E30F94C2058AE495E39F -:100CB0000E94ACCE8DE3C816D104E104F104A0F08B -:100CC0000E94F5CB81E08093C50840E060E477E7BF -:100CD0008BE190E00E947CE88091C508882321F098 -:100CE0000E94F1CB1092C50886E495E3FF90EF9047 -:100CF000DF90CF900D94C2050F941327882321F223 -:100D0000FF90EF90DF90CF900895CF93DF93C09145 -:100D1000761081E6C89FE0011124C858DF4E80910B -:100D2000D40580FF05C00E940FD8CE010E9425C5C2 -:100D3000CE010E9457C880E0DF91CF910C94D1EB97 -:100D4000FC01808108950F931F93CF93DF93582F59 -:100D5000FC0180E077E0919148E0282F30E0A92F56 -:100D6000B0E08901000F012F001F110B9170C92FF6 -:100D700090E0D92F880F0C171D0721F0C901880FAB -:100D8000991F8727B595A7959A2F415031F79E2F28 -:100D9000951B961700F3DF91CF911F910F91089546 -:100DA00008950895AF92BF92CF92DF92EF92FF9293 -:100DB0000F931F93CF93DF936C017B018B01040F83 -:100DC000151FEB015E01AE18BF08C017D10759F01F -:100DD0006991D601ED91FC910190F081E02DC60161 -:100DE0001995892B79F7C501DF91CF911F910F914B -:100DF000FF90EF90DF90CF90BF90AF9008953FB7F6 -:100E0000F8948091531890915418A0915518B0916E -:100E1000561826B5A89B05C02F3F19F00196A11DB5 -:100E2000B11D3FBFBA2FA92F982F8827BC01CD0134 -:100E3000620F711D811D911D42E0660F771F881F93 -:100E4000991F4A95D1F7089520912B18260F332723 -:100E5000331F21323105ECF420918518FC0190E01C -:100E600080E0243069F082E00895A0912B18219150 -:100E7000AC01455F574EA40FB52FB11D2C930196C1 -:100E8000861798F380912B18680F60932B1880E0D9 -:100E9000089581E008950895E0915C1880915B18B1 -:100EA000E81730F4F0E0E651F84E808190E00895C4 -:100EB0008FEF9FEF089590915C1880915B182FEF52 -:100EC0003FEF981748F4E92FF0E0E651F84E208103 -:100ED00030E09F5F90935C18C901089580915B1882 -:100EE00090915C18891B990B0895CF92DF92EF9235 -:100EF000FF920F931F93CF93DF937C01CB018A0165 -:100F00002091AE18222389F0EB016B01C40ED51E8F -:100F1000CC15DD0569F06991D701ED91FC91019047 -:100F2000F081E02DC7011995F3CF642F0F942407AA -:100F3000C801DF91CF911F910F91FF90EF90DF904B -:100F4000CF900895CF93DF931F92CDB7DEB769831B -:100F50002091AE182223F9F02091AB18203258F0DE -:100F600021E030E0FC013383228390E080E00F90A9 -:100F7000DF91CF9108958091AC18E82FF0E0E5570C -:100F8000F74E998190838F5F8093AC188093AB1854 -:100F900081E090E0ECCF61E0CE0101960F94240750 -:100FA000F7CF2091E8173091E9172817390771F426 -:100FB0009091E7178091E617981741F0E091E717B5 -:100FC000F0E0EA55F84E808190E008958FEF9FEFB2 -:100FD0000895EF92FF920F931F93CF93DF93DC015D -:100FE0005C96ED90FC905D97E114F10479F481E05A -:100FF00090E013969C938E93129790E080E0DF919F -:10100000CF911F910F91FF90EF9008955196ED9120 -:10101000FC91529750968C915097982F90950FB7BE -:101020005E962C915E97122F127021FD6095F894B8 -:101030002081112319F1282B2083E7012197F1F753 -:1010400028E0462F50E0308160FF1AC0382B3083F3 -:10105000E7012197F1F7BA0175956795215089F756 -:10106000112381F08081892380830FBF5C968D914D -:101070009C910197F1F781E090E0C1CF2923DCCF6B -:101080003923E5CF9081892BEFCF2091E81730915C -:10109000E9172817390771F48091E6172091E717AF -:1010A00090E0805C9F4F821B910960E470E00F9498 -:1010B0004841089590E080E008952091E81730912C -:1010C000E91728173907B9F49091E7178091E617C7 -:1010D000981789F0E091E717F0E0EA55F84E808123 -:1010E0002091E71730E02F5F3F4F2F733327209376 -:1010F000E71790E008958FEF9FEF0895E091E817CC -:10110000F091E917E817F90769F4A389B4899C916C -:101110008589809589238C931092E9171092E8179E -:1011200081E0089580E00895CF93DF93EC018A8DEC -:101130009B8D892B01F18091E8179091E9178C170D -:101140009D07C9F0009711F00F947E088E8D8E7F59 -:101150008E8F1092E6171092E717D093E917C0937D -:10116000E817EB89FC8980819D89892B808381E048 -:10117000DF91CF91089580E0FBCFFC01A4A5B5A538 -:10118000109749F0ED91FC9111970190F081E02DBD -:10119000CD011995089582A593A5009739F0DC013A -:1011A000ED91FC910190F081E02DF3CF80E0089566 -:1011B000FC01A4A5B5A5109741F0ED91FC91119704 -:1011C0000284F385E02DCD01199482A593A50097A3 -:1011D00039F0DC01ED91FC910284F385E02DF4CF30 -:1011E00090E080E00895FC01A4A5B5A5109741F01A -:1011F000ED91FC9111970084F185E02DCD011994BA -:1012000082A593A5009739F0DC01ED91FC91008453 -:10121000F185E02DF4CF90E080E00895DC01589650 -:101220004C91589760FB42F958964C935897242F4D -:1012300059964C915997342F337050E040E0ED911E -:10124000FC910190F081E02D60E01994DC01ED91BA -:10125000FC910280F381E02D6FE61994262F2F7008 -:10126000DC0195966C919597607F622B95966C93B7 -:10127000959792962D913D914D915C919597ED9119 -:10128000FC910190F081E02D6CE61994DC019496BC -:101290002C91949760FB21F994962C9394979296B5 -:1012A0002D913D914D915C919597ED91FC9101901F -:1012B000F081E02D6CE61994DC0193968C91939764 -:1012C00060FB87F993968C93939761FB882780F94D -:1012D00094966C9194976E7F682B94966C939497E8 -:1012E00092962D913D914D915C919597ED91FC9148 -:1012F00011970190F081E02D6CE6CD011994DC018D -:1013000092968C91929760FB87F992968C93929724 -:101310006695677093968C919397887F682B9396C8 -:101320006C93939792962D913D914D915C919597E9 -:10133000ED91FC9111970190F081E02D6CE6CD01CB -:1013400019946770262F2295207FDC0192966C916C -:1013500092976F78622B92966C93929792962D91BA -:101360003D914D915C919597ED91FC910190F081AB -:10137000E02D6CE61994DC01ED91FC910280F38183 -:10138000E02D6CE619940F94BB09892F8F70089596 -:101390000F94BB098695817008950F94BB09771F40 -:1013A0007727771F8170880F872B08950F94BB09CB -:1013B000862F881F8827881F7770770F872B0895BF -:1013C0000F94BB09862F8295877008952EE93FE020 -:1013D000009729F0F9013197F1F70197F9CF0895B6 -:1013E000089580E00895FC018491882321F08230E3 -:1013F00011F083E0089586E00895EF92FF920F9335 -:101400001F93CF93DF93EC01162FEC80FD80F70143 -:101410000491C7010F94F309A82F013049F10FEF90 -:101420002C813D81F9013A9644913196549133973C -:101430006491319684911136E8F070E0762F66273A -:10144000860F972F911D0097A9F08E0D9F1D41E6E5 -:10145000511730F5188A1B8A1C8A198A1A8A90E05B -:1014600080E0DF91CF911F910F91FF90EF90089551 -:101470000FE0D6CFF90136966491319684911134FC -:1014800060F070E0762F6627860F972F911D0097EA -:1014900021F08E0D9F1D41E4DBCFC7014196D8CFCF -:1014A0005417C0F2B0E0FC0164916F3F29F401963B -:1014B000451781F24F5FF7CF411333C0F9012491F3 -:1014C000AC014F5F5F4FFC01222311F0223091F4F9 -:1014D00024912B8BFA0144914C8BFC013396E491BF -:1014E000E88BFC013496E491E98BFC013596E4919C -:1014F000EA8BB7CF2491322F3F7032503A8B22952E -:101500002F70298BFA014491242F2F702C8B429538 -:101510004F704B8BFC013296E491E295EF70E88BB3 -:10152000A0CF3296649160236A0F7B2F711D860FC6 -:10153000971FBECF8EBD0DB407FEFDCF8EB50895AB -:101540000F93FC010150040F84A996A9941788F009 -:10155000081710F4041778F42150260F83A995A9D1 -:10156000961758F0281760F481E0261720F40F91A1 -:101570000895081778F780E0FACF2817A8F7FBCF6F -:1015800081E0F5CF0F94AC41FC01DB018C9120810F -:101590003181382798E0A901220F331F57FD05C07C -:1015A0009150C9F7318320830895B1E22B27B0E130 -:1015B0003B27F6CF8F929F92AF92BF92CF92DF924E -:1015C000EF92FF92CF93DF9390934F1480934E143A -:1015D0001092821482E090E0A0E0B0E080936B145F -:1015E00090936C14A0936D14B0936E1410924D14DC -:1015F0001092491410924A1410924B1410924C14E9 -:101600008FEF9FEFDC018093451490934614A093D5 -:101610004714B0934814662309F470C040E060E0BA -:1016200070E0CB010E94717A81110DC0C0E08C2F57 -:10163000DF91CF91FF90EF90DF90CF90BF90AF9070 -:101640009F908F900895809103148F7779F7809100 -:101650000F1490911014A0911114B09112148436AB -:101660009105A105B10510F3C0900B14D0900C1496 -:10167000E0900D14F0900E14C114D104E104F104B3 -:10168000A9F240E0C701B6010E94717AC82F8823F1 -:1016900069F280915012909151128115924031F669 -:1016A000A0915512AA2311F2609153127091541215 -:1016B0006115710509F4BACF20915212222309F461 -:1016C000B5CFA0937D1420936F1490E080E030E0BC -:1016D000E1E0F0E0D82FAF01082E02C0440F551F03 -:1016E0000A94E2F72417350769F041E0480F0196A4 -:1016F0008930910579F74093781498CFC12CD12C7B -:101700007601BFCF8093781420915B1230915C12E8 -:1017100050E040E02115310541F4209169123091EB -:101720006A1240916B1250916C1220937014309396 -:101730007114409372145093731446015701860E2E -:10174000971EA11CB11C80927E1490927F14A092CF -:101750008014B0928114E0915612F0915712F093D8 -:101760008414E0938314B0E00F94E53DDC01CB01D9 -:10177000880D991DAA1DBB1D809385149093861416 -:10178000A0938714B093881425E0EE0FFF1F2A95CD -:10179000E1F7E150FE4FEF2FFF27E6958E0F9F1FD9 -:1017A000A11DB11D8093791490937A14A0937B149A -:1017B000B0937C148090581290905912B12CA12CA7 -:1017C0008114910441F48090651290906612A0906B -:1017D0006712B0906812C81AD90AEA0AFB0AC80C44 -:1017E000D91CEA1CFB1C04C0F694E794D794C79458 -:1017F000DA95D2F7C0927414D0927514E0927614F0 -:10180000F092771485EFC8168FE0D806E104F10452 -:1018100020F48CE08093821409CF80E125EFC2167A -:101820002FEFD206E104F10488F0809171129091BB -:101830007212A0917312B0917412809385149093D8 -:101840008614A0938714B093881480E28093821446 -:10185000EECE8F929F92AF92BF92CF92DF92EF9295 -:10186000FF920F931F93CF93DF9300D01F92CDB7BA -:10187000DEB7FC018381813091F080E00F900F9002 -:101880000F900F90DF91CF911F910F91FF90EF90EC -:10189000DF90CF90BF90AF909F908F9008958181FF -:1018A00081FFEBCF81899289A389B489892B8A2B07 -:1018B0008B2B09F460C07F0140E050E0BA01CF01FA -:1018C0000E94827C8823C9F2F701C18CD28C858862 -:1018D0009688A788B08C82E090E0A0E0B0E0F601A6 -:1018E00080839183A283B3839E012F5F3F4FB50115 -:1018F000A401C6010E94457B882309F4BECF00E005 -:1019000010E09801B501A401C6010E94B37A8823B2 -:1019100009F4B3CF89809A80AB80BC80F6018789B7 -:10192000803101F5F8EF8F16FFEF9F06A104B10497 -:10193000D8F2F701158A168A178A108E118A128A30 -:10194000138A148A818180688183C7010E94297E5D -:10195000882309F492CF40E050E0BA01C7010E9409 -:10196000827C8CCF88EF88168FEF9806A8068FE0D0 -:10197000B806F8F6B9CF81E081CF2F923F924F920F -:101980005F926F927F928F929F92AF92BF92CF920F -:10199000DF92EF92FF920F931F93CF93DF9300D0CC -:1019A0001F92CDB7DEB7382E7B012DB73EB73C83F3 -:1019B0002B838091ED18811107C01092D2181092DC -:1019C000D51881E08093ED188091CA18811107C065 -:1019D0001092AF181092B21881E08093CA18DA0101 -:1019E0008C918F3209F08DC084EA94E1F7019183E4 -:1019F00080834F5F5F4F311010929717F70101906E -:101A0000F081E02DFA83E9838A0122EDC22E28E1DC -:101A1000D22E3BE1232E01151105E9F14DB65EB63C -:101A20006FE270E0C8010F94E2414C0108171907FA -:101A300068F53C01601A710A7724C30101962DB73D -:101A40003EB7281B390B0FB6F8943EBF0FBE2DBF13 -:101A50008DB79EB701965C01A301B8010F940242B5 -:101A6000F501E60DF71D1082C6010E945E7ED701CA -:101A70006D917C9121E0A501C6010E946A808111CF -:101A800046C0C5010E9455BE10E000E00FB6F894B4 -:101A90005EBE0FBE4DBE3320A9F0D701ED91FC9183 -:101AA0008BE1A9E8B4E101900D928A95E1F791E00C -:101AB00080919717811190E08091A21790FB86F991 -:101AC0008093A217C801EB81FC810FB6F894FEBF8A -:101AD0000FBEEDBF0F900F900F900F90DF91CF9141 -:101AE0001F910F91FF90EF90DF90CF90BF90AF903C -:101AF0009F908F907F906F905F904F903F902F902E -:101B0000089589E894E1D7018D939C9377CFF701ED -:101B10008081918129813A812817390711F00E942B -:101B20005E7ED701CD92DC92332099F0A091971779 -:101B3000AA3078F481E08A0F809397172A9ED0010B -:101B40001124A757B94EF601822D01900D928A9566 -:101B5000E1F7B2EDCB16B8E1DB0669F49FEAC92ED6 -:101B600098E1D92E84010F5F1F4F0FB6F8945EBE27 -:101B70000FBE4DBE50CF82EDC82E88E1D82EF2CFD9 -:101B80008F929F92AF92BF92EF92FF921F93CF934B -:101B9000DF93CDB7DEB7A0970FB6F894DEBF0FBEC8 -:101BA000CDBF611571058105910591F120E04AE0F5 -:101BB000842E912CA12CB12C11E0120FEE24E39471 -:101BC000F12CEC0EFD1EE20EF11C27FDFA94A5018E -:101BD00094010F94A43DF7016083B901CA01212F3C -:101BE000611571058105910539F7115018F1E1E092 -:101BF000F0E0EC0FFD1FE10FF11D17FDFA9590814C -:101C000087E39A3008F480E3890F0E949FCEEDCFDE -:101C100080E3A0960FB6F894DEBF0FBECDBFDF9174 -:101C2000CF911F91FF90EF90BF90AF909F908F90BA -:101C30000C949FCEA0960FB6F894DEBF0FBECDBF1A -:101C4000DF91CF911F91FF90EF90BF90AF909F9049 -:101C50008F900895CF92DF92EF92FF926B017C01FB -:101C6000F7FE0BC0F094E094D094C094C11CD11C3A -:101C7000E11CF11C8DE20E949FCEC701B601FF90CE -:101C8000EF90DF90CF900D94C00DCF93DF93209114 -:101C9000441221111EC0FC0101900020E9F7319788 -:101CA000EF01C81BD90BCB32D1052CF02291207C3F -:101CB0002038E1F3F5CFBC01DD27AE0189E192E1E7 -:101CC0000F940242C75EDD4E1882109218121092D5 -:101CD0001712DF91CF910895BF92CF92DF92EF92CA -:101CE000FF920F931F93CF93DF93EB01FC012381AE -:101CF000223008F49DC040855185628573854F71FF -:101D0000552766277727452B462B472B09F090C090 -:101D10008C011092FD111092FC11C12CDD24DA947B -:101D20007E01FBE0EF0EF11C8DE0B82E40E250E0AA -:101D3000BE01C8010E94167D8032910581F021E02C -:101D4000892B09F420E0822F8195DF91CF911F919B -:101D50000F91FF90EF90DF90CF90BF900895288172 -:101D6000222309F467C0253E11F02E3229F4109287 -:101D7000FD111092FC11DACF3B853F733F3009F023 -:101D800042C04A8D5B8D452B61F52F713FEF320FBD -:101D9000323038F58D85213041F1C81229C02150EB -:101DA000330BB29EC001B39E900D1124DC01A450F0 -:101DB000BE4EFE0120E02B30F0F0468157814F3FB0 -:101DC000510519F010F04FE550E04D932F5F32961A -:101DD0002D3089F7288126FF04C0FC01E75FFD4E06 -:101DE00010822B8523FDA2CFB0CFC82ED12CD7CF08 -:101DF000DD24D394D4CF253018F044815581DFCF32 -:101E000041815281DCCFD1100EC0FE0120E020FBC9 -:101E1000279527F93191230FEE16FF06C1F7C21659 -:101E200001F3DD24D3941092FD111092FC11D9CF4F -:101E30008FEF8BCF80E089CF9091771021E6929F32 -:101E4000F0011124E852FF4E80839F5F943040F4EC -:101E500090937710809175108F5F8093751008951F -:101E600010927710F7CFCF92DF92EF92FF92ECE8CB -:101E7000FFE080818183C0900E10D0900F10E09021 -:101E80001010F09011108FEFC81AD80AE80AF80A5B -:101E900082E89CE30E94ACCEC701B6010F942A0EE3 -:101EA0008AE00E949FCE8EE79CE3FF90EF90DF9048 -:101EB000CF900C94ACCECF92DF92EF92FF920F9323 -:101EC0001F93CF938C01C62F0E940BD8C0900E1089 -:101ED000D0900F10E0901010F0901110C8010E94E7 -:101EE000ACCEC701B6010F942A0E8AE00E949FCEA5 -:101EF0000E947BDD0196E1F78C2F0F94330F109237 -:101F0000131010921210CF911F910F91FF90EF902C -:101F1000DF90CF9008952F923F924F925F926F92F1 -:101F20007F928F929F92AF92BF92CF92DF92EF9269 -:101F3000FF920F931F93CF93DF93CDB7DEB76697D2 -:101F40000FB6F894DEBF0FBECDBF4C017B011A0166 -:101F50003E8B2D8B198A1A8AFB0180819181A28187 -:101F6000B3818F3F9105A105B10521F118F11D86BF -:101F70001E861F86188AAC01BD0137E076956795ED -:101F8000579547953A95D1F75A87498780688B8747 -:101F90008C870091890F10918A0F8091870F909103 -:101FA000880F9C8B8B8BAA24A394B12C011511054F -:101FB00009F050C0F7018081898BB401AE014F5EFA -:101FC0005F4FC101ED89FE89199566960FB6F894A9 -:101FD000DEBF0FBECDBFDF91CF911F910F91FF905C -:101FE000EF90DF90CF90BF90AF909F908F907F90B9 -:101FF0006F905F904F903F902F90089582179307B6 -:1020000020F19C818B85981708F445C09B818C85B5 -:102010008917D8F06091870F7091880F640D751D36 -:1020200048E050E0CE0109960F94DF386F8578893B -:102030006115710509F4BECF8616970609F4BECF67 -:10204000F70180818068898BB9CF86010A151B054D -:1020500008F4B0CF3501600E711E76946794630169 -:1020600091E0C91AD108260193E0440C551C9A95B9 -:10207000E1F76B897C89640D751D48E050E0CE0165 -:1020800001960F94DF3829813A8189859A8528172E -:10209000390708F0B3CF5301EFEFAE1ABE0AD6CF1F -:1020A0008F929F92AF92BF92CF92DF92EF92FF9268 -:1020B0000F931F93CF93DF9300D01F92CDB7DEB75E -:1020C0006C017B014A015901AE014F5F5F4FB401C2 -:1020D000C7010E94C23E7C0189819A81AB81BC818B -:1020E000892B8A2B8B2B49F09801A501BE016F5FCC -:1020F0007F4FC6010F948B0FE7CF0F900F900F907B -:102100000F90DF91CF911F910F91FF90EF90DF9093 -:10211000CF90BF90AF909F908F9008950E9481CDF7 -:1021200081111AC08091A21782FF0DC087FD0BC0DC -:102130008091FC11811104C089E79FE00D94450E48 -:102140008CEF91E1FBCF8091860F813041F08AE4E2 -:102150009CE36FEF0C941D3B81E79CE3FACF85E68F -:102160009CE3F7CF4F925F926F927F928F929F92F4 -:10217000AF92BF92CF92DF92EF92FF920F931F9395 -:10218000CF93DF93C6E7D2E04C845D846E847F8476 -:102190000DE61FE0F80124813581468157816C816D -:1021A0007D818E819F810F94083E4B015C01F80177 -:1021B0002085318542855385688579858A859B850B -:1021C0000F94083E6B017C01F8012081318142812E -:1021D0005381688179818A819B810F94083EAB018C -:1021E000BC0187E49CE30E94A4CFB501A40183E471 -:1021F0009CE30E94A4CFB701A6018FE39CE30E9459 -:10220000A4CFB301A2018BE39CE3DF91CF911F9197 -:102210000F91FF90EF90DF90CF90BF90AF909F9085 -:102220008F907F906F905F904F900C94A4CFCF933E -:10223000DF931F92CDB7DEB787E0898360E0CE01E0 -:1022400001960E94D9B261E0CE0101960E94D9B2F6 -:1022500062E0CE0101960E94D9B289810F90DF9190 -:10226000CF9108950F931F93CF93DF93CDB7DEB730 -:102270006E970FB6F894DEBF0FBECDBF0F94171147 -:102280008823E9F142EF53E082FF02C043EF53E0BD -:1022900022EF33E081FF02C025EF33E080FD2CC048 -:1022A00082EF93E05F934F933F932F939F938F938E -:1022B00089E29CE39F938F938E010F5F1F4F1F93C3 -:1022C0000F930F9448390E940FD8C8010E9425C56A -:1022D000C8010F94450E0FB6F894DEBF0FBECDBFF8 -:1022E00081E06E960FB6F894DEBF0FBECDBFDF91D2 -:1022F000CF911F910F91089587EF93E0D3CF80E0A6 -:10230000F0CFCF93DF938091091690910A16891B25 -:1023100080958F7019F40E94EADDF5CF809109163F -:102320008F5F8F70A09109169DE5A99FD0011124A0 -:10233000FD01E356F64FEF0119929A95E9F7908166 -:1023400098609083AE54B64F90E1EFE1F6E10190D2 -:102350000D929A95E1F72091091690910A1629138A -:1023600003C094E69093061680930916DF91CF91EF -:102370000C944995CF93DF93CDB7DEB760970FB636 -:10238000F894DEBF0FBECDBF80E1E6E7F2E0DE01EC -:10239000119601900D928A95E1F7CE0101960E9467 -:1023A000D0B160960FB6F894DEBF0FBECDBFDF91FF -:1023B000CF910895DC01ED91FC910190F081E02D29 -:1023C00027E030E040E050E061E01994DC01149631 -:1023D0008C911497807F8A6014968C931497129630 -:1023E0002C91129713963C911397482F4F7050E001 -:1023F000ED91FC9111970190F081E02D60E1CD010C -:1024000019946091EA1581E068278FEA95E10D94AF -:102410000E096091AE1581E0682783E795E10D9480 -:102420000E096091721581E0682787E395E10D94AC -:102430000E096091361581E068278BEF94E10D94C9 -:102440000E096091FA1481E068278FEB94E10D94F6 -:102450000E09CF93C82F41E00E946FD98C2FCF91E6 -:102460000C948ED9CF93DF936AE17CE30F94291209 -:10247000C5E5D9E04C895D896E897F8982E19CE35D -:102480000E94A4CF488D598D6A8D7B8D8FE09CE38F -:102490000E94A4CF4C8D5D8D6E8D7F8D8CE09CE372 -:1024A0000E94A4CF48A159A16AA17BA189E09CE325 -:1024B0000E94A4CF8AE0DF91CF910C949FCE80E55B -:1024C00094E10E94297E80E594E10E945E7E8091E5 -:1024D000A2178D7F8E7F8093A21710929E17109265 -:1024E0009F171092A0171092A11708950E940FD85D -:1024F000609153097091540986EF9BE30E94E0DDDF -:1025000083EF9BE30C94ACCE0E94D1C981110C9453 -:10251000A7C960E070E0CB0108954F925F926F927F -:102520007F928F929F92AF92BF92CF92DF92EF9263 -:10253000FF920F931F93CF93DF9300D01F92CDB7DD -:10254000DEB74C015B016A01F22E6E2D80E00E9425 -:102550006FE5182F81111CC0409151096E2D89E043 -:102560000E94092E812F0F900F900F900F90DF91F6 -:10257000CF911F910F91FF90EF90DF90CF90BF9080 -:10258000AF909F908F907F906F905F904F90089545 -:10259000002331F1409151096E2D84E00E94092EF3 -:1025A0000E940FD881ED9BE30E94ACCE61E08F2D9D -:1025B0000E9425CC0091500983E08093500981E06E -:1025C00080934F0980914F09882341F060E08F2D5F -:1025D0000E9425CC81E00E94EADDF4CF00935009EF -:1025E000409151096E2D85E00E94092E20E030E0D7 -:1025F000A901F40160817181828193810F94B139C5 -:10260000882371F080E090E0A0ECB0E489839A83A5 -:10261000AB83BC83BE016F5F7F4FC4010E944EB588 -:1026200020E030E0A901F501608171818281938110 -:102630000F94B139882351F140908D0950908E0943 -:1026400060908F097090900980E090E0A8ECB1E470 -:1026500080938D0990938E09A0938F09B093900970 -:1026600080E090E0A0ECB0E489839A83AB83BC83E4 -:10267000BE016F5F7F4FC5010E944EB540928D092C -:1026800050928E0960928F0970929009812C912C42 -:1026900080E4A82EBA2C03E020E030E0A901F60186 -:1026A00060817181828193810F946840181684F44F -:1026B0004091510960E086E00E94092E89829A8249 -:1026C000AB82BC82BE016F5F7F4FC6010E944EB5D8 -:1026D000F09050090093500910924F094091510910 -:1026E00060E087E00E94092E80914E09811104C0AC -:1026F00081E00E94EADDF8CFF0925009813061F26A -:1027000031CF4F925F926F927F928F929F92AF9252 -:10271000BF92FF920F931F93CF93DF93CDB7DEB796 -:10272000A0970FB6F894DEBF0FBECDBFF82E4A01BA -:102730005B012801390120E030E0A901C301B801A3 -:102740000F94B139811111C0FF2019F081E0F81206 -:1027500092C060E070E88BE395E420E030E040E771 -:1027600052E40F94023F2B013C014D8E5E8E6F8E22 -:1027700078A20F2D10E0F801E253F44CE491772495 -:1027800073941E160CF4712CFF24F39420E030E0B7 -:10279000A901C501B4010F94684018160CF0F12C82 -:1027A00080E00E9485B269837A838B839C8381E079 -:1027B0000E9485B26D837E838F83988782E00E941A -:1027C00085B269877A878B879C8783E00E9485B270 -:1027D0006D877E878F87988B000F111F000F111F49 -:1027E000E1E0F0E0EC0FFD1F0E0F1F1FF80110825B -:1027F000118212821382CE0101960E94D0B1F8019B -:1028000080829182A282B382198A1A8A1B8A1C8AC8 -:102810001D8A1E8A1F8A188E198E1A8E1B8E1C8E78 -:1028200080914C0990914D09892B61F49E012F5E96 -:102830003F4F40915109BE01635E7F4FCE0101962B -:102840000E94D6960E947F8F7F100E94D6BAA096D3 -:102850000FB6F894DEBF0FBECDBFDF91CF911F91B1 -:102860000F91FF90BF90AF909F908F907F906F904F -:102870005F904F90089560E070E080E793E46DCF43 -:10288000CF92DF92EF92FF920F931F93CF93DF933C -:1028900000D01F92CDB7DEB705E1041B442361F0E1 -:1028A00082E090E0A0E0B0E089839A83AB83BC83B0 -:1028B000CE0101960E946740E02FF0E086E0089F7D -:1028C000800111248091FC1181111AC089E79FE0D9 -:1028D000B8010E94DDC7081B190B80E2C82ED12C5D -:1028E000E12CF12C0730110588F0C982DA82EB82E5 -:1028F000FC82CE0101960E946740081B190BF2CFA3 -:10290000E450FE4E10828CEF91E1E2CF0F900F90D9 -:102910000F900F90DF91CF911F910F91FF90EF904B -:10292000DF90CF9008954F925F926F927F92AF9217 -:10293000BF92CF92DF92EF92FF920F931F93CF93AC -:10294000DF9300D01F92CDB7DEB77B01142F41FB80 -:10295000662760F90E94733F882309F45CC0D12C7C -:10296000C12CE114F10439F0C7010E94B43E96E095 -:10297000899F6001112410FF20C080E890E08C192D -:102980009D096CE070E00F9448415B0100E810E0A5 -:1029900090E2492E512C612C712C81E0A81AB108CB -:1029A000B7FC0DC049825A826B827C82CE010196AF -:1029B0000E946740081B190BF0CF00E810E0CD28FB -:1029C000B9F0C80166E070E00F94344120914A09E3 -:1029D00030914B094091480950914909062F609167 -:1029E0004709C7010E94A74196E0899F80011124F1 -:1029F00080E2C82ED12CE12CF12C0730110558F0C3 -:102A0000C982DA82EB82FC82CE0101960E94674085 -:102A1000081B190BF2CF0F900F900F900F90DF91C2 -:102A2000CF911F910F91FF90EF90DF90CF90BF90CB -:102A3000AF907F906F905F904F9008958F929F928C -:102A4000AF92BF92EF92FF920F931F93CF93DF93BA -:102A500000D01F92CDB7DEB7982F862F7A01122FA4 -:102A6000692F0E94733F882309F446C020914A09C8 -:102A700030914B09409148095091490904E1609116 -:102A80004709C7010E94A74196E0899F7001112460 -:102A900080E2882E912CA12CB12C87E0E816F1045D -:102AA00058F089829A82AB82BC82CE0101960E9444 -:102AB0006740E81AF90AF1CF812F110F990BAA0B81 -:102AC000BB0B89839A83AB83BC83809146099AE7C9 -:102AD0009093801680938116CE0101960E946740E4 -:102AE00080E290E0A0E0B0E089839A83AB83BC836E -:102AF000CE0101960E9467400F900F900F900F90AB -:102B0000DF91CF911F910F91FF90EF90BF90AF9009 -:102B10009F908F900895EF92FF920F931F93CF9302 -:102B2000DF93FB01D081DD2341F17B018C016D2F0F -:102B30000F94FD09F801C189C195FFEFEF1AFF0A53 -:102B4000F70181917F01F801882341F09089C90F35 -:102B5000D82F682FC8010F94FD09F2CFD03259F059 -:102B600083899189890F8C0FDF91CF911F910F91EC -:102B7000FF90EF9008958089F6CF80E0F5CF81E057 -:102B8000809345091092410910924209109243091D -:102B90001092440908952F923F924F925F926F9244 -:102BA0007F928F929F92AF92BF92CF92DF92EF92DD -:102BB000FF920F931F93CF93DF9300D000D0CDB738 -:102BC000DEB71C017E836D8329013A01470158015C -:102BD00020E030E040E05FECC301B2010F946840B8 -:102BE00018162CF0412C512C612C2FEC722EC301A5 -:102BF000B2010F94743F2B013C0120E030E040E033 -:102C00005FE4C501B4010F94B13987FD05C0812C83 -:102C1000912CA12C9FE4B92EC301B2010F94B839B5 -:102C20009B01AC01ED81FE81608171818281938184 -:102C30000F94073E0F947B3F69837A838B839C8339 -:102C4000C501B4010F94743F7B018C01E418F508B1 -:102C5000060917091F92912C812C88E0A82E88E480 -:102C6000B82EC980DA80A30192016D817E81C101F5 -:102C70000E94EB2C0F9026960FB6F894DEBF0FBE85 -:102C8000CDBFDF91CF911F910F91FF90EF90DF901B -:102C9000CF90BF90AF909F908F907F906F905F90FC -:102CA0004F903F902F9008952F923F924F925F92B6 -:102CB0006F927F928F929F92AF92BF92CF92DF924C -:102CC000EF92FF920F931F93CF93DF931C01EB01C1 -:102CD000CA01B9010F94B6392AE037ED43E25DE34A -:102CE0000F94173A2B013C0120E030E040E05FEC0C -:102CF0000F94684018162CF0412C512C612C3FEC9D -:102D0000732EC301B2010F94743F2B013C01688103 -:102D100079818A819B810F94B6392AE037ED43E2AD -:102D20005DE30F94173A6B017C01C301B2010F946C -:102D3000B8399B01AC01C701B6010F94073E0F944F -:102D40007B3F6B0188E79FE0A0E0B0E08419950924 -:102D5000A609B7091F9248012CEFA22E27E4B22E34 -:102D60007C018D01A3019201BE01C1010E94EB2CE7 -:102D70000F90DF91CF911F910F91FF90EF90DF9017 -:102D8000CF90BF90AF909F908F907F906F905F900B -:102D90004F903F902F9008952F923F924F925F92C5 -:102DA0006F927F928F929F92AF92BF92CF92DF925B -:102DB000EF92FF920F931F93CF93DF9300D000D039 -:102DC0001F921F92CDB7DEB71C0178876F83790100 -:102DD0001A830983BA01550F880B990B0F94B839E0 -:102DE0004B015C0120E030E040E05FEC0F94684074 -:102DF00018162CF0812C912CA12C2FECB22EC50191 -:102E0000B4010F94743F2B013C01B701FF0C880BF8 -:102E1000990B0F94B8394B015C0120E030E040E0A1 -:102E20005FE40F94B13987FD05C0812C912CA12C52 -:102E30009FE4B92EEF81F88560817181072E000C27 -:102E4000880B990B0F94B8396B017C01C301B20157 -:102E50000F94B8399B01AC01C701B6010F94073E2E -:102E60000F947B3F6B837C838D839E83C501B4016C -:102E70000F94743F7B018C01E418F50806091709CB -:102E80001F9289809A808EE0A82E88E4B82ECB808D -:102E9000DC80A30192016F817885C1010E94EB2C37 -:102EA0000F9028960FB6F894DEBF0FBECDBFDF910E -:102EB000CF911F910F91FF90EF90DF90CF90BF9037 -:102EC000AF909F908F907F906F905F904F903F90CA -:102ED0002F9008956F927F928F929F92AF92BF92A0 -:102EE000CF92DF92EF92FF920F931F93CF93DF93D6 -:102EF0003C01EB01688179818A819B810F947B3F42 -:102F00001F92912C812C84E1A82E88E4B82E6B01AD -:102F100018ECE12EF12C00E010E020E030E0A901F7 -:102F2000BE01C3010E94EB2C0F90DF91CF911F9146 -:102F30000F91FF90EF90DF90CF90BF90AF909F9058 -:102F40008F907F906F9008958F929F92AF92BF92D3 -:102F5000CF92DF92EF92FF920F931F93CF93DF9365 -:102F6000EC014B016091360970E090E080E00F9435 -:102F7000B63929EC38EC48EC5EE30F94173A20E0C0 -:102F800030E040E05FE30F94083E0F947B3F1F92D8 -:102F900084EEA82E87E4B82E6B0114E6E12EF12C06 -:102FA00000E010E020E030E0A90166E379E0CE0126 -:102FB0000E94EB2C0F90DF91CF911F910F91FF900A -:102FC000EF90DF90CF90BF90AF909F908F9008953B -:102FD0008F929F92AF92BF92CF92DF92EF92FF9229 -:102FE0000F931F93FB01C080D12C21E02F9328E089 -:102FF000822E2CEC922E3EEDA32E37E4B32EE12C44 -:10300000F12C8701EA9420E030E0A9010E94EB2C2A -:103010000F901F910F91FF90EF90DF90CF90BF9096 -:10302000AF909F908F9008956F927F928F929F9212 -:10303000AF92BF92CF92DF92EF92FF920F931F93C6 -:10304000CF93DF933C01EB014A016881798190E0E5 -:1030500080E00F94B6392DEC3CEC4CEC5DE30F9422 -:10306000173A20E030E040E251E40F94073E0F941D -:103070007B3F1F9288EDA82E87E4B82E6B0112E2E9 -:10308000E12EFF24F39400E010E02AE030E040E07D -:1030900050E0BE01C3010E94EB2C0F90DF91CF9155 -:1030A0001F910F91FF90EF90DF90CF90BF90AF9066 -:1030B0009F908F907F906F900895282F30E0F901B6 -:1030C000E151F84C9491F901E857F44C44912E5B8E -:1030D000344CF9012491222309F435C0992311F1CC -:1030E00091509231F8F4E92FF0E08827E558F74E37 -:1030F0008E4F0D945C41F601A8003C01E201CA002C -:10310000A0014C02F0012402420186025E01B401DA -:103110000802A001660174026802809180008F7726 -:1031200080938000E22FF0E0EE0FFF1FE85DF44C8B -:10313000A591B4918FB7F894EC91611148C0409576 -:103140004E234C938FBF0895809180008F7DE8CFF0 -:1031500080918000877FE4CF84B58F7784BDE2CFF4 -:1031600084B58F7DFBCF8091B0008F778093B000C6 -:10317000D9CF8091B0008F7DF9CF809190008F776B -:1031800080939000CFCF809190008F7DF9CF809178 -:103190009000877FF5CF8091A0008F778093A0006B -:1031A000C1CF8091A0008F7DF9CF8091A000877F53 -:1031B000F5CF809120018F7780932001B3CF80914C -:1031C00020018F7DF9CF80912001877FF5CF4E2B95 -:1031D000B8CFEF92FF920F931F93CF93DF93CDB7AA -:1031E000DEB762970FB6F894DEBF0FBECDBF611594 -:1031F000710579F460E062960FB6F894DEBF0FBEF9 -:10320000CDBFDF91CF911F910F91FF90EF900D9463 -:103210005D186F3F710511F461E0EDCF8B01F82E61 -:10322000682FCE0101960E949ECD8989882309F4DA -:1032300077C0E981FA819F858889911134C06081C6 -:1032400090E023E030E0A901481B590B440F551FC3 -:10325000042E01C0220F0A94EAF72095262362E08B -:1032600070E001C0660F4A95EAF7262B2083FC0127 -:103270003396EE0FFF1F21E030E02C0F3D1FE20FD1 -:10328000F31F0190F081E02D1183008362960FB649 -:10329000F894DEBF0FBECDBFDF91CF911F910F918C -:1032A000FF90EF9008952A892111F0CFAFEFB0E0A1 -:1032B000923029F0AD85BE850D90BC91A02D608126 -:1032C00090E023E030E0A901481B590B440F551F43 -:1032D000042E01C0220F0A94EAF72095262362E00B -:1032E00070E001C0660F4A95EAF7262B208303960B -:1032F000880F991FE1E0F0E0EC0FFD1F8E0F9F1F7C -:10330000FC01E080F18098010F94F83D2FEF30E050 -:1033100040E050E00F94A43DF70131832083B6CF05 -:1033200061E00F37110508F460E08F2D64CF109233 -:10333000851881E08093841810925F1861E084E121 -:103340000F945D1861E085E10F945D18E9EBF0E002 -:1033500080818E7F808380818D7F808388E48093CD -:10336000B80085E48093BC000895CF93DF9391E08B -:1033700090930A188823B9F0C091B800D091BA0090 -:103380008091BC008A7B8093BC0060E084E10F9454 -:103390005D1860E085E10F945D180F949719D09344 -:1033A000BA00C093B800DF91CF9108958F929F9299 -:1033B000AF92BF92CF92DF92EF92FF920F931F9343 -:1033C000CF93DF9300D000D0CDB7DEB791E19983E2 -:1033D0001A828B831C826D834E8381E08093AE18AA -:1033E00082E68093AD181092AC181092AB1846E0AC -:1033F00050E0BE016F5F7F4F85EF98E10F94750736 -:103400000091AB18013208F094C01091AD180F94E0 -:10341000FF066B017C0180918518811165C082E0F7 -:103420008093851881E0809384188FEF80938318B0 -:103430001092821800938118ABE8B8E1E1E6F8E158 -:1034400080E008138FC01092601880916018110FEF -:10345000182B1093601880915F18813009F086C096 -:1034600010925F180F94FF066B017C018091601829 -:103470008093BB008091871890918818A09189183B -:10348000B0918A18892B8A2B8B2B99F00F94FF0609 -:1034900000918718109188182091891830918A1806 -:1034A0006C197D098E099F09061717072807390728 -:1034B000E0F18091BC0083FDD9CF85EC8093BC0006 -:1034C0000F94FF066B017C0180918518823009F40E -:1034D0004FC0809183188F3F61F1809183188032B3 -:1034E00041F18091831825C08091871890918818A8 -:1034F000A0918918B0918A18892B8A2B8B2B09F4FB -:103500008ACF0F94FF068090871890908818A0901B -:103510008918B0908A186C197D098E099F09861642 -:103520009706A806B90608F076CF809186180F9402 -:10353000B5191092AC181092AB181092AE182696CE -:103540000FB6F894DEBF0FBECDBFDF91CF911F91B4 -:103550000F91FF90EF90DF90CF90BF90AF909F9032 -:103560008F9008959D9191938F5F6BCF85EEA6CF3D -:103570008091871890918818A0918918B0918A1825 -:10358000892B8A2B8B2B09F49FCF0F94FF06009178 -:103590008718109188182091891830918A186C1911 -:1035A0007D098E099F09061717072807390708F0B4 -:1035B0008BCFBBCF85ED8093BC0080918718909115 -:1035C0008818A0918918B0918A180796A11DB11D7D -:1035D00023E0B695A795979587952A95D1F72091E1 -:1035E000BC0024FD03C010928518089540918718EF -:1035F000509188186091891870918A18452B462B34 -:10360000472B69F30097A105B10541F025E32A9501 -:10361000F1F700000197A109B109E1CF8091861867 -:103620000D94B519CF93DF93EC016C8161708881A3 -:103630000F945D186C81669561708A81DF91CF91DE -:103640000D945D18860F911DFC0183A18F3F19F029 -:10365000642F0D945D180895CF93DF9390E0FC01E3 -:10366000E857F44C24918E5B944CFC0184918823A0 -:10367000C9F090E0880F991FFC01EB52F84CA5911E -:10368000B491FC01E85DF44CC591D49161110DC079 -:103690009FB7F8948C91209582238C93888128235E -:1036A00028839FBFDF91CF910895623051F49FB777 -:1036B000F8943C91822F809583238C93E8812E2B64 -:1036C000EFCF8FB7F894EC912E2B2C938FBFEACFCE -:1036D000CF93DF93EC01ECA5FDA5309709F470C002 -:1036E000138E128E118E108E178A168A82E490E045 -:1036F000958F848F848596EF980F943048F02EEC48 -:10370000280F243028F022EC280F283008F051C070 -:103710002FE030E0378B268B20E430E0318F208F94 -:1037200027E230E0338F228F943050F02EEC280FB8 -:10373000243030F022EC280FB0E0A0E0283010F464 -:10374000A8E6B0E02C91943028F032EC380F3830F5 -:1037500008F443C031E0232B943048F09EEC980FDE -:10376000943028F08E53B0E0A0E0883010F4A8E642 -:10377000B0E02C93248536EF320F343080F18EEC9C -:10378000820F843060F182EC820F883058F190E033 -:1037900080E0948B838B343040F52650330B81E0EE -:1037A00001C0880F2A95EAF7858B848D958D019746 -:1037B000F1F7CF010F9494088CA59DA50F947E0876 -:1037C0008EA59FA5009719F161E00F945D1861E047 -:1037D0008EA5DF91CF910D942C1B34E0BCCF8BE6EE -:1037E00090E0D7CF8DE690E0D4CF88E02233E1F2AD -:1037F00084E02333C9F282E02433B1F282EC820FF9 -:10380000883018F42E53330BCACF81E0CDCFDF912F -:10381000CF910895EF92FF920F931F93CF938C0156 -:10382000C42F79016150673008F045C0E62FF0E001 -:103830008827E25EF34E8E4F0D945C41DA0022023F -:10384000F40078019A0168016202780183E2E80ECF -:10385000F11C005D1F4FF70181917F018F3F49F0FF -:1038600061E00F942C1B61E0F701319780810F9488 -:103870005D18E016F10679F761E084E30F942C1BE4 -:1038800060E084E30F945D1861E083E30F942C1BE8 -:1038900060E083E30F945D1861E085E30F942C1BD7 -:1038A00061E085E30F945D181CBC80E58CBDC230DF -:1038B00010F481E08DBD81E0CF911F910F91FF90B9 -:1038C000EF90089561E0C8010F94221BF4CF4111DD -:1038D00003C041E062E0F7CF40E064E0C8010F942C -:1038E000221B40E0F7CFF80183A160E08F3F19F37E -:1038F000EACF842F0F949A0ADECFF70181917F01DE -:103900000F949A0AC150C111F8CFD5CFF701849115 -:103910000F949A0AFFEFEF1AFF0AC150C111F6CFB8 -:10392000CACF8F929F92AF92BF92CF92DF92EF92C7 -:10393000FF926B017C010F94FF064B015C01C114E7 -:10394000D104E104F104B9F00F94FF066819790974 -:103950008A099B09683E73408105910580F321E047 -:10396000C21AD108E108F10888EE880E83E0981E9B -:10397000A11CB11CE4CFFF90EF90DF90CF90BF90DF -:10398000AF909F908F900895CF92DF92EF92FF9229 -:103990000F931F93CF93DF9300D000D01F921F92FD -:1039A000CDB7DEB77C0118861F8285E08983F701D9 -:1039B00082A98A8360686B835C834D833E832F83F7 -:1039C00067E0CE0101960F94A3068887F70182A5D0 -:1039D00093A5892B31F080A991A9009711F00F943C -:1039E000121B8E010F5F1F4F6E01F9E0CF0ED11C2D -:1039F000F80161918F01C7010F94BD08F70121897A -:103A00003289820F932F911D928B818B0C151D058E -:103A100079F762E070E080E090E00F94911C2896C6 -:103A20000FB6F894DEBF0FBECDBFDF91CF911F91CF -:103A30000F91FF90EF90DF90CF9008952FB7F894FB -:103A400060914F18709150188091511890915218B0 -:103A50002FBF0895CF92DF92EF92FF920F941E1D19 -:103A60006B017C0128E5C20E22E0D21EE11CF11C94 -:103A70000E94C8DD8F3F71F00F941E1D6C197D09E7 -:103A80008E099F0997FDF4CF80E0FF90EF90DF90C3 -:103A9000CF90089581E0F9CF2F923F924F925F929D -:103AA0006F927F928F929F92AF92BF92CF92DF924E -:103AB000EF92FF920F931F93CF93DF93CDB7DEB7B3 -:103AC00061970FB6F894DEBF0FBECDBF1C011C86F8 -:103AD0001B8685E08987F10182A98A876B8763E06D -:103AE000CE0109960F94A3068C87F2E0F98B9E0114 -:103AF000235F3F4F3E872D87F10184A595A5009751 -:103B000061F00F949408C1010F94F3081816190678 -:103B10007CF4C1010F94D808F6CF82A593A5892B18 -:103B200091F380A991A9009771F30F94121BEBCF29 -:103B3000F10186A597A5009741F061E00F945D180B -:103B400061E0F10186A50F942C1B8E01075F1F4FCA -:103B5000F80161918F01C1010F94BD082D853E854B -:103B600002171307A9F7F10186A597A5009719F089 -:103B700062E00F942C1B62E070E080E090E00F9414 -:103B8000911C0F941E1D2B013C018985CB84D12CE7 -:103B9000F12CE12CDD24DA94E82A812C912C5401BB -:103BA00005E010E00F941E1D641575058605970548 -:103BB00031F00150110909F474C02B013C01C1011D -:103BC0000F94D80897FD0FC07A2D692D582D4427E2 -:103BD0004C019924092C000CAA08BB08842A952AB8 -:103BE000A62AB72ABB24C814D904EA04FB04D1F6D8 -:103BF00026013701812C912C54010F941E1D6B015D -:103C00007C0125E030E0388B2F8710E00F941E1DDB -:103C10006C157D058E059F0549F0EF85F889319774 -:103C2000F88BEF87EF2BE9F16B017C01C1010F9459 -:103C3000D808DC0197FD1CC09201A301B401C501A5 -:103C400008E00F947641BB27EB2FEE0FEE0B422ED0 -:103C50004A2A532E5B2A6E2E642A7E2E752A8E2EB9 -:103C6000862A9E2E972AAE2EA82ABE2EB92A1F5F1C -:103C7000153061F6F10186A597A5009741F061E046 -:103C80000F945D1861E0F10186A50F942C1BC10112 -:103C90000F94F3081816190664F4C1010F94D8089C -:103CA000F6CF412C512C612C712C812C912CA12C04 -:103CB000B12CF10184A595A5009711F00F947E0811 -:103CC00062E070E080E090E00F94911CF101178AAF -:103CD0009201A301B401C50108E30F949141298326 -:103CE0009201A301B401C50100E30F9491412A831D -:103CF0009201A301B401C50108E20F9491412B8305 -:103D00009201A301B401C50100E20F9491412C83FB -:103D10009201A301B401C50108E10F9491412D83E3 -:103D20009201A301B401C50100E10F9491412E83DA -:103D30009201A301B401C50108E00F9491412F83C2 -:103D4000488667E0CE0101960F94A306481202C090 -:103D5000411011C081E0F101878BF989F13019F030 -:103D600021E0298BC9CE412C512C612C712C812C46 -:103D7000912CA12CB12C9201A301B401C50108E042 -:103D80000F949141B901CA0161960FB6F894DEBF54 -:103D90000FBECDBFDF91CF911F910F91FF90EF909C -:103DA000DF90CF90BF90AF909F908F907F906F905B -:103DB0005F904F903F902F9008951F920F920FB6F3 -:103DC0000F9211242F933F938F939F93AF93BF93A1 -:103DD00080914F1890915018A0915118B09152189D -:103DE00030914E1823E0230F2D3758F50196A11D71 -:103DF000B11D20934E1880934F1890935018A093A4 -:103E00005118B09352188091531890915418A09162 -:103E10005518B09156180196A11DB11D80935318E5 -:103E200090935418A0935518B0935618BF91AF9122 -:103E30009F918F913F912F910F900FBE0F901F90E8 -:103E4000189526E8230F0296A11DB11DD2CF1F920F -:103E50000F920FB60F9211240BB60F922F933F9330 -:103E60004F935F936F937F938F939F93AF93BF9382 -:103E7000EF93FF938091B900887F803609F44DC09D -:103E800008F040C0883209F4A9C028F5803109F44F -:103E90009DC0C8F4882309F4FBC0883009F496C09B -:103EA000FF91EF91BF91AF919F918F917F916F9112 -:103EB0005F914F913F912F910F900BBE0F900FBECE -:103EC0000F901F901895883109F488C0803241F70F -:103ED0008093831814C0803409F49DC040F480336B -:103EE000B9F38833E9F68093831885ECB0C0803548 -:103EF00009F485C0883509F496C0883489F60F9492 -:103F0000DA1ACECF883909F48CC038F5883729F011 -:103F100050F4883611F0803719F683E080938518C5 -:103F200010924D1857C0883809F47BC0803919F0B9 -:103F3000803809F0B5CF80914D18803208F071C0FB -:103F4000E0914D1881E08E0F80934D188091BB0059 -:103F5000F0E0E35DF74E80833DC0803B39F0E0F454 -:103F6000803A09F479C0883A09F09ACF84E08093C6 -:103F7000851810922C1810922B18E0915918F09176 -:103F80005A18199580912B1881110FC081E08093E8 -:103F90002B1810920B1809C0803C09F4A6CF883C5E -:103FA00009F4A3CF883B09F07BCFE0912C1881E086 -:103FB0008E0F80932C18F0E0E55FF74E80818093A0 -:103FC000BB0090912C1880912B1829C0809160180B -:103FD0008093BB0085EC8093BC0062CF90918218E7 -:103FE00080918118981758F5E091821881E08E0F22 -:103FF00080938218F0E0EF59F74E8081E9CFE0918D -:10400000821881E08E0F809382188091BB00F0E0CF -:10401000EF59F74E808390918218809181189817FC -:10402000C8F285E8D8CFE091821881E08E0F8093A6 -:1040300082188091BB00F0E0EF59F74E80838091A9 -:10404000841881115CCF81E080935F1884EA8093AB -:10405000BC001092851824CF85EC8093BC00109290 -:10406000851880914D18803230F4E0914D18F0E0C1 -:10407000E35DF74E108260914D1870E0E0915718A3 -:10408000F09158188DE298E1199510924D1808CFCB -:104090001092831834CF1F920F920FB60F921124F3 -:1040A0000BB60F922F933F934F935F936F937F9332 -:1040B0008F939F93AF93BF93EF93FF93E091E81794 -:1040C000F091E917309749F0A685B7858585968DDB -:1040D00091FF16C09C918923B1F4FF91EF91BF919C -:1040E000AF919F918F917F916F915F914F913F9190 -:1040F0002F910F900BBE0F900FBE0F901F90189531 -:104100009C91892351F7A389B4899C9185898095D5 -:1041100089238C93868997890197F1F7608D718D3A -:10412000A685B785558538E020E0CB010197F1F7EA -:10413000822F90E095958795282F4C91452309F083 -:104140002068315091F7868D81FD20958091E6178A -:1041500090E001968F7399273091E717381799F0FF -:10416000A091E617B0E0AA55B84E2C938093E617BD -:10417000828D938D0197F1F7A389B4898C919589EC -:10418000892B8C93AACF868D8160868FF1CFDC013D -:1041900015966C931597262F30E050E040E0ED9196 -:1041A000FC910190F081E02D61E11994DC01ED9129 -:1041B000FC910088F189E02D19958F5F0895615079 -:1041C000DC01ED91FC910684F785E02D1994DC016A -:1041D000ED91FC910484F585E02D199583500895A7 -:1041E0006D5FDC01ED91FC910284F385E02D199463 -:1041F000DC01ED91FC910084F185E02D19956115AC -:1042000071058105910539F06F3F7F4F8F4F9F4FAB -:1042100021F080E0089582E0089581E00895CF9232 -:10422000DF92EF92FF921F93CF93DF93EC0190E028 -:1042300080E00F94B63925ED34E045E352E40F9465 -:10424000173A20E030E04AE754E40F94023F6B0154 -:104250007C012AE037ED43EA5CE369857A858B854A -:104260009C850F94083EA70196010F94173A26E605 -:1042700036E646EA5EE30F94023F20E030E040E895 -:104280005FE30F94073E0F947B3F162FE881F9817F -:104290000480F581E02D603108F060C061E0CE015E -:1042A00019952AE037ED43EA5CE369857A858B85C9 -:1042B0009C850F94083EA70196010F94173A2CEEA7 -:1042C00031E548E35EE30F94023F20E030E040E850 -:1042D0005FE30F94073E0F947B3F162F103208F0D8 -:1042E0001FE1912F9F718B81807E892B8B832A8187 -:1042F000382F8C81482F4F7050E0E881F981019070 -:10430000F081E02D60E1CE011995612F70E090E021 -:1043100080E00F94B8392D853E854F8558890F94DC -:10432000173A0F947B3F862F8F716A81607E682BCE -:104330006A83262F3B818C81482F4F7050E0E881A3 -:10434000F9810190F081E02D60E1CE01DF91CF9104 -:104350001F91FF90EF90DF90CF90199460E0CE0115 -:104360001995BCCFDC0196964D935D936D937C932C -:104370009997ED91FC910190F081E02D9A01AB01AC -:1043800060E71994DC01ED91FC910280F381E02D4E -:1043900060E0199562FB882780F908959A01AB01C6 -:1043A000DC0158962C935897632F63705996EC91C3 -:1043B0005997EC7FE62B5996EC935997ED91FC9128 -:1043C0000190F081E02D60E019940F94BB09862FD5 -:1043D0008F700895262F2F70DC0192966C91929722 -:1043E000607F622B92966C93929792962D913D915D -:1043F0004D915C919597ED91FC910190F081E02DAC -:104400006CE61994DC0192964D935D936D937C93C9 -:104410009597ED91FC910190F081E02D9A01AB010F -:104420006CE61994CF93DF93DC01EB01298112969E -:104430009C911297291718F113968C911397821754 -:10444000F0F0E88115968C911597E817C0F43C813F -:1044500016964D915C91291B283018F0480F511D7C -:10446000277081E090E001C0880F2A95EAF7E40FF9 -:10447000F52FF11D2081332329F0822B8083DF91DA -:10448000CF91089580958223F9CFDB01ED91FC91C6 -:1044900019940F931F93CF93DF931F92CDB7DEB77D -:1044A00000914B1610914C16E0917A16F0917B1604 -:1044B00082E0199530E020E04AE0B80189E496E115 -:1044C0000F944522182FE0917A16F0917B1683E025 -:1044D0001995E0917A16F0917B1680E019951123D9 -:1044E000B9F160914B1670914C169E012F5F3F4FB2 -:1044F00046E489E496E10F94452289818093491628 -:1045000060914B1670914C169E012F5F3F4F47E410 -:1045100089E496E10F944522898180934A1660913F -:104520004B1670914C1630E020E048E489E496E1A7 -:104530000F9445228093541660914B1670914C163F -:104540002CE736E147E189E496E10F94452211E03A -:10455000812F0F90DF91CF911F910F910895DF92DE -:10456000EF92FF920F931F93CF93DF93182F062F95 -:10457000C42FD42FF62EF40EEE24E394DD24DA9427 -:104580008F2D8D1BD83090F58C2F887F800F9C2F1E -:1045900096959695969528EF929FC00D1124CC2361 -:1045A000D1F197E0C92760914B1670914C1610938A -:1045B00065168093661681E080936816CF5FC7709A -:1045C0008FEF90E001C0880FCA95EAF780936716D5 -:1045D00025E636E14BE389E496E1DF91CF911F9127 -:1045E0000F91FF90EF90DF900D94452260914B1654 -:1045F00070914C161093651680936616E0926816BB -:10460000D092671625E636E14BE389E496E10F94F4 -:104610004522D850B5CFDF91CF911F910F91FF90D8 -:10462000EF90DF900895AF92BF92CF92DF92EF921A -:10463000FF920F931F93CF93DF93EC01E62EF42E9E -:10464000122F022FD62ED20ECC24CA945C012CE15C -:10465000A20EB11C8D2D801B083070F5812F887F34 -:104660008E0D912F96959695969528EF929F100D09 -:104670001124112371F197E019276A817B818C8FB6 -:10468000FD8E1F8E1F5F17708FEF90E001C0880FA7 -:104690001A95EAF78E8F9E01245E3F4F4BE3CE01C1 -:1046A000DF91CF911F910F91FF90EF90DF90CF900E -:1046B000BF90AF900D9445226A817B818C8FFD8ED7 -:1046C0001F8ECE8E95014BE3CE010F9445220850EC -:1046D000C1CFDF91CF911F910F91FF90EF90DF90AD -:1046E000CF90BF90AF9008950F93CF93C82F01E064 -:1046F00020E8482F60E089E496E10F94A00A88231F -:1047000049F020E84C2F60E089E496E1CF910F91C9 -:104710000D941323CF910F910895FF920F931F9340 -:10472000CF93DF93D82F162FF42EC22F022F242FD2 -:10473000462F682F89E496E10F94A00A882309F197 -:104740002F2D412F6D2F89E496E10F9413234C2FC9 -:10475000612F8D2F0F94AF228FEF8F0D4C2F612F74 -:104760008D0F0F94AF224FEF4C0F410F2F2D6D2F58 -:1047700089E496E1DF91CF911F910F91FF900D9405 -:104780001323DF91CF911F910F91FF900895DF9236 -:10479000EF92FF920F931F93CF93DF937C01162F1D -:1047A000C42FD22ED02F0F94A00A882351F0DC0FF3 -:1047B0002D2D4C2F612FC7010F941323CF5FDC13D6 -:1047C000F7CFDF91CF911F910F91FF90EF90DF9086 -:1047D0000895EF92FF920F931F93CF93DF93C82F0B -:1047E0007B01142FCB010E94B43E26E0C29FE00162 -:1047F0001124112389F091E090936916829F900112 -:1048000011242E5F0CE042E36C2F615089E496E1A5 -:104810000F94C72310926916A7016CE38C2F0E9496 -:10482000C464112319F081E080936916DF91CF9160 -:104830001F910F91FF90EF9008953F924F925F92DA -:104840006F927F928F929F92AF92BF92CF92DF92A0 -:10485000EF92FF920F931F93CF93DF931F921F92BC -:10486000CDB7DEB75C01680181E0809340094090DC -:104870003B0950903C0960903D0970903E094114FD -:1048800051046104710479F091E0141415040CF0E2 -:1048900090E090933A0910923B0910923C091092D3 -:1048A0003D0910923E0910913A0930903F0910924B -:1048B0003F09311005C080917502882309F470C04A -:1048C00049012A013B01C9010E94B43E082F80E042 -:1048D000E114F10419F0C7010E94B43E1A82198252 -:1048E000C114D104B1F4402F50E0282F30E0CA01A8 -:1048F000820F931F46976CF485E190E0841B950B23 -:10490000821B930B97FD0196959587958A8381E08D -:10491000898301E021EA34E2A401BE016F5F7F4F89 -:10492000CE0102960E94D840C114D10491F08A8130 -:10493000882321F01A8289818F5F898300E024EA2D -:1049400034E2A601BE016F5F7F4FCE0102960E9446 -:10495000D840E114F10459F000E021EA34E2A70163 -:10496000BE016F5F7F4FCE0102960E94D84041E0AA -:104970004127B30181E00F94E923C5010E94B43EB1 -:10498000412FB50194E1981B892F0F94E92333201F -:1049900039F01123C9F041145104B1F0F201199515 -:1049A0000F900F90DF91CF911F910F91FF90EF909B -:1049B000DF90CF90BF90AF909F908F907F906F903F -:1049C0005F904F903F9008950E946C2EE9CFEF9238 -:1049D000FF921F93CF93DF93EC01EE85FF85309715 -:1049E00009F01995EA80FB80E9A9FAA982E01995F6 -:1049F000E9A9FAA981E0199530E020E045E1B70185 -:104A0000CE010F944522182F882341F09E012D5C82 -:104A10003F4F47E1B701CE010F944522E9A9FAA91A -:104A200080E01995812FDF91CF911F91FF90EF903A -:104A30000895DC0114968D919C9115978617970720 -:104A400009F43CC015967C936E931497611571051B -:104A500079F157968C915797FB01811130C03596AB -:104A6000E4915896EC935897645F7F4FFB016491F3 -:104A700059966C93599758968C915897082E000C1C -:104A8000990B59962C915997821B910927FD939563 -:104A90005A962C915A97203441F0829FC0011124DC -:104AA00026E0969587952A95E1F75B968C935B9720 -:104AB00082E192E056969C938E93559708958130AB -:104AC00041F43F96E4915896EC935897605F7F4F7E -:104AD000CDCF3D96E4915896EC935897625F7F4F07 -:104AE000C5CF5F926F927F928F929F92AF92BF924B -:104AF000CF92DF92EF92FF920F931F93CF93DF93AA -:104B0000EC01562E142F622F0F94FD096C0180E0EA -:104B1000C114D104B1F08C819D810F94F309B82E9A -:104B2000FB88EC888989580E1E198A89181B0E2D5E -:104B30002F2D412F652DCE010F94A00A811111C098 -:104B40008889DF91CF911F910F91FF90EF90DF90B7 -:104B5000CF90BF90AF909F908F907F906F905F901D -:104B60000895CB0CD11C87E0F80EF694F694F694D9 -:104B7000E10E4E01ECE18E0E911C6F2C712C1E1576 -:104B8000F9F2052D560111C0F50184916A817B81EE -:104B90000C8F1D8F1F8E8E8F94014BE3CE010F94CF -:104BA0004522FFEFAF1ABF0A085F8A2D8C198F15B7 -:104BB00058F3C60CD71C1F5FE2CFFF920F931F93D1 -:104BC000CF93DF93D82FF62E8A01E0915E16F091F5 -:104BD0005F1689E496E11995F80EC0E0F80124917A -:104BE000222359F04F2D6D2F89E496E10F94712502 -:104BF000D80FC80F0F5F1F4FF1CF8C2FDF91CF91D0 -:104C00001F910F91FF900895DB011496ED91FC9197 -:104C100030E020E065E01994DB011496ED91FC9101 -:104C200030E020E062E01994DB011496ED91FC91F4 -:104C300030E020E063E01994CF92DF92EF92FF9290 -:104C40000F931F93CF93DF938C017B016A0180E068 -:104C5000F601C491811110C081E0CF3F49F04C2F83 -:104C6000B701C8010F940426882309F444C080E0EA -:104C7000BFEFCB1ADB0AECCF4FEFCF3F89F3CE3F2C -:104C8000D9F1C03FA0F7C03E38F04C2F4F70B701AC -:104C9000C8010F940C26EBCFC03D38F04C2F4F705D -:104CA000B701C8010F941426E2CFC03CF8F0D70139 -:104CB0001496ED91FC9130E020E040E064E0C80102 -:104CC0001995C295C07FCE5FD0E0CE010F94E60962 -:104CD000D7011496ED91FC9130E020E041E064E0D2 -:104CE000C8011995CE010F94E609C1CFC7FDBFCF0A -:104CF0008C2F90E0F8CF80E0DF91CF911F910F9142 -:104D0000FF90EF90DF90CF9008954F925F926F9257 -:104D10007F928F929F92AF92BF92CF92DF92EF924B -:104D2000FF920F931F93CF93DF93EC01562E142F16 -:104D3000622E402E220F220F220F0F94A00A8823EA -:104D400021F1410E4E018CE1880E911CA62CB12C54 -:104D50006701762C052D12C0F60184916A817B8152 -:104D60000C8F1D8F1F8E8E8F94014BE3CE010F94FD -:104D70004522FFEFCF1ADF0A7A94085F7110ECCF5B -:104D8000EA0CFB1C1F5F4112E3CFDF91CF911F9113 -:104D90000F91FF90EF90DF90CF90BF90AF909F90DA -:104DA0008F907F906F905F904F900895CF93DF9397 -:104DB000EC018991882319F00E949FCEFACFDF91F0 -:104DC000CF9108950E94E0DD8AE00C949FCE1F935E -:104DD000CF93DF93182FEB010E940FD886EC97E357 -:104DE0000E94ACCE82EB97E3113011F488EB97E38D -:104DF0000E94ACCEBE018EEB97E3DF91CF911F9165 -:104E00000D94E2268BE1E4EAF4E1A9E8B4E1019033 -:104E10000D928A95E1F78091A21780648093A21782 -:104E2000109297170895EF92FF920F931F93CF93CD -:104E3000DF93CDB7DEB7A7970FB6F894DEBF0FBEEE -:104E4000CDBF8091A21784FF0E948F7E8091A21710 -:104E500084FF58C08091981790E08F969F938F930E -:104E60008BEC97E39F938F938E01045E1F4F1F93EC -:104E70000F930F9448398091A2170F900F900F90C5 -:104E80000F900F900F9084FBFF24F0F884FF3AC03E -:104E90001FA21EA2A801BE016A5D7F4F80E00F9491 -:104EA000BD0C009779F119821C826EA17FA121E0CF -:104EB000AC01CE0101960E946A80E82E882321F081 -:104EC000CE0101960E945E7ECE0101960E94648012 -:104ED000EE20C1F00F940227C8010E949B798091B7 -:104EE00098178F5F809398178F2DA7960FB6F89419 -:104EF000DEBF0FBECDBFDF91CF911F910F91FF900D -:104F0000EF90089510929817F12CEECF0F931F9306 -:104F1000CF93DF9300D01F92CDB7DEB79C010AE894 -:104F200016E090E1E6E7F2E0D80101900D929A9543 -:104F3000E1F7F9012081318142815381F8016085D7 -:104F40007185828593850F94083EF801608771878B -:104F50008287938780E090E0A0EAB0E489839A8317 -:104F6000AB83BC83CE0101960E94E3B40F900F90F7 -:104F70000F900F90DF91CF911F910F910895109294 -:104F8000F8181092F71888EE93E0A0E0B0E0809354 -:104F9000F9189093FA18A093FB18B093FC1889E9BC -:104FA00093E09093F6188093F5181092A414109241 -:104FB000A7141092891410928C14E9E8F6E187E99D -:104FC00097E1108213827B968E179F07D1F78BEAA9 -:104FD00093E090930219809301191092031989E1CB -:104FE000809305191092081910928214109250148F -:104FF0001092531448E250E06FE370E08FEA95E1BD -:105000000F9457291092E2151092E3158091E41540 -:10501000807F8093E4151092E5151092E7151092A9 -:10502000E6151092E9151092E8151092EA1589EC30 -:1050300093E09093B0158093AF154BE350E060E49C -:1050400070E083E795E10F9457291092A61510920E -:10505000A7158091A815807F8093A8151092A91597 -:105060001092AB151092AA151092AD151092AC15B6 -:105070001092AE1589EC93E090937415809373159C -:105080004AE250E061E470E087E395E10F9457292C -:1050900010926A1510926B1580916C15807F809329 -:1050A0006C1510926D1510926F1510926E1510926E -:1050B0007115109270151092721589EC93E090930F -:1050C0003815809337154CE250E062E470E08BEFC6 -:1050D00094E10F94572910922E1510922F1580915C -:1050E0003015807F80933015109231151092331552 -:1050F0001092321510923515109234151092361503 -:1051000089EC93E09093FC148093FB1444E150E00D -:105110006CE070E08FEB94E10F9457291092F21439 -:105120001092F3148091F414807F8093F414109201 -:10513000F5141092F7141092F6141092F9141092BC -:10514000F8141092FA1489EC93E09093C0148093B1 -:10515000BF141092EB151092EC151092ED151092F1 -:10516000EE151092EF151092F4151092F51510929D -:10517000F6151092F7151092F8151092FD15109271 -:10518000FE151092FF151092001610920116109243 -:105190002B1610922C1610922D1610922E1610927D -:1051A0002716109228161092291610922A1610927D -:1051B000231610922416109225161092261610927D -:1051C0001F1610922016109221161092221610927D -:1051D0000B1610920C1610920D1610920E161092BD -:1051E0000A161092091610920816109207161092BD -:1051F000061684E0809332161092301610922F1605 -:10520000109231168DEC94E69093441680934316D9 -:10521000109248161092471687EE93E09093461628 -:10522000809345168FEF8093861680938716809320 -:10523000881680938316809384168093851681E068 -:1052400099E19093A4178093A3178091A217847E6D -:105250008B7F8093A21710929E1710929F17109227 -:10526000A0171092A11710929A1710929B171092E4 -:105270009C1710929D1710929917109298171092E0 -:105280009717E9E8F6E18EE091E0DF019C011D92BD -:1052900021503040E1F780910A018E7F80930A010E -:1052A00080910B0180958170809309010895CF92C0 -:1052B000DF92EF92FF920F931F93CF93DF93EC0156 -:1052C0008B016A011A821B828C81807F8C831D82F4 -:1052D0001E821F828885807F88878EEA97E4A1EEF0 -:1052E000BDE389879A87AB87BC8740E050E060E0E8 -:1052F0007FE34D875E876F87788B29EC33E03983B6 -:1053000028831A8A198A8B8B9C8BAD8BBE8B1F8A44 -:10531000188E898D8C7F898F1A8E8B8D807F8B8FD5 -:105320001D8E1C8E1E8E1F8E18A219A21AA21BA2E1 -:105330001CA21DA21EA21FA218A619A61BA61AA671 -:105340001DA61CA690E080E00C151D0511F4902F01 -:10535000812F9EA78FA719AA18AA1AAA8FE190E0F9 -:105360000F9422347C01DC0113961C921E9212973A -:1053700088EE93E0A0E0B0E0F70184839583A683F4 -:10538000B78387E893E091838083178A168A118E0A -:10539000108E138E128E158E148E668D6E7F6D7F1D -:1053A000668F6695617081E068278C2D0F945D187B -:1053B00061E08C2D0F942C1BF601E857F44CE4911E -:1053C000D7015096EC93F601EE5BF44CE491F0E0DB -:1053D000EE0FFF1FE85DF44C85919491F701928BDD -:1053E000818B60E0802F0F942C1BD7015E968C91EF -:1053F00081FD04C061E0802F0F945D18F7010487E0 -:10540000F801E857F44CE491D7011D96EC93F801AC -:10541000EE5BF44CE491F0E0EE0FFF1FE25FF44C22 -:1054200085919491F70197878687FDA6ECA6888DD4 -:1054300081608D7F8B7F888F898D8160898F8C8142 -:10544000807F81608C8384E18D8383E590E0A0E0A0 -:10545000B0E18AA39BA3ACA3BDA384E290E0ADE03E -:10546000B1EC8EA39FA3A8A7B9A7DF91CF911F91FD -:105470000F91FF90EF90DF90CF900895CF93DF933F -:10548000CDB7DEB7CF54D1090FB6F894DEBF0FBE4B -:10549000CDBF789484B5826084BD84B5816084BDBD -:1054A00085B5826085BD85B5816085BD80916E00C2 -:1054B000816080936E0010928100809181008260F3 -:1054C0008093810080918100816080938100809130 -:1054D00080008160809380008091B100846080931F -:1054E000B1008091B00081608093B0008091910004 -:1054F00082608093910080919100816080939100FF -:10550000809190008160809390008091A1008260E2 -:105510008093A1008091A10081608093A10080917F -:10552000A00081608093A00080912101826080931F -:1055300021018091210181608093210180912001CE -:1055400081608093200180917A00846080937A004A -:1055500080917A00826080937A0080917A008160E5 -:1055600080937A0080917A00806880937A0010920C -:10557000C10040900F194BA614BE1092C00080913C -:10558000C00082608093C0001092C50087E08093C5 -:10559000C4008091C10080618093C1008091C100EE -:1055A00088608093C1008091C10080688093C100B1 -:1055B0000F941E1D6B017C0128EEC20E23E0D21E4B -:1055C000E11CF11C8BE89FE00E949CCD882309F42C -:1055D0009DC089E99AE30E94ACCE9898A09A8091E8 -:1055E0006F0390917003A0917103B091720389A32E -:1055F0009AA3ABA3BCA3AE014F5D5F4F59AF48AFB9 -:10560000CE0185969EA38DA3C12CA4E2DA2EA4EF31 -:10561000EA2EF12CA8ADB9AD6D91B9AFA8AFCE010E -:1056200001960E949ECD8A89811190C18989882323 -:1056300009F48CC14F844FA6242D0FEF10E02230C7 -:1056400011F00FEF1FEF49805A805BAE4AAE6B80BE -:105650007C807EA66DA68EE0E3E7F3E0DE01539644 -:1056600001900D928A95E1F72FA5223009F057C0DD -:1056700031E023963FAF239743E024964FAF249722 -:10568000CE01439622969FAF8EAF229791E09CA7C2 -:10569000A1E0A8AB1DAAEFEFF0E0FFABEEAB2DEF62 -:1056A00030E038A72FA32296AEADBFAD22972D9044 -:1056B0003D902296BFAFAEAF2297BFA5B230C1F1E9 -:1056C000E0E22E16310409F413C1F0E82F1631047C -:1056D00009F40EC1E8EE4E2EE3E05E2E249C90010C -:1056E000259C300D349C300D112450E040E0C70162 -:1056F000B6010F94C63DC9010197369527950097CD -:10570000C9F441E050E05AAB49AB1BC00F941E1DD9 -:105710006C197D098E099F0997FDF8CF5ACF5AE081 -:1057200023965FAF23976EE024966FAF2497A8CFA0 -:105730009801C8011AAB09AB8017910710F49AAB16 -:1057400089AB2115310509F485C21CAB0BAB2017C1 -:10575000310710F43CAB2BAB4FA058A429EE4216F6 -:1057600023E0520608F47BC2C20128EE33E0821B1C -:10577000930B2C01712C612C4CAE5DAE6EAE7FAEE6 -:1057800089A99AA90196829D9001839D300D929DD1 -:10579000300D112450E040E0C701B6010F94C63D22 -:1057A00049015A0129013A0128EE821623E09206A6 -:1057B000A104B10430F478EE472E73E0572E612C2B -:1057C000712CD501C40139EE831633E09306A10490 -:1057D000B10420F088EE93E0A0E0B0E0A3019201D4 -:1057E000281B390B4A0B5B0B2C962CAF3DAF4EAFF1 -:1057F0005FAF2C97C101880F991F4BA85CA8849DAF -:105800009001859D300D949D300D112450E040E0B5 -:10581000C701B6010F94C63D60962CAF3DAF4EAFA9 -:105820005FAF6097283E63E036074105510550F4AD -:1058300088EE93E0A0E0B0E060968CAF9DAFAEAF95 -:10584000BFAF609728962CAF3DAF4EAF5FAF2897A4 -:10585000293E93E039074105510560F058EE452E89 -:1058600053E0552E612C712C28964CAE5DAE6EAE79 -:105870007FAE289760968CAD9DADAEADBFAD609705 -:1058800028964CAC5DAC6EAC7FAC2897841995091A -:10589000A609B70928968CAF9DAFAEAFBFAF2897CA -:1058A0004CAC5DAC6EAC7FAC2C968CAD9DADAEAD12 -:1058B000BFAD2C9784159505A605B70508F0D4C192 -:1058C00028964CAC5DAC6EAC7FAC28974816590658 -:1058D0006A067B0608F4C8C198A68FA224965FAC1E -:1058E000249758AA6CA46DAA89A89AA89FAA8EAAE0 -:1058F0002CA52F5F2CA7283009F0D5CEAAADBBADC3 -:105900008C918C7F98A99370892B8C93EDA5FEA523 -:10591000208148A8842D90E0959587959595879549 -:1059200043E0880F991F4A95E1F7277E822B8083F9 -:105930008081887F5DA8852980832FA5223031F062 -:10594000ED85FE854EA85FA8518240826DA07EA0A5 -:1059500088AC99AC6814790409F05CCE8FEA95E1C3 -:105960000F94681B83E795E10F94681B87E395E12B -:105970000F94681B8BEF94E10F94681B8FEB94E1FD -:105980000F94681B9BA490FE04C080E99AE30E94D8 -:10599000ACCEABA4A1FE04C08FE79AE30E94ACCECC -:1059A000BBA4B2FE04C08DE69AE30E94ACCECBA4A9 -:1059B000C3FE04C08CE59AE30E94ACCEDBA4D5FE06 -:1059C00004C08BE49AE30E94ACCE8BE39AE30E947E -:1059D000ACCE0E940FD88DE09AE30E94ACCE0E941C -:1059E0000FD885EF99E30E94ACCE0E940FD880912A -:1059F000091990910A199E012F5F3F4F5901B90172 -:105A0000009709F44EC1681B790B86EE99E30E945A -:105A100087DA60ED75E08FEC99E30E9404DB389A39 -:105A200040981092CB081092CC081092CD0810929A -:105A3000CE0810925C1810925B181092AC1810925D -:105A4000AB180F94971984E892E090935A188093BA -:105A5000591884E991E0909358188093571840E0C2 -:105A600060E080E00F94D6190E94594080915D1843 -:105A7000811107C00E940FC5882319F081E080932F -:105A80005D1885E496E10E94126B2AE4E22E28E379 -:105A9000F22E03E127E047E064E289E496E10F9407 -:105AA000852683E00E94AA3F42E458E36BE28BE242 -:105AB0000E94C46445E358E367E38CE10E94C46438 -:105AC00089E496E10F94E7248111DFCF0F941E1D26 -:105AD0002B013C012091E6083091E7084091E8084D -:105AE0005091E90860917602709177028091780276 -:105AF000909179020F94083E60937602709377023A -:105B000080937802909379022091EA083091EB0813 -:105B10004091EC085091ED0860917A0270917B02FF -:105B200080917C0290917D020F94083E60937A02EE -:105B300070937B0280937C0290937D022091EE080B -:105B40003091EF084091F0085091F10860917E0289 -:105B500070917F0280918002909181020F94083EA3 -:105B600060937E0270937F02809380029093810203 -:105B70000E947BB5249A2C988091010180618093CA -:105B800001018091020180718093000180910101E7 -:105B900080628093010180910201807280930001F4 -:105BA0009D9A8091010180648093010187ED80932B -:105BB0007A0010927E0010927D0080917D008062BC -:105BC00080937D0080917D00806880937D0080912E -:105BD0007D00806480937D0080E887BD80916E00A9 -:105BE000826080936E000DEC19E3F801C590D490AB -:105BF00035E0C316D1041CF495E0C92ED12CD09207 -:105C00006902C09268020D2C000CEE08FF0860E0EB -:105C100080916402909165020E9451836FA378A7DE -:105C200089A79AA7C701B6010F94B8399B01AC01A7 -:105C30006FA178A589A59AA50F94B13987FF34C0C3 -:105C400080916402909165024097909365028093E1 -:105C50006402DDCF81E090E09CAB8BAB7DCD2FA1CA -:105C600038A588EE93E083CD4CAC5DAC6EAC7FACD8 -:105C700028968CAC9DACAEACBFAC28978414950430 -:105C8000A604B70408F034CE38A72FA323969FAC00 -:105C9000239798AAACA4ADAA4BA85CA85FAA4EAA69 -:105CA00027CE6F507941B1CE81ED882E88E3982EB2 -:105CB000F401C590D49041E0C41AD10855E0C5164E -:105CC00051E0D50624F0B4E0CB2EDD24D394D0925D -:105CD0006B02C0926A020D2C000CEE08FF0860E017 -:105CE00080916602909167020E9451836FA378A70A -:105CF00089A79AA7C701B6010F94B8399B01AC01D7 -:105D00006FA178A589A59AA50F946840181654F438 -:105D1000809166029091670240969093670280930B -:105D20006602DDCFF801C590D49065E0C616D104B7 -:105D30001CF4A5E0CA2ED12CD0927102C092700240 -:105D40000D2C000CEE08FF0861E080916C02909130 -:105D50006D020E9451836FA378A789A79AA7C701F4 -:105D6000B6010F94B8399B01AC016FA178A589A544 -:105D70009AA50F94B13987FF0AC080916C02909167 -:105D80006D02409790936D0280936C02DDCFF40119 -:105D9000C590D49081E0C81AD10895E0C91691E069 -:105DA000D90624F0F4E0CF2EDD24D394D0927302F0 -:105DB000C09272020D2C000CEE08FF0861E0809189 -:105DC0006E0290916F020E9451836FA378A789A7FA -:105DD0009AA7C701B6010F94B8399B01AC016FA116 -:105DE00078A589A59AA50F946840181654F4809157 -:105DF0006E0290916F02409690936F0280936E02B4 -:105E0000DDCF80916202909163020E94E98520E0DB -:105E100030E040EA50E40F94B13987FF0AC0809126 -:105E200062029091630240979093630280936202B2 -:105E3000E8CF8091CF089091D0080E94E98520E0BA -:105E400030E04CED52E40F946840181654F4809101 -:105E5000CF089091D00840969093D0088093CF08B7 -:105E6000E8CF0E948BBB19A282E390E09C8B8B8BC6 -:105E70001A82198201E0950141E050E0BE016F5D98 -:105E80007F4FCE0143960E9461CE89A1863109F4ED -:105E90003EC10E94DE8E81E08093D1088091040192 -:105EA0008D7F80930401809105018095827080939D -:105EB000030153985B9A6C98749A1092E3081092BD -:105EC000E2080E9471B9819A879A80910A018260E2 -:105ED00080930A010E9A3B9A579A5F9A829A8A9AFD -:105EE000809107018160809307018091080180956E -:105EF0008170809306010A9A129A3F9A479A809A73 -:105F000088985F9A8091E4088E7F8093E408869A4F -:105F10008E988A9A8091E4088D7F8093E40880911E -:105F20000A01886080930A0180910B018870809338 -:105F3000090180910801809581708093060180910C -:105F4000E4088B7F8093E40880E090E0A6E1B3E46E -:105F500080937E0290937F02A0938002B09381028F -:105F60000E947BB50C9A1498129A399A4198479AD4 -:105F7000809180008C7F8093800080918100877E5B -:105F8000886080938100809180008F73809380006F -:105F900080918100887F82608093810080E090E41E -:105FA000909389008093880010928500109284005D -:105FB0000E944995789487E08093E5080E945A886A -:105FC00088E198E20FB6F894A895809360000FBE20 -:105FD000909360000F941E1DDC01CB01841995097C -:105FE000A609B709803AEFE09E07A105B10570F454 -:105FF00000EA1FE020E030E028013901481A590A80 -:106000006A0A7B0AC301B2010E9421CD21E041E06E -:1060100061E081E00E94FEDB83E080933509212C62 -:10602000E2E03E2E71E6972E6AE0862E80E00E9426 -:10603000EADD8091A21787FF21C010929817877F11 -:106040008B7F8093A2170E94677E10927710109228 -:106050007610109275100E9439B880E00E9416BB2D -:106060000E94B4850E9497CD1092740250EA652E6A -:106070005AE3752E7092F3086092F2088091350908 -:10608000CDB6DEB610E000E0843009F452C0ADB603 -:10609000BEB66091F2087091F30810E000E061155F -:1060A000710509F08DC08091F408882309F42BC193 -:1060B000E4EFF8E08F01045F1840F190FF2019F041 -:1060C0003AE0F312F7CF0115110559F0F801EC5041 -:1060D000F74F108284EF98E00E9457C880E00E943A -:1060E000D1EB81E0F11001C080E0080F802FE82F94 -:1060F000F0E0EC50F74F9081E82FE01BF0E0EC501F -:10610000F74F9083992309F498C08F5FF0CF83E312 -:1061100090E09C8B8B8B1A82198201E0950140E103 -:1061200050E062ED78E0CE0143960E9461CEB3CE9E -:106130008C01F801EC55F54CE491C8010196EE2371 -:1061400011F0EA30A9F7ADB6BEB6A81AB90A0FB673 -:10615000F894BEBE0FBEADBE2DB73EB72F5F3F4F0A -:106160007901A80164EA7AE3C9010F94DF38F701E5 -:10617000E00FF11F1082D7018C918B3331F40FB6F1 -:10618000F894DEBE0FBECDBE82CF809175108430F4 -:10619000B0F780917710899DC0011124B70188580C -:1061A0009F4E0F94ED4181E00F941C0F0FB6F894B1 -:1061B000DEBE0FBECDBEB3E0B093350968CF860119 -:1061C000FB01E00FF11F74906801EFEFCE1ADE0AB9 -:1061D000772019F0FAE07F12F2CF4DB65EB64C1878 -:1061E0005D080FB6F8945EBE0FBE4DBE2DB73EB72C -:1061F0002F5F3F4F7901A801C9010F94DF38F701E4 -:10620000E00FF11F1082772009F47AC08091F20824 -:106210009091F308C80ED91ED092F308C092F208EC -:10622000012B31F0C7010E9457C880E00E94D1EBDA -:106230000FB6F894BEBE0FBEADBE909134098091EA -:106240005E18981709F4F2CE8091340980935E1895 -:1062500080913409882309F4E7CE0E940FD88FEF8C -:106260009AE30E94ACCE8091340910E280FF0AC00C -:1062700080E00E94AFB2AB01BC018BEF9AE30E94B9 -:10628000A4CF18E58091340900E281FF0AC081E0C3 -:106290000E94AFB2AB01BC0187EF9AE30E94A4CF8A -:1062A00009E58091340982FF2CC282E00E94AFB2DE -:1062B000AB01BC0183EF9AE30E94A4CF9AE5F92ECB -:1062C0008AE00E949FCE1F9280E28F931F92FF92DE -:1062D0001F920F931F921F938BED9AE39F938F93BF -:1062E00084EE9AE39F938F931F920E94FA3AEDB740 -:1062F000FEB73D960FB6F894FEBF0FBEEDBF92CE2F -:10630000D12CC12C89CF80917510882309F495CFA9 -:106310008091A21780FFEFC100917610099D800146 -:10632000112408581F4E67ED7AE3C8010F942E39E7 -:10633000009739F0DC0113968C9180538A3008F075 -:10634000C5C1F80101900020E9F731977F01E01AFB -:10635000F10A109250146EE470E0C8010F94E2410B -:106360006C01009709F085C0B1E0EB1AF108F80163 -:10637000EE0DFF1D4DE0442E418282821382F80112 -:1063800001900020E9F731976F01C01AD10A80917E -:106390005314813009F069C08091511481FF65C0A8 -:1063A00082FF1CC04091611450916214609163148B -:1063B000709164148091581490915914A0915A14BA -:1063C000B0915B1484179507A607B70739F080E5ED -:1063D00094E10E94827C882309F447C040915814BC -:1063E0005091591460915A1470915B14C114D104E6 -:1063F00009F427C18091691490916A14DC01149604 -:106400007C902FEF270D2A013B0139E076946794A9 -:10641000579447943A95D1F742227A01B1E0FB2292 -:10642000411057C0E114F10409F053C040915414D5 -:10643000509155146091561470915714411551059F -:106440006105710529F58091651490916614A091FC -:106450006714B09168140097A105B10591F580E526 -:1064600094E10E94647F811134C081E080935014D4 -:106470000DC160E270E00F94E2418C010F5F1F4F8D -:106480006AE270E0C6010F94E241FC01319772CFDD -:106490009E012F5F3F4F0E94457B882331F3898106 -:1064A0009A81AB81BC81E0916914F0916A142789CB -:1064B000203109F085C0883FEFEF9E07A105B105A7 -:1064C00070F68093541490935514A0935614B0937F -:1064D00057145101AE18BF08CA14DB0408F4560162 -:1064E000E0916914F0916A148091541490915514BC -:1064F000A0915614B09157140297A109B1092585AE -:1065000004C0880F991FAA1FBB1F2A95D2F7468582 -:10651000578560897189840F951FA61FB71F9C013D -:10652000AD01240D311D411D511D29013A01A11458 -:1065300032E0B30609F04DC08091451490914614A5 -:10654000A0914714B0914814481659066A067B0674 -:1065500069F410924D148FEF9FEFDC018093451486 -:1065600090934614A0934714B093481480914E140E -:1065700090914F14DC01ED91FC910288F389E02D9C -:106580009801B301A2011995882309F46ECF809177 -:10659000581490915914A0915A14B0915B148A0D1B -:1065A0009B1DA11DB11D8093581490935914A09365 -:1065B0005A14B0935B140A0D1B1DCA18DB080ECFCA -:1065C000883FFFEF9F07AF07FFE0BF0708F479CFD1 -:1065D00046CFE114F10469F54091581450915914D3 -:1065E00060915A1470915B148091611490916214BF -:1065F000A0916314B0916414481759076A077B0788 -:10660000C0F00E94287A882309F42FCF81E080937C -:106610004D14409245145092461460924714709263 -:106620004814A501B801C7018B5B9D4E0F94C6416C -:10663000AECF41E0C301B2010E94717A8111F1CF66 -:1066400014CF8091611490916214A0916314B09161 -:10665000641484179507A607B70768F4809151144E -:1066600040936114509362146093631470936414A4 -:106670008068809351148091511483FF07C080E596 -:1066800094E10E94297E882309F4EFCE8091501472 -:10669000882331F00E940BD88DEA9AE30E94ACCE99 -:1066A0008091A21781FD27C0E09176109E9EF00197 -:1066B0001124E852FF4E8081811110C08AEA9AE3CA -:1066C0000E94ACCE8AE00E949FCE08C00F945F1259 -:1066D00084EC9AE30E94ACCE0E9491CF8091761018 -:1066E0008F5F843058F480937610809175108150BC -:1066F00080937510A2CD0F948506F0CF109276107E -:10670000F4CF80E2F82EDCCDCF93DF93EC012A8129 -:106710003B818C81482F4F7050E0E881F9810190D6 -:10672000F081E02D60E1CE0119956D81CE010F94CD -:10673000C7202E813F818885482F4F7050E0E88127 -:10674000F9810190F081E02D63E1CE011995488D2A -:10675000898D582F537070E060E0CE010F94CE21E8 -:106760002A8D8B8D382F3F7022273F702A8F932FD1 -:106770009F70807F892B8B8F50E040E0E881F9810A -:106780000190F081E02D63E0CE0119952E8D3F8DB3 -:1067900048A159A1E881F9810190F081E02D62E2E0 -:1067A000CE0119954AA15BA16CA17DA1CE010F94E8 -:1067B00002224EA15FA168A579A5CE010F94B22156 -:1067C0002BA93CA98DA9482F4F7050E0E881F98191 -:1067D0000190F081E02D64E1CE0119952EA930E001 -:1067E00050E040E0E881F9810190F081E02D60E423 -:1067F000CE0119952FA938AD50E040E0E881F9812C -:106800000190F081E02D62E4CE01DF91CF911994E7 -:10681000CF93DF9380E594E10E946480C7E9D7E1DC -:106820006B97CE010E94648086E1C938D807C1F712 -:1068300089E894E10E94648084EA94E1DF91CF9139 -:106840000C9464800F931F93CF93DF938230910554 -:1068500010F482E090E0E0910B19F0910C1930E017 -:1068600020E0B0E0A0E0309799F42115310509F45B -:106870004AC0281B390B24303105D8F58A819B8109 -:106880006115710589F1FB0193838283FE0111C0BB -:10689000408151810281138148175907E0F0481760 -:1068A000590799F4109761F012960C93129713966A -:1068B0001C933296CF01DF91CF911F910F910895D4 -:1068C00000930B1910930C19F4CF2115310551F0D9 -:1068D0004217530738F0A901DB019A01BD01DF011E -:1068E000F801C1CFEF01F9CF90930C1980930B19E8 -:1068F000CDCFFE01E20FF31F819391932250310916 -:1069000039832883D7CF2091091930910A19232B75 -:1069100041F4209188023091890230930A19209322 -:10692000091920918602309187022115310541F421 -:106930002DB73EB740918A0250918B02241B350B34 -:10694000E0910919F0910A19E217F307A0F42E1B40 -:106950003F0B2817390778F0AC014E5F5F4F2417C3 -:10696000350748F04E0F5F1F50930A1940930919DD -:10697000819391939FCFF0E0E0E09CCFCF93DF93A2 -:106980000097E9F0FC01329713821282A0910B1953 -:10699000B0910C19ED0130E020E01097A1F42081B6 -:1069A0003181820F931F2091091930910A192817FC -:1069B000390709F061C0F0930A19E0930919DF91D2 -:1069C000CF910895EA01CE17DF07E8F54A815B8190 -:1069D0009E0141155105B1F7E901FB83EA83499115 -:1069E0005991C40FD51FEC17FD0761F48081918187 -:1069F0000296840F951FE901998388838281938190 -:106A00009B838A83F0E0E0E012968D919C9113972E -:106A10000097B9F52D913C911197CD010296820F07 -:106A2000931F2091091930910A192817390739F64F -:106A3000309751F510920C1910920B19B0930A1956 -:106A4000A0930919BCCFD383C28340815181840FA5 -:106A5000951FC817D90761F44E5F5F4F88819981F0 -:106A6000480F591F518340838A819B81938382837E -:106A70002115310509F0B0CFF0930C19E0930B19F3 -:106A80009ECFFD01DC01C0CF13821282D7CF8F923F -:106A90009F92AF92BF92CF92DF92EF92FF920F93AD -:106AA0001F93CF93DF935C017B016115710519F092 -:106AB000DB018D939C9385010F5F1F4FF501D08102 -:106AC0008D2F90E00F94D6386C01892BB9F5DD320B -:106AD000B9F50F5F1F4FD5011196DC91C1E0580148 -:106AE000F1E0AF1AB10843E050E064E275E0C5019F -:106AF0000F940739892B69F5680182E0C80ED11C13 -:106B000045E050E06FE175E0C6010F940739892B2D -:106B100021F4680197E0C90ED11CE114F10419F0C9 -:106B2000D701CD92DC9260E070E080E89FEFC11168 -:106B3000FFC060E070E080E89FE7FAC05801BBCF7B -:106B4000DB3229F485010E5F1F4FF501D181C0E0D2 -:106B5000C6CF43E050E06CE175E0C5010F94073902 -:106B6000892BE9F0F80110E000E020E030E0A90115 -:106B70005F01B0ED8B2E8D0E89E08815C8F19C2E3B -:106B8000689491F88C2F8870C2FF16C0811102C0E2 -:106B90000F5F1F4F3196D501DC91C92DE9CFE1146C -:106BA000F10429F00E5F1F4FF7011183008360E0AD -:106BB00070E080EC9FE7BCC0882311F00150110900 -:106BC000A5E0B0E00F94E53D9B01AC01220F331F1F -:106BD000441F551F280D311D411D511D283999E9AC -:106BE0003907490799E15907A8F2C6609C2ED2CF10 -:106BF000AEEF8A1206C0C3FD3CC09C2E689493F889 -:106C0000C9CFDF7DD534A9F580818D3239F4C061DB -:106C1000DF011296818162E070E006C0DF018B32F5 -:106C2000C1F3119661E070E080535D01A61AB70AC6 -:106C30008A30F8F4E0E8CE16ECE0DE065CF4B6014B -:106C4000660F771F660F771FC60ED71ECC0CDD1C94 -:106C5000C80ED11C5D01FFEFAF1ABF0A8C918053A3 -:106C60008A30A8F1C4FF03C0D194C194D1080C0D9F -:106C70001D1DC1FF09C0E114F10431F081E0A81A23 -:106C8000B108D701AD92BC92CA01B9010F94B639CF -:106C9000C370C33009F490584B015C0120E030E030 -:106CA000A9010F94B139882309F440C0C3E5D5E0A8 -:106CB00017FF05C0119501951109CBE3D5E06E01D1 -:106CC000B8E1CB1AD10880E2E82EF12C0FC0D50133 -:106CD000B1CFFE0125913591459154910E191F09AF -:106CE000C501B4010F94173A4B015C01D501C401F1 -:106CF0000E151F0574F72497F594E794CC16DD065E -:106D0000A9F78A2F880F8B2F881F8F3F49F020E02B -:106D100030E0A901C501B4010F94B139811106C059 -:106D200082E290E090930E1980930D19C501B40191 -:106D3000DF91CF911F910F91FF90EF90DF90CF9057 -:106D4000BF90AF909F908F9008953F924F925F9227 -:106D50006F927F928F929F92AF92BF92CF92DF926B -:106D6000EF92FF920F931F93CF93DF935C016B0120 -:106D70007A016115710519F0FB0191838083E1149B -:106D8000F10451F0C7010297839730F040E030E002 -:106D900020E090E06BC05E01E5012196F5011081D5 -:106DA000812F90E00F94D638892BA9F71D3201F579 -:106DB0002196F501118101E0E114F10409F4E6C026 -:106DC000F0E1EF16F10409F088C0103359F488811E -:106DD0008F7D883509F07CC0198122960260F0E130 -:106DE000EF2EF12C812C912CA12C88E0B82E92C092 -:106DF0001B3221F4E5012296F501118100E0DCCF80 -:106E0000EAE0EE16F10409F4C7C0F0E1EF16F10470 -:106E100009F073C0E7CF78E0E72EF12C812C912C9C -:106E2000A12C60E1B62E76C021E0ADC0302F3170CC -:106E3000C114D10431F0222371F12197F601D183DD -:106E4000C08327FF2EC060E070E080E090E8311141 -:106E500004C06FEF7FEF8FEF9FE722E230E03093C7 -:106E60000E1920930D19462F372F282F642F732FBB -:106E7000822FDF91CF911F910F91FF90EF90DF90C4 -:106E8000CF90BF90AF909F908F907F906F905F90CA -:106E90004F903F90089501FF04C02297F601D183DF -:106EA000C083332341F090958095709561957F4F15 -:106EB0008F4F9F4FD8CF97FFD6CF82E290E090932D -:106EC0000E1980930D196FEF7FEF8FEF9FE7CBCFF8 -:106ED00010E3E114F10409F49ECF28E0E216F10476 -:106EE00009F49CCF0CF08CCF812C912CA12CE0E4E8 -:106EF000BE2E82E0E816F10469F060E070E080E008 -:106F000090E897010F2C000C440B550B0F94A43DF7 -:106F100049015A0120E060E070E0CB0127010F2C0D -:106F2000000C66087708FE0150ED352E310E39E071 -:106F3000331570F43FEB310F49EC342E3A3138F011 -:106F40003FE9310F3A3108F071CF39EA332E310E73 -:106F50003E141F040CF06ACF27FD15C08616970655 -:106F6000A806B90678F0A30192010F94943D630D31 -:106F7000711D811D911D61307105810520E8920709 -:106F800008F452CF2FEF21961081CDCF103309F4A2 -:106F90001ECF2AE0E22EF12C9CEC892E982CA82CF6 -:106FA0009CE0B92EB7CF3F924F925F926F927F9243 -:106FB0008F929F92AF92BF92CF92DF92EF92FF9209 -:106FC0000F931F93CF93DF935C016B017A016115DF -:106FD000710519F0FB0191838083E114F10449F0FC -:106FE000C7010297839728F060E070E0CB019BC057 -:106FF0005E01E5012196F5011081812F90E00F944B -:10700000D638892BA9F71D3209F05CC02196F5010D -:10701000118101E0E114F10409F4BBC0F0E1EF16C5 -:10702000F10409F09BC0103341F488818F7D8835CD -:1070300009F08FC0198122960260E0E1EE2EF12C5A -:1070400088248A94982CA82CFFE0BF2E20E060E0D2 -:1070500070E0CB0127010F2C000C66087708FE01B9 -:1070600050ED352E310E39E0331568F43FEB310F1A -:1070700049EC342E3A3130F03FE9310F3A31B0F576 -:1070800039EA332E310E3E141F0484F52F3FB9F038 -:1070900086169706A806B90638F1A30192010F9447 -:1070A000943D232D30E050E040E0620F731F841FB9 -:1070B000951F6217730784079507B0F021E02196AA -:1070C0001081CDCF1B3221F4E5012296F50111810B -:1070D00000E0A0CF78E0E72EF12C88248A94982C49 -:1070E000A82C6FE1B62EB2CF2FEFE9CFC114D10497 -:1070F00031F0222351F12197F601D183C08300FFA3 -:1071000007C090958095709561957F4F8F4F9F4FE9 -:107110002F3F49F482E290E090930E1980930D196D -:107120006FEF7FEFCB01DF91CF911F910F91FF9018 -:10713000EF90DF90CF90BF90AF909F908F907F9017 -:107140006F905F904F903F90089501FFD8CF2297A6 -:10715000D3CF10E3E114F10409F4BCCF3AE0E31615 -:10716000F104E9F080E1E816F10409F466CFE8E003 -:10717000EE16F10409F4B1CF6FEF7FEFCB01970169 -:107180000F2C000C440B550B0F94A43D49015A01E0 -:107190005DCF103309F449CF9AE0E92EF12C89E94B -:1071A000882E982CA82C89E1B82E50CF91110D94DF -:1071B000863C803219F089508550C8F70895FB014C -:1071C000DC0102C005900D9241505040D8F708955F -:1071D000FB01DC010D900020E9F7119705900D925D -:1071E0000020E1F70895FC010590061621F000202B -:1071F000D9F7C00108953197CF010895FC0105909A -:107200000020E9F7809590958E0F9F1F0895FB0150 -:10721000DC014150504088F08D9181341CF08B3559 -:107220000CF4805E659161341CF06B350CF4605E8B -:10723000861B611171F3990B0895881BFCCFFB012C -:10724000DC014150504048F005900D920020C9F7F4 -:1072500001C01D9241505040E0F70895FB01559147 -:107260005523A9F0BF01DC014D9145174111E1F70C -:1072700059F4CD010590002049F04D914015411180 -:10728000C9F3FB014111EFCF81E090E00197089530 -:107290000F931F93CF93DF93CDB7DEB72E970FB623 -:1072A000F894DEBF0FBECDBF0E891F898EE08C83A0 -:1072B0001A8309838FEF9FE79E838D83AE01465E1D -:1072C0005F4F688D798DCE0101960F94843A2F819E -:1072D0003885020F131FF80110822E960FB6F8940E -:1072E000DEBF0FBECDBFDF91CF911F910F910895EB -:1072F0000F931F93CF93DF93CDB7DEB72E970FB6C3 -:10730000F894DEBF0FBECDBF8C01FA018EE08C83F6 -:107310001A83098377FF02C060E070E86150710949 -:107320007E836D83A901BF01CE0101960F94843A3B -:107330004D815E8157FD0AC02F8138854217530762 -:107340000CF49A01020F131FF80110822E960FB64B -:10735000F894DEBF0FBECDBFDF91CF911F910F918B -:1073600008950F94F33908F481E00895E89409C072 -:1073700097FB3EF490958095709561957F4F8F4F68 -:107380009F4F9923A9F0F92F96E9BB279395F6957E -:10739000879577956795B795F111F8CFFAF4BB0FFC -:1073A00011F460FF1BC06F5F7F4F8F4F9F4F16C060 -:1073B000882311F096E911C0772321F09EE8872FEA -:1073C000762F05C0662371F096E8862F70E060E0A6 -:1073D0002AF09A95660F771F881FDAF7880F96951F -:1073E000879597F90895990F0008550FAA0BE0E8C3 -:1073F000FEEF16161706E807F907C0F01216130677 -:10740000E407F50798F0621B730B840B950B39F4B6 -:107410000A2661F0232B242B252B21F408950A261C -:1074200009F4A140A6958FEF811D811D08950F9449 -:107430002A3A0D94443D0F94363D38F00F943D3D6B -:1074400020F0952311F00D942D3D0D94333D112422 -:107450000D94783D0F94553D70F3959FC1F3950FB2 -:1074600050E0551F629FF001729FBB27F00DB11DC8 -:10747000639FAA27F00DB11DAA1F649F6627B00D58 -:10748000A11D661F829F2227B00DA11D621F739F41 -:10749000B00DA11D621F839FA00D611D221F749F4F -:1074A0003327A00D611D231F849F600D211D822F96 -:1074B000762F6A2F11249F5750409AF0F1F08823BD -:1074C0004AF0EE0FFF1FBB1F661F771F881F9150EA -:1074D0005040A9F79E3F510580F00D942D3D0D942D -:1074E000783D5F3FE4F3983ED4F3869577956795B2 -:1074F000B795F795E7959F5FC1F7FE2B880F911D14 -:107500009695879597F908952F923F924F925F92A3 -:107510006F927F928F929F92AF92BF92CF92DF92A3 -:10752000EF92FF920F931F93CF93DF9300D000D081 -:1075300000D01F921F92CDB7DEB77C013B018A01BC -:10754000FC0117821682838181FFDDC1CE01019685 -:107550005C01F7019381F30193FD859193FF819184 -:107560003F01882309F453C1853239F493FD859195 -:1075700093FF81913F01853229F4B70190E00F9488 -:107580009F3CE7CF912C212C312CFFE1F31538F0F3 -:107590008B3211F190F4803209F1833229F137FCFA -:1075A0003CC020ED280F2A3050F536FE20C08AE07E -:1075B000989E200D1124922E06C08D3291F08033BA -:1075C00071F7689430F8F30193FD859193FF8191F1 -:1075D0003F018111DACF21C0689431F8689432F804 -:1075E000F2CF689433F8EFCF689434F8ECCFEAE048 -:1075F0002E9E200D1124222E689435F8E4CF8E3271 -:1076000029F436FC04C1689436F8DDCF8C3619F4C1 -:10761000689437F8D8CF8836B1F2982F9F7D95546B -:107620009330E0F08336A1F18337C1F1833509F05F -:1076300063C02801F2E04F0E511CF801C080D180D8 -:10764000692D70E036FC02C06FEF7FEFC6010F942A -:10765000893C4C01689437F882010AC00C5F1F4FC7 -:10766000FFE3F98388248394912C6501E89437F82B -:1076700033FE2DC0522C8114910471F5552009F46C -:1076800068CFB70180E290E00F949F3C5A94F6CF08 -:10769000F801808189830E5F1F4FE4CF2801F2E05B -:1076A0004F0E511CF801C080D180692D70E036FC6E -:1076B00002C06FEF7FEFC6010F94943C4C01820132 -:1076C000D5CFB70180E290E00F949F3C2A94281414 -:1076D000190409F0B0F7CECFF60137FC859137FEDB -:1076E00081916F01B70190E00F949F3C51105A9423 -:1076F000F1E08F1A9108BFCF843619F0893609F06E -:1077000077C0F80137FE6BC06081718182819381FF -:107710000C5F1F4FF32DFF763F2E97FF09C090950A -:107720008095709561957F4F8F4F9F4F689437F884 -:107730002AE030E0A5010F94CF3CC82ECA188C2C4B -:10774000432C36FE0CC0E89440F8C91440F434FED3 -:1077500005C032FC03C0F32DFE7E4F2E892C44FE63 -:10776000AAC0FE01EC0DF11D8081803309F09CC0A0 -:10777000242D297E422E842D8870582E43FCAAC0C9 -:1077800040FEA4C09C2C821418F42C0C922C981847 -:1077900044FEA6C0B70180E390E00F949F3C42FEF8 -:1077A00009C088E790E041FE02C088E590E0B7019B -:1077B0000F949F3CC91408F49FC0CA94D12C9FEF2A -:1077C000C91AD90ACA0CDB1CF60182916F01B701F4 -:1077D00090E00F949F3CAC14BD04B1F74FCF608193 -:1077E0007181072E000C880B990B0E5F1F4F92CFF3 -:1077F000D32CE894D4F82AE030E08537E1F1232D4A -:10780000297FD22E8F36A9F1F0F4883551F1F70196 -:10781000868197812B960FB6F894DEBF0FBECDBF41 -:10782000DF91CF911F910F91FF90EF90DF90CF905C -:10783000BF90AF909F908F907F906F905F904F9090 -:107840003F902F900895803749F0883701F7D4FE94 -:1078500002C06894D2F820E130E00DC06894D4F8FA -:10786000F6CF34FE03C0822F8660D82E20E132E0AE -:1078700002C028E030E0F801D7FE0FC060817181BE -:10788000828193810C5F1F4FA5010F94CF3CC82EBE -:10789000CA183D2CE89437F852CF6081718190E08E -:1078A00080E00E5F1F4FF0CF42FC02C0839463CF95 -:1078B0008394839460CF842D867809F45CCFF6CFCF -:1078C000B70180E290E00F949F3C83948214C0F350 -:1078D000512C5ECF522C5818821408F459CFF8CF8F -:1078E000842D867809F466CF8BE241FE80E247FC66 -:1078F0008DE2B70190E05CCFB70180E390E00F9498 -:107900009F3C9A9457CF8FEF9FEF84CF992788277A -:107910000895FC010590615070400110D8F78095E2 -:1079200090958E0F9F1F0895FC016150704001904B -:107930000110D8F7809590958E0F9F1F08950F9393 -:107940001F93CF93DF93182F092FEB018B8181FDBC -:1079500009C01FEF0FEF812F902FDF91CF911F9163 -:107960000F91089582FF14C02E813F818C819D81EB -:10797000281739073CF4E881F981CF0101969983F2 -:10798000888310838E819F8101969F838E83E3CFAE -:10799000E885F985812F1995892BA1F3DACFFA01B2 -:1079A000AA27283051F1203181F1E8946F936E7F3E -:1079B0006E5F7F4F8F4F9F4FAF4FB1E03ED0B4E02F -:1079C0003CD0670F781F891F9A1FA11D680F791F70 -:1079D0008A1F911DA11D6A0F711D811D911DA11D81 -:1079E00020D009F468943F912AE0269F1124301991 -:1079F000305D3193DEF6CF010895462F4770405D2C -:107A00004193B3E00FD0C9F7F6CF462F4F70405DDA -:107A10004A3318F0495D31FD4052419302D0A9F735 -:107A2000EACFB4E0A6959795879577956795BA952F -:107A3000C9F700976105710508959B01AC010A2EF5 -:107A400006945795479537952795BA95C9F7620FCC -:107A5000731F841F951FA01D089597F99F6780E8E5 -:107A600070E060E008959FEF80EC089500240A9490 -:107A70001616170618060906089500240A94121609 -:107A80001306140605060895092E0394000C11F43C -:107A9000882352F0BB0F40F4BF2B11F460FF04C0E9 -:107AA0006F5F7F4F8F4F9F4F089557FD9058440F42 -:107AB000551F59F05F3F71F04795880F97FB991F4D -:107AC00061F09F3F79F0879508951216130614060A -:107AD000551FF2CF4695F1DF08C016161706180697 -:107AE000991FF1CF86957105610508940895E89472 -:107AF000BB2766277727CB0197F90895F999FECF21 -:107B000092BD81BDF89A992780B50895262FF999DD -:107B1000FECF1FBA92BD81BD20BD0FB6F894FA9A70 -:107B2000F99A0FBE01960895DB018F939F930F94EE -:107B3000E53DBF91AF91A29F800D911DA39F900D38 -:107B4000B29F900D11240895A1E21A2EAA1BBB1B0F -:107B5000FD010DC0AA1FBB1FEE1FFF1FA217B30719 -:107B6000E407F50720F0A21BB30BE40BF50B661F2F -:107B7000771F881F991F1A9469F7609570958095F3 -:107B800090959B01AC01BD01CF010895052E97FB97 -:107B90001EF400940F94DD3D57FD07D00F94A43DD3 -:107BA00007FC03D04EF40D94DD3D50954095309583 -:107BB00021953F4F4F4F5F4F089590958095709559 -:107BC00061957F4F8F4F9F4F08950F94F83DA59F6C -:107BD000900DB49F900DA49F800D911D11240895C8 -:107BE000B7FF0D94E53D0F94E53D821B930B08957F -:107BF000A29FB001B39FC001A39F700D811D1124EE -:107C0000911DB29F700D811D1124911D0895505832 -:107C1000BB27AA270F941F3E0D94443D0F94363D79 -:107C200038F00F943D3D20F039F49F3F19F426F4CD -:107C30000D94333D0EF4E095E7FB0D942D3DE92FB7 -:107C40000F94553D58F3BA176207730784079507D9 -:107C500020F079F4A6F50D94773D0EF4E0950B2E07 -:107C6000BA2FA02D0B01B90190010C01CA01A0018E -:107C70001124FF27591B99F0593F50F4503E68F1E9 -:107C80001A16F040A22F232F342F4427585FF3CF2A -:107C9000469537952795A795F0405395C9F77EF4FB -:107CA0001F16BA0B620B730B840BBAF09150A1F044 -:107CB000FF0FBB1F661F771F881FC2F70EC0BA0FCA -:107CC000621F731F841F48F4879577956795B79552 -:107CD000F7959E3F08F0B0CF9395880F08F099274D -:107CE000EE0F9795879508950F94363D60F080E8E4 -:107CF00091E009F49EEF0F943D3D28F040E851E0FB -:107D000071F45EEF0CC00D94333D0D94773DE92F77 -:107D1000E0780F94553D40F3092E052AB1F326175C -:107D200037074807590738F00E2E07F8E02569F0A5 -:107D3000E025E0640AC0EF6307F8009407FADB016E -:107D4000B9019D01DC01CA01AD01EF930F94193F08 -:107D50000F94443D0F94B73E5F91552339F02BEDBE -:107D60003FE049E450FD49EC0D94083E0895DF934F -:107D7000DD27B92FBF7740E85FE3161617064807DF -:107D80005B0718F4D92F0F946D409F938F937F93C7 -:107D90006F930F94F640E4EEF0E00F94EA3F0F94F7 -:107DA000443D2F913F914F915F910F942A3ADD23EB -:107DB00051F09058A2EA2AED3FE049EC5FE3D07819 -:107DC0005D270F941F3EDF910D94443D0F9450406A -:107DD00090F09F3748F4911116F40D94783D60E0CF -:107DE00070E080E89FE3089526F01B16611D711D69 -:107DF000811D0D94C13F0D94DC3F0F941340E3951A -:107E00000D943C400F94163F0D94443D0F943D3D1E -:107E100058F00F94363D40F029F45F3F29F00D945F -:107E20002D3D51110D94783D0D94333D0F94553DEA -:107E300068F39923B1F3552391F3951B550BBB2799 -:107E4000AA2762177307840738F09F5F5F4F220FDE -:107E5000331F441FAA1FA9F335D00E2E3AF0E0E8D5 -:107E600032D091505040E695001CCAF72BD0FE2F1F -:107E700029D0660F771F881FBB1F261737074807B3 -:107E8000AB07B0E809F0BB0B802DBF01FF2793586B -:107E90005F4F3AF09E3F510578F00D942D3D0D94C3 -:107EA000783D5F3FE4F3983ED4F3869577956795E8 -:107EB000B795F7959F5FC9F7880F911D96958795A0 -:107EC00097F90895E1E0660F771F881FBB1F6217BF -:107ED00073078407BA0720F0621B730B840BBA0B7D -:107EE000EE1F88F7E09508950F947B3F6894B111D9 -:107EF0000D94783D08950F945D3D88F09F5798F05C -:107F0000B92F9927B751B0F0E1F0660F771F881F9E -:107F1000991F1AF0BA95C9F714C0B13091F00F94B7 -:107F2000773DB1E008950D94773D672F782F88272E -:107F3000B85F39F0B93FCCF3869577956795B395DF -:107F4000D9F73EF490958095709561957F4F8F4F4E -:107F50009F4F08950F94504090F09F3748F491112F -:107F600016F00D94783D60E070E080E89FEB089596 -:107F700026F41B16611D711D811D0D94C13F0D94CA -:107F8000DC3F882371F4772321F09850872B762FDC -:107F900007C0662311F499270DC09051862B70E01D -:107FA00060E02AF09A95660F771F881FDAF7880F2E -:107FB0009695879597F908959F3F31F0915020F459 -:107FC000879577956795B795880F911D96958795B5 -:107FD00097F90895DF93CF931F930F93FF92EF923A -:107FE000DF927B018C01689406C0DA2EEF010F94BA -:107FF0002A3AFE01E894A591259135914591559134 -:10800000A6F3EF010F941F3EFE019701A801DA9439 -:1080100069F7DF90EF90FF900F911F91CF91DF9163 -:1080200008950D94333D0F945D3DD8F3E894E0E05E -:10803000BB279F57F0F02AED3FE049EC06C0EE0F5A -:10804000BB0F661F771F881F28F0B23A62077307BD -:10805000840728F0B25A620B730B840BE3959A9550 -:1080600072F7803830F49A95BB0F661F771F881F10 -:10807000D2F790480D94DE3FEF93E0FF07C0A2EAED -:108080002AED3FE049EC5FEB0F941F3E0F94443D17 -:108090000F90039401FC9058E1E1F1E00D9406414A -:1080A0000F945D3DA0F0BEE7B91788F4BB279F3859 -:1080B00060F41616B11D672F782F8827985FF7CFC9 -:1080C000869577956795B11D93959639C8F3089570 -:1080D0000F94F33908F48FEF08959B01AC0160E031 -:1080E00070E080E89FE30D94023F0F945D3D58F1EE -:1080F0009E5760F19851A0F0E9F0983020F5092ED4 -:108100009927660F771F881F991F0A94D1F712C00D -:10811000062E672F782F8827985F11F4000C07C070 -:10812000993FB4F38695779567959395D9F7611D37 -:10813000711D811D3EF490958095709561957F4FDE -:108140008F4F9F4F089568940D94783D0D94773D1F -:108150009F930F9413400F9007FCEE5F0D943C40EB -:1081600019F416F40D94333D0D94DC3F0F945D3DEE -:10817000B8F39923C9F3B6F39F57550B87FF0F94B4 -:10818000FF400024A0E640EA90018058569597955C -:1081900028F4805C660F771F881F20F026173707AA -:1081A000480730F4621B730B840B202931294A2BBA -:1081B000A69517940794202531254A2758F7660F6E -:1081C000771F881F20F026173707480730F4620B07 -:1081D000730B840B200D311D411DA09581F7B90152 -:1081E000842F9158880F9695879508959B01AC012F -:1081F0000D94173A0F94F339880B990B0895915009 -:108200005040660F771F881FD2F708959F938F9372 -:108210007F936F93FF93EF939B01AC010F94173AF9 -:10822000EF91FF910F94EA3F2F913F914F915F9112 -:108230000D94173A991B79E004C0991F961708F01E -:10824000961B881F7A95C9F78095089587FB082E9D -:10825000062687FD819567FD61950F941A410EF4FE -:10826000919507FC81950895AA1BBB1B51E107C09E -:10827000AA1FBB1FA617B70710F0A61BB70B881FB6 -:10828000991F5A95A9F780959095BC01CD01089545 -:1082900097FB072E16F4009407D077FD09D00F94B2 -:1082A000344107FC05D03EF4909581959F4F089589 -:1082B000709561957F4F0895EE0FFF1F881F8BBF4C -:1082C0000790F691E02D1994AA27992329F4A85F25 -:1082D000982B11F480E10895903118F4AD5F9295D8 -:1082E000A395990FE8F78A2F99270895002E083053 -:1082F00090F0982F872F762F652F542F432F322FF2 -:1083000022270850F4CF220F331F441F551F661F2A -:10831000771F881F991F0A95B2F7002D089597FDC2 -:108320001094002E083098F00850232F342F452F3A -:10833000562F672F782F892F912DF4CF159497956D -:1083400087957795679557954795379527950A951A -:10835000AAF71124002D089581E090E0F8940D947F -:108360001C429111089581548A5108F4805E855A07 -:108370000895FB01DC0104C08D910190801921F466 -:1083800041505040C8F7881B990B0895FB01DC0150 -:1083900002C001900D9241505040D8F70895FB0162 -:1083A000DC018D9181341CF08B350CF4805E619181 -:1083B00061341CF06B350CF4605E861B611189F32F -:1083C000990B0895FC018191861721F08823D9F734 -:1083D000992708953197CF010895FB01DC010190A1 -:1083E0000D920020E1F70895FB01DC01415050405F -:1083F00030F08D910190801919F40020B9F7881B95 -:10840000990B0895FB01DC014150504048F0019068 -:108410000D920020C9F701C01D9241505040E0F775 -:108420000895FC0181E090E00190061609F4CF0167 -:108430000020D1F7019708951EE1C7E4DEE100E0D6 -:1084400006C0802FFE010F945C412196011DC834A7 -:10845000D10780E00807A9F7F894FFCF104000008B -:108460000080020430290002AC00FFFFFF01CDCCE8 -:10847000CC3DFA00D20001010000803F640064009E -:1084800064000000803F0000803FFFFFFFFFFFFF10 -:10849000FF080101000000E6C20000A8C2000000C1 -:1084A000000000184300009A42000016430000C874 -:1084B00041010D0D0202C0D401006400AA00FF3F7B -:1084C000FF3F00000000FF3FFF3F00000000FF3FB4 -:1084D0000103000018430000A8C20000164300007A -:1084E0000000000010198000003C1C46003C1C46A7 -:1084F000003C1C46003C1C4658595A45000100FFF0 -:108500000100FF0002020000484200004842000053 -:10851000804000000040D505C705B70504010401EF -:108520000000204100002041CDCCCC3E00000040A6 -:108530000000C07F0000C07F0000C07FFF003C0043 -:108540000100004040000034420000000000000034 -:10855000000000000000005041000000000000008A -:10856000416400000064000000030000006400009B -:10857000006400000003000000030000000300008E -:10858000001E0000001E00000000001643000096C0 -:10859000420000A04156383600FFFF4040CF38CFA0 -:1085A00038440000000000470048000000000000C0 -:1085B00001010100001643000096420000A04100A6 -:1085C000001643000096420000A0410A05062E0155 -:1085D00000080020004000800000010004000000AE -:1085E000000000F201DE00B5240401400220023048 -:1085F00001000000008C02B000B5240401DA01CEB5 -:108600000034010000000095756E76AD743D7592E2 -:1086100074A5732D7488734F754E74C76F4A704973 -:1086200070000000007C01DC01E6019C00E200E03B -:10863000018401280200011001BE0086011602001B -:108640000000000929DE00B5244970455252005A45 -:0686500000590058000073 -:020000040003F7 -:10E000000D9489F10D94B2F10D94B2F10D94B2F129 -:10E010000D94B2F10D94B2F10D94B2F10D94B2F1F0 -:10E020000D94B2F10D94B2F10D94B2F10D94B2F1E0 -:10E030000D94B2F10D94B2F10D94B2F10D94B2F1D0 -:10E040000D94B2F10D94B2F10D94B2F10D94B2F1C0 -:10E050000D94B2F10D94B2F10D94B2F10D94B2F1B0 -:10E060000D94B2F10D94B2F10D94B2F10D94B2F1A0 -:10E070000D94B2F10D94B2F10D94B2F10D94B2F190 -:10E080000D94B2F10D94B2F10D94B2F10D94B2F180 -:10E090000D94B2F10D94B2F10D94B2F10D94B2F170 -:10E0A0000D94B2F10D94B2F10D94B2F10D94B2F160 -:10E0B0000D94B2F10D94B2F10D94B2F10D94B2F150 -:10E0C0000D94B2F10D94B2F10D94B2F10D94B2F140 -:10E0D0000D94B2F10D94B2F10D94B2F10D94B2F130 -:10E0E0000D94B2F141546D656761323536300041AF -:10E0F000726475696E6F206578706C6F72657220DE -:10E1000073746B3530305632206279204D4C530099 -:10E11000426F6F746C6F616465723E004875683F52 -:10E1200000436F6D70696C6564206F6E203D200048 -:10E130004350552054797065202020203D20005FF9 -:10E140005F4156525F415243485F5F3D2000415658 -:10E1500052204C696243205665723D20004743437C -:10E160002056657273696F6E203D20004350552024 -:10E1700049442020202020203D20004C6F7720663D -:10E18000757365202020203D20004869676820665F -:10E190007573652020203D200045787420667573D6 -:10E1A00065202020203D20004C6F636B2066757336 -:10E1B000652020203D20004D617220203720323024 -:10E1C000313300312E362E3800342E332E350056A2 -:10E1D00023202020414444522020206F7020636F70 -:10E1E00064652020202020696E73747275637469E1 -:10E1F0006F6E2061646472202020496E74657272B3 -:10E20000757074006E6F20766563746F7200726A49 -:10E210006D702020006A6D70200057686174207056 -:10E220006F72743A00506F7274206E6F7420737541 -:10E2300070706F72746564004D7573742062652030 -:10E2400061206C6574746572002000577269747483 -:10E25000696E672045450052656164696E672045B7 -:10E26000450045452065727220636E743D00504F35 -:10E27000525400303D5A65726F2061646472003FF1 -:10E280003D43505520737461747300403D454550C3 -:10E29000524F4D207465737400423D426C696E6B41 -:10E2A000204C454400453D44756D70204545505215 -:10E2B0004F4D00463D44756D7020464C415348001B -:10E2C000483D48656C70004C3D4C69737420492F83 -:10E2D0004F20506F72747300513D51756974005234 -:10E2E0003D44756D702052414D00563D73686F7707 -:10E2F00020696E7465727275707420566563746FF0 -:10E30000727300593D506F727420626C696E6B00BD -:10E310002A0011241FBECFEFD1E2DEBFCDBF01E046 -:10E320000CBF12E0A0E0B2E0EEE1FDEF03E00BBFB6 -:10E3300002C007900D92A030B107D9F712E0A0E01B -:10E34000B2E001C01D92AE30B107E1F70F9460F367 -:10E350000D948DFE01E20EBF0FEF0DBF11241FBE05 -:10E360000D9460F30D9400F020E030E040ED57E0B4 -:10E3700005C0FA013197F1F72F5F3F4F2817390792 -:10E38000C0F308959C01260F311DC901A0E0B0E043 -:10E390002F5F3F4FABBFFC018791882361F08093D3 -:10E3A000C6008091C00086FFFCCF8091C0008064D1 -:10E3B0008093C000EACF08958DE08093C6008091DD -:10E3C000C00086FFFCCF8091C00080648093C000B5 -:10E3D0008AE08093C6008091C00086FFFCCF8091C8 -:10E3E000C00080648093C00008950F94C2F10F9420 -:10E3F000DCF10895FC019081992359F09093C600B7 -:10E400008091C00086FFFCCF8091C0008064809323 -:10E41000C0003196992379F70895282F982F929567 -:10E420009F70892F805D8A3308F0895F8093C600D2 -:10E430008091C00086FFFCCF8091C00080648093F3 -:10E44000C000822F8F70982F905D9A3308F0995FEB -:10E450009093C6008091C00086FFFCCF8091C000E1 -:10E4600080648093C00008959C01FB01853691056E -:10E470001CF46330710594F0C90164E670E00F94F8 -:10E480002EFE605D7F4F6093C6008091C00086FFC6 -:10E49000FCCF8091C00080648093C0002B30310598 -:10E4A00014F43297B4F0C90164E670E00F942EFEC4 -:10E4B0006AE070E00F942EFE605D7F4F6093C600AF -:10E4C0008091C00086FFFCCF8091C0008064809363 -:10E4D000C000C9016AE070E00F942EFEC0968093E0 -:10E4E000C6008091C00086FFFCCF8091C000806490 -:10E4F0008093C00008951F93182F8EE692EE60E07F -:10E500000F94C2F11093C6008091C00086FFFCCF2B -:10E510008091C00080648093C0000F94DCF11F9153 -:10E5200008952F923F924F925F926F927F928F92B7 -:10E530009F92AF92BF92CF92DF92EF92FF920F9392 -:10E540001F93DF93CF93CDB7DEB762970FB6F894E2 -:10E55000DEBF0FBECDBF382E622ECA01DB015C01CB -:10E560006D01772420E2222E2E010894411C511CBB -:10E570008BC081E0A81680E0B80681E0C80680E084 -:10E58000D80628F0C601AA27BB270F940DF2BB2797 -:10E59000AD2D9C2D8B2D0F940DF28A2D0F940DF225 -:10E5A0002092C6008091C00086FFFCCF8091C00001 -:10E5B00080648093C0009DE29093C6008091C0006B -:10E5C00086FFFCCF8091C00080648093C0002092C1 -:10E5D000C6008091C00086FFFCCF8091C00080649F -:10E5E0008093C00019828601750188249924A1E0D6 -:10E5F0003A1651F03A1620F0B2E03B1661F409C029 -:10E600000BBFF701779007C0C7010F9477FE782EF4 -:10E6100002C0F7017080872D0F940DF22092C60082 -:10E620008091C00086FFFCCF8091C0008064809301 -:10E63000C000872D8052F401EF70F0708F3520F408 -:10E64000E40DF51D708204C0E40DF51D8EE280839B -:10E650000894E11CF11C011D111D0894811C911CE2 -:10E6600090E18916910409F0C2CF80E190E0A0E02A -:10E67000B0E0A80EB91ECA1EDB1E198AC2010F9493 -:10E68000FAF10F94DCF16A94662009F072CF629679 -:10E690000FB6F894DEBF0FBECDBFCF91DF911F91B3 -:10E6A0000F91FF90EF90DF90CF90BF90AF909F9031 -:10E6B0008F907F906F905F904F903F902F90089534 -:10E6C0002F923F924F925F926F927F928F929F9282 -:10E6D000AF92BF92CF92DF92EF92FF920F931F9370 -:10E6E000DF93CF93CDB7DEB7CD53D1400FB6F894BB -:10E6F000DEBF0FBECDBF01E20EBF0FEF0DBF94B75F -:10E70000F894A89514BE80916000886180936000A1 -:10E7100010926000789493FF05C0E0910002F091A0 -:10E7200001021995279A2F9A8091C00082608093E8 -:10E73000C00080E18093C40088E18093C1000000A4 -:10E74000EE24FF24870144E0A42EB12CCC24DD2448 -:10E7500024C0C5010197F1F70894E11CF11C011DCB -:10E76000111D21E2E2162EE4F20620E0020720E06D -:10E77000120718F031E0C32ED12CC801B70127ECE5 -:10E780003BE140E050E00F9441FE611571058105C9 -:10E79000910519F485B1805885B98091C00087FD35 -:10E7A00003C0C114D104A9F2A6014F5F5F4FC25E3E -:10E7B000DE4F59834883CE51D140C25EDE4F8881FF -:10E7C0009981CE51D140019711F00D9410FEC05D9A -:10E7D000DE4F19821882C053D14060E0C15DDE4F28 -:10E7E0001882CF52D14088249924C35DDE4F19820C -:10E7F0001882CD52D140C05EDE4F188219821A8233 -:10E800001B82C052D140CE5CDE4F188219821A8220 -:10E810001B82C253D140EE24FF2487010BBFF701B6 -:10E8200007911691C45CDE4F19830883CC53D14005 -:10E830000D940BFEC25EDE4F28813981CE51D1404E -:10E840002130310509F52091C600C25EDE4F1982E4 -:10E850001882CE51D14022C02F5F3F4F4F4F5F4FA4 -:10E86000213082E138078AE7480780E0580780F0C6 -:10E87000C45CDE4FE881F981CC53D140EF5FFF4F9C -:10E8800019F0EE27FF27099420E030E040E050E047 -:10E890008091C00087FFE0CF2091C600C35DDE4FAE -:10E8A00048815981CD52D1404F5F5F4FC35DDE4FEC -:10E8B00059834883CD52D140213209F063C64A3092 -:10E8C000510508F05FC60894811C911C53E0851621 -:10E8D000910409F059C600E010E018C081E280936D -:10E8E000C6008091C00086FFFCCF8091C00080648C -:10E8F0008093C0002F5F3F4F2931310579F70F9486 -:10E90000DCF10F5F1F4F0530110519F020E030E0FA -:10E91000E5CF10920A0210920B0210920C02109294 -:10E920000D02109206021092070210920802109235 -:10E930000902109202021092030210920402109235 -:10E9400005028FEE90EE60E00F94F5F180E191EE1C -:10E9500060E00F94C2F18091C00087FFFCCF9091DE -:10E96000C600903608F09F759032B8F09093C600BC -:10E970008091C00086FFFCCF8091C00080648093AE -:10E98000C000A0E2A093C6008091C00086FFFCCF2B -:10E990008091C00080648093C000983409F4D7C18E -:10E9A0009934B8F4923409F459C1933458F490333B -:10E9B00019F1903308F4E3C59F33A1F1903409F0C5 -:10E9C000DEC5BDC0953409F470C1963409F0D7C5D1 -:10E9D00098C1923509F42BC2933538F49C3409F46C -:10E9E000F5C1913509F0CBC518C2963509F445C279 -:10E9F000993509F0C4C567C483E792EE62E00F94CD -:10EA0000F5F110920602109207021092080210927D -:10EA1000090210920A0210920B0210920C0210923C -:10EA20000D0213C18FE792EE62E00F94F5F18FEEC5 -:10EA300090EE60E00F94F5F181E291EE60E00F94CA -:10EA4000C2F187EB91EE60E00F94F5F180E391EE77 -:10EA500060E00F94C2F184EE90EE60E00F94F5F167 -:10EA60008FE391EE60E00F94C2F186E090E061E008 -:10EA700070E00F9434F20F94DCF18DE591EE60E0DC -:10EA80000F94C2F189EC91EE60E00F94F5F18EE401 -:10EA900091EE60E00F94C2F183EC91EE60E00F9490 -:10EAA000F5F18CE691EE60E00F94C2F18EE10F94E7 -:10EAB0000DF288E90F940DF281E00F940DF20F949E -:10EAC000DCF18BE791EE60E00F94C2F119E0E0E039 -:10EAD000F0E010935700E4918E2F0F940DF20F94F5 -:10EAE000DCF18AE891EE60E00F94C2F1E3E0F0E03F -:10EAF00010935700E4918E2F0F940DF20F94DCF1D8 -:10EB000089E991EE60E00F94C2F1E2E0F0E0109349 -:10EB10005700E4918E2F0F940DF20F94DCF188EAE8 -:10EB200091EE60E00F94C2F1E1E0F0E01093570045 -:10EB30001491812F0F940DF20F94DCF107CF8BE825 -:10EB400092EE62E00F94F5F18BE492EE60E00F94A8 -:10EB5000F5F10F94DCF100E010E019C0C8016F2D51 -:10EB60000F947FFEFF2031F489E492EE60E00F9471 -:10EB7000C2F10BC0F092C6008091C00086FFFCCFAE -:10EB80008091C00080648093C0000F5F1F4FC80158 -:10EB900081519F41A0E0B0E0ABBFFC01F790BAE229 -:10EBA000FB1621F0E2E000301E07C1F60F94DCF105 -:10EBB0000F94DCF187E592EE60E00F94F5F10F948D -:10EBC000DCF1CC24DD2400E010E01EC0C8010F946D -:10EBD00077FEF82E882331F489E492EE60E00F94FA -:10EBE000C2F10BC08093C6008091C00086FFFCCFAD -:10EBF0008091C00080648093C000FE1419F00894D6 -:10EC0000C11CD11C0F5F1F4FC80181519F41A0E063 -:10EC1000B0E0ABBFFC01E790FAE2EF1621F022E092 -:10EC20000030120799F60F94DCF10F94DCF182E6C4 -:10EC300092EE60E00F94C2F1C60161E070E00F94C3 -:10EC400034F20F94DCF10F94DCF110920202109276 -:10EC50000302109204021092050278CE89E992EE26 -:10EC600062E00F94F5F1279A2F9A16C02F9880E052 -:10EC700090E0E0EDF7E03197F1F7019684369105E9 -:10EC8000C1F72F9A80E090E0E0EDF7E03197F1F7DF -:10EC9000019684369105C1F78091C00087FFE6CFC9 -:10ECA0008091C00087FFFCCF64C485EA92EE62E0E9 -:10ECB0000F94F5F140910202509103026091040219 -:10ECC0007091050281E020E10F9491F2809102029F -:10ECD00090910302A0910402B091050280509F4FD1 -:10ECE000AF4FBF4F8093020290930302A0930402A0 -:10ECF000B093050280509041A040B04008F426CE69 -:10ED0000A4CF83EB92EE62E00F94F5F140910602FE -:10ED100050910702609108027091090280E020E1A1 -:10ED20000F9491F28091060290910702A09108023F -:10ED3000B091090280509F4FAF4FBF4F80930602A2 -:10ED400090930702A0930802B0930902FFCD80ECD4 -:10ED500092EE62E00F94F5F183E792EE60E00F949B -:10ED6000F5F18FE792EE60E00F94F5F18BE892EE0B -:10ED700060E00F94F5F189E992EE60E00F94F5F10F -:10ED800085EA92EE60E00F94F5F183EB92EE60E09D -:10ED90000F94F5F180EC92EE60E00F94F5F187ECC2 -:10EDA00092EE60E00F94F5F188ED92EE60E00F9442 -:10EDB000F5F18FED92EE60E00F94F5F18AEE92EEB0 -:10EDC00060E00F94F5F183E093EEBDCD87EC92EE19 -:10EDD00062E00F94F5F181E40F947BF282E40F94EA -:10EDE0007BF283E40F947BF284E40F947BF285E45E -:10EDF0000F947BF286E40F947BF287E40F947BF20E -:10EE000088E40F947BF28AE40F947BF28BE40F94F6 -:10EE10007BF28CE40F947BF299CD88ED92EE62E068 -:10EE20000F94F5F1772473948824992409C48FED05 -:10EE300092EE62E00F94F5F140910A0250910B02BC -:10EE400060910C0270910D0282E020E10F9491F22A -:10EE500080910A0290910B02A0910C02B0910D02D8 -:10EE600080509F4FAF4FBF4F80930A0290930B0289 -:10EE7000A0930C02B0930D0269CD8AEE92EE62E08F -:10EE80000F94F5F184EE90EE60E00F94F5F18FECC5 -:10EE900091EE60E00F94F5F1662477244301CC5D98 -:10EEA000DE4F19821882C452D140D401C301B695F5 -:10EEB000A79597958795CA5DDE4F88839983AA8326 -:10EEC000BB83C652D140CC5DDE4FA881B981C4520C -:10EED000D1401196CC5DDE4FB983A883C452D14096 -:10EEE000CD0162E070E00F9434F2B0E2B093C6005E -:10EEF0008091C00086FFFCCF8091C0008064809329 -:10EF0000C000EDE2E093C6008091C00086FFFCCF18 -:10EF10008091C00080648093C000F0E2F093C6004E -:10EF20008091C00086FFFCCF8091C00080648093F8 -:10EF3000C000CA5DDE4FE880F9800A811B81C6529D -:10EF4000D140BB27A12F902F8F2D0F940DF2CA5DBA -:10EF5000DE4F8881C652D1400F940DF2B0E2FB2EF5 -:10EF6000F092C6008091C00086FFFCCF8091C00067 -:10EF700080648093C0000DE30093C6008091C000C0 -:10EF800086FFFCCF8091C00080648093C00010E2B7 -:10EF90001093C6008091C00086FFFCCF8091C00016 -:10EFA00080648093C0008BBEF3012791C65DDE4F65 -:10EFB0002883CA52D140A22EBB24CC24DD2408943D -:10EFC000611C711C811C911C8BBEF3018791282E42 -:10EFD0003324442455240894611C711C811C911C09 -:10EFE0008BBEF3013791C55DDE4F3883CB52D140E4 -:10EFF0000894611C711C811C911C8BBEF30147910C -:10F00000C45DDE4F4883CC52D140ADEFEA2EAFEF66 -:10F01000FA2EAFEF0A2FAFEF1A2F6E0C7F1C801E57 -:10F02000911E142D032DF22CEE24EA0CFB1C0C1D5A -:10F030001D1D0F940DF220E22093C6008091C000A8 -:10F0400086FFFCCF8091C00080648093C000C65DC5 -:10F05000DE4F8881CA52D1400F940DF230E23093D6 -:10F06000C6008091C00086FFFCCF8091C000806404 -:10F070008093C000C45DDE4F8881CC52D1400F9494 -:10F080000DF240E24093C6008091C00086FFFCCFA5 -:10F090008091C00080648093C000C55DDE4F888190 -:10F0A000CB52D1400F940DF250E25093C6008091A4 -:10F0B000C00086FFFCCF8091C00080648093C000B8 -:10F0C0008FEFE8168FEFF80680E0080780E018075A -:10F0D00031F484E092EE60E00F94C2F1DFC0D80119 -:10F0E000C7018070907CA070B0708050904CA040A0 -:10F0F000B040D1F52FEF3FE340E050E0E222F322B1 -:10F1000004231523CA5DDE4FA880B980CA80DB8046 -:10F11000C652D140AE0CBF1CC01ED11EAA0CBB1CD7 -:10F12000CC1CDD1C8EE092EE60E00F94C2F1BB2798 -:10F13000A12F902F8F2D0F940DF28E2D0F940DF285 -:10F1400030E23093C6008091C00086FFFCCF8091F2 -:10F15000C00080648093C0004EE34093C60080915D -:10F16000C00086FFFCCF87C08EE09EEFA0E0B0E03D -:10F17000E822F9220A231B239CE0E91694E9F90608 -:10F1800090E0090790E0190709F088C0C45DDE4FE0 -:10F19000A881CC52D140EA2EFF2400E010E0102FCD -:10F1A0000F2DFE2CEE24C55DDE4FB881CB52D14031 -:10F1B000EB0EF11C011D111DD601C501817090706F -:10F1C000A070B070DC0199278827E80EF91E0A1F8D -:10F1D0001B1F20EF30E040E050E0A222B322C42207 -:10F1E000D52241E1AA0CBB1CCC1CDD1C4A95D1F7F1 -:10F1F000EA0CFB1C0C1D1D1D81E090E0A0E0B0E0BE -:10F20000282239224A225B2235E1220C331C441C7D -:10F21000551C3A95D1F7E20CF31C041D151D57013E -:10F220006801AA0CBB1CCC1CDD1C85E192EE60E0E1 -:10F230000F94C2F1C801AA27BB270F940DF2BB2778 -:10F24000A12F902F8F2D0F940DF28E2D0F940DF274 -:10F2500090E29093C6008091C00086FFFCCF809121 -:10F26000C00080648093C000AEE3A093C60080918C -:10F27000C00086FFFCCF8091C00080648093C000F6 -:10F28000C601AA27BB270F940DF2BB27AD2D9C2DDD -:10F290008B2D0F940DF28A2D0F940DF20F94DCF14B -:10F2A000CC5DDE4FE881F981C452D140F99709F471 -:10F2B0004DCBF4E0EF2EF12C012D112D6E0C7F1CA7 -:10F2C000801E911EF2CD83E093EE62E00F94F5F183 -:10F2D0008AE192EE60E00F94C2F18091C00087FF56 -:10F2E000FCCF1091C6001F751093C6008091C0001E -:10F2F00086FFFCCF8091C00080648093C0000F9493 -:10F30000DCF1812F81548A3108F036C1163409F4BA -:10F3100095C0173490F4133409F44EC0143430F40B -:10F320001134F1F0123409F01DC130C0143409F465 -:10F3300059C0153409F016C16BC01A3409F4C4C0A1 -:10F340001B3438F4173409F48FC0183409F00AC19B -:10F35000A1C01B3409F4D2C01C3409F003C1E8C0B9 -:10F360008FEF81B90DC082B1809582B980E090E0C5 -:10F37000E0EDF7E03197F1F70196883C9105C1F790 -:10F380008091C00087FFEFCF12B8EFC08FEF84B934 -:10F390000DC085B1809585B980E090E0E0EDF7E0A3 -:10F3A0003197F1F70196883C9105C1F78091C00033 -:10F3B00087FFEFCF15B8D9C08FEF87B90DC088B1DF -:10F3C000809588B980E090E0E0EDF7E03197F1F7C3 -:10F3D0000196883C9105C1F78091C00087FFEFCF6F -:10F3E00018B8C3C08FEF8AB90DC08BB180958BB9A7 -:10F3F00080E090E0E0EDF7E03197F1F70196883C8E -:10F400009105C1F78091C00087FFEFCF1BB8ADC059 -:10F410008FEF8DB90DC08EB180958EB980E090E0F0 -:10F42000E0EDF7E03197F1F70196883C9105C1F7DF -:10F430008091C00087FFEFCF1EB897C08FEF80BBD1 -:10F440000DC081B3809581BB80E090E0E0EDF7E0F6 -:10F450003197F1F70196883C9105C1F78091C00082 -:10F4600087FFEFCF11BA81C08FEF83BB0DC084B38C -:10F47000809584BB80E090E0E0EDF7E03197F1F714 -:10F480000196883C9105C1F78091C00087FFEFCFBE -:10F4900014BA6BC08FEF809301010FC080910201FD -:10F4A00080958093020180E090E0E0EDF7E03197F5 -:10F4B000F1F70196883C9105C1F78091C00087FF64 -:10F4C000EDCF1092020151C08FEF809304010FC065 -:10F4D0008091050180958093050180E090E0E0ED4A -:10F4E000F7E03197F1F70196883C9105C1F78091DB -:10F4F000C00087FFEDCF1092050137C08FEF8093DA -:10F5000007010FC08091080180958093080180E079 -:10F5100090E0E0EDF7E03197F1F70196883C910536 -:10F52000C1F78091C00087FFEDCF109208011DC088 -:10F530008FEF80930A010FC080910B01809580931B -:10F540000B0180E090E0E0EDF7E03197F1F70196F4 -:10F55000883C9105C1F78091C00087FFEDCF1092E4 -:10F560000B0103C085E292EEEEC98091C00087FFD7 -:10F57000FCCF8091C600EAC988E392EEE4C98CE131 -:10F5800091EEE1C988249924933011F1943028F444 -:10F59000913089F09230B8F408C0953061F195301F -:10F5A000F0F0963009F048C043C02B3109F042C951 -:10F5B00091E06BE13FC96227C15DDE4F2883CF52E6 -:10F5C000D14092E037C9B22FA0E0622793E032C960 -:10F5D000822F90E0A82BB92B622794E02BC92E3004 -:10F5E00009F039C3622795E0C05DDE4F19821882A9 -:10F5F000C053D1401FC9E1E0F0E0EC0FFD1FC05D3A -:10F60000DE4F08811981C053D140E00FF11F2083E4 -:10F610000F5F1F4FC05DDE4F19830883C053D14079 -:10F6200062270A171B0709F005C9D80196E002C92D -:10F63000261709F010C303C0973009F0FBC87724E0 -:10F640009981933109F412C19431C8F4963009F4C8 -:10F65000D8C0973050F4923009F406C1933009F4C1 -:10F660006DC0913009F059C253C0913109F477C08F -:10F67000923108F0BBC0903109F04FC2F5C098310B -:10F6800009F487C0993150F4953109F4EFC09531F0 -:10F6900008F4C6C1963109F040C2C2C19A3109F4DA -:10F6A0006CC09A3108F491C09B3109F45BC09D3164 -:10F6B00009F033C29D81903359F48F81882311F46E -:10F6C0009EE11CC0813011F091E018C098E916C08D -:10F6D000892F807591F0903539F4E0E0F0E089E011 -:10F6E0008093570094910AC0983539F4E3E0F0E034 -:10F6F00089E080935700949101C090E01A821B82A8 -:10F700008D818C831D829E831F8227E030E009C299 -:10F710001A8288E08B8381E48C8386E58D8382E581 -:10F720008E8389E48F8383E5888780E589878FE5E9 -:10F730008A8782E38B872BE030E0F3C18A818139AD -:10F7400041F0823941F0803911F48FE005C080E04A -:10F7500003C082E001C08AE01A828B8344C0772410 -:10F76000739482C08D81882311F48EE12CC0813086 -:10F7700011F081E028C088E926C01A82E1E0F0E0BB -:10F7800089E08093570084918B831C8224E030E0D1 -:10F79000C8C18B81803589F48C81883039F4E2E0EE -:10F7A000F0E089E08093570084910DC0E0E0F0E044 -:10F7B00089E080935700849106C0E3E0F0E089E09F -:10F7C0008093570084911A82DFCF8D81836C99E0FA -:10F7D000E1E0F0E0082E90935700E89507B600FCB2 -:10F7E000FDCF1A821B8223E030E09BC180EC8A832C -:10F7F000CE5CDE4F188219821A821B82C253D1401E -:10F800008EC18A8190E0A0E0B0E0582F44273327D2 -:10F8100022278B8190E0A0E0B0E0DC0199278827C7 -:10F82000282B392B4A2B5B2B8D8190E0A0E0B0E098 -:10F83000282B392B4A2B5B2B8C8190E0A0E0B0E089 -:10F84000BA2FA92F982F8827282B392B4A2B5B2BCF -:10F85000220F331F441F551FC05EDE4F288339839C -:10F860004A835B83C052D1401A8259C13A81C95C34 -:10F87000DE4F3883C753D140CA5CDE4F1882C6536F -:10F88000D1408B81C82EDD24CA5CDE4F488159816E -:10F89000C653D140C42AD52A933109F082C0CE5C28 -:10F8A000DE4F88819981AA81BB81C253D1408050AB -:10F8B000904CA340B04030F583E0CE5CDE4FE88052 -:10F8C000F9800A811B81C253D140F70100935B008C -:10F8D00080935700E89507B600FCFDCFCE5CDE4F65 -:10F8E000088119812A813B81C253D14000501F4FAA -:10F8F0002F4F3F4FCE5CDE4F088319832A833B8313 -:10F90000C253D140C05EDE4F488159816A817B81FC -:10F91000C052D140DE011B9631E08C9111962C91A2 -:10F9200011971296C75CDE4F2883C953D140C85C3B -:10F93000DE4F1882C853D14090E0C85CDE4FE881AA -:10F94000F981C853D1408E2B9F2B0C01FA01609393 -:10F950005B0030935700E89511244E5F5F4F6F4F67 -:10F960007F4F0EEFE02E0FEFF02ECE0CDF1CC114F8 -:10F97000D10499F685E0C05EDE4F088119812A81A5 -:10F980003B81C052D140F80120935B008093570027 -:10F99000E89507B600FCFDCF81E180935700E8951C -:10F9A00035C0C05EDE4F88819981AA81BB81C0527B -:10F9B000D140B695A795979587957C018601ABE0D8 -:10F9C000AA2EB12CAC0EBD1E0BC0D5016D915D01F0 -:10F9D000C7010F947FFE0894E11CF11C01501040F8 -:10F9E0000115110591F7A60160E070E0440F551F65 -:10F9F000661F771FC05EDE4FE880F9800A811B8199 -:10FA0000C052D1404E0D5F1D601F711F1A82C05E33 -:10FA1000DE4F488359836A837B83C052D1407FC0C5 -:10FA2000FA80C55CDE4FF882CB53D140C65CDE4F16 -:10FA30001882CA53D1408B81C82EDD24C65CDE4FAC -:10FA400008811981CA53D140C02AD12A1A828981DA -:10FA5000BE016D5F7F4F843121F59601C05EDE4FA0 -:10FA6000E880F9800A811B81C052D1400BBFF701A9 -:10FA700087919691DB018C9311969C936E5F7F4FDB -:10FA8000D801C7010296A11DB11DC05EDE4F88835B -:10FA90009983AA83BB83C052D14022503040F1F6F3 -:10FAA00036C0C05EDE4F288139814A815B81C052F9 -:10FAB000D1400894C108D108760100E010E0089414 -:10FAC000C11CD11C0894E11CF11C011D111DE20E8A -:10FAD000F31E041F151F21BDBB27A52F942F832FB5 -:10FAE00082BD2F5F3F4F4F4F5F4FF89A80B5DB01CC -:10FAF0008D93BD012E153F054007510761F7C05E8C -:10FB0000DE4F288339834A835B83C052D1409601FC -:10FB10002D5F3F4FFB01108204C080EC8A8322E0FE -:10FB200030E08BE18093C6008091C00086FFFCCF5F -:10FB30008091C00080648093C000C15DDE4FF88179 -:10FB4000CF52D140F093C6008091C00086FFFCCF19 -:10FB50008091C00080648093C000432F3093C60022 -:10FB60008091C00086FFFCCF8091C00080648093AC -:10FB7000C000922F2093C6008091C00086FFFCCF6A -:10FB80008091C00080648093C0008EE08093C600A6 -:10FB90008091C00086FFFCCF8091C000806480937C -:10FBA000C00065E1C15DDE4FE880CF52D1406E25D7 -:10FBB00069276427FE01319610C090819093C6009A -:10FBC0008091C00086FFFCCF31968091C000806498 -:10FBD0008093C0006927215030402115310569F715 -:10FBE0006093C6008091C00086FFFCCF8091C0006A -:10FBF00080648093C00085B1805885B9772081F4F6 -:10FC0000C15DDE4F0881CF52D1400F5FC15DDE4F35 -:10FC10000883CF52D14090E0A0E0B0E00D941AF4F8 -:10FC200027982F9880E090E020ED37E0F901319798 -:10FC3000F1F7019684369105C9F700008091C00064 -:10FC40008D7F8093C00081E180935700E895EE2777 -:10FC5000FF270994FFCF90E00D941AF497FB092E2B -:10FC600007260AD077FD04D02ED006D000201AF443 -:10FC7000709561957F4F0895F6F7909581959F4F08 -:10FC80000895A1E21A2EAA1BBB1BFD010DC0AA1FDD -:10FC9000BB1FEE1FFF1FA217B307E407F50720F0F5 -:10FCA000A21BB30BE40BF50B661F771F881F991F70 -:10FCB0001A9469F760957095809590959B01AC01B9 -:10FCC000BD01CF010895AA1BBB1B51E107C0AA1FAC -:10FCD000BB1FA617B70710F0A61BB70B881F991FED -:10FCE0005A95A9F780959095BC01CD010895F99991 -:10FCF000FECF92BD81BDF89A992780B50895262F31 -:10FD0000F999FECF1FBA92BD81BD20BD0FB6F89400 -:0EFD1000FA9AF99A0FBE01960895F894FFCF63 -:00000001FF diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h deleted file mode 100644 index a239ee4..0000000 --- a/Marlin/Configuration.h +++ /dev/null @@ -1,3166 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CONFIG_EXAMPLES_DIR "FlashForge/CreatorPro" - -/** - * 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 - */ -#define CONFIGURATION_H_VERSION 02000905 - -//=========================================================================== -//============================= Getting Started ============================= -//=========================================================================== - -/** - * Here are some useful links to help get your machine configured and calibrated: - * - * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all - * - * Průša Calculator: https://blog.prusaprinters.org/calculator_3416/ - * - * Calibration Guides: https://reprap.org/wiki/Calibration - * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide - * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap - * https://youtu.be/wAL9d7FgInk - * - * Calibration Objects: https://www.thingiverse.com/thing:5573 - * https://www.thingiverse.com/thing:1278865 - */ - -// @section info - -// Author info of this build printed to the host during boot and M115 -#define STRING_CONFIG_H_AUTHOR "M. Baker" // Who made the changes. -//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) - -/** - * *** VENDORS PLEASE READ *** - * - * Marlin allows you to add a custom boot image for Graphical LCDs. - * With this option Marlin will first show your custom screen followed - * by the standard Marlin logo with version number and web URL. - * - * We encourage you to take advantage of this new feature and we also - * respectfully request that you retain the unmodified Marlin boot screen. - */ - -// Show the Marlin bootscreen on startup. ** ENABLE FOR PRODUCTION ** -#define SHOW_BOOTSCREEN - -// Show the bitmap in Marlin/_Bootscreen.h on startup. -//#define SHOW_CUSTOM_BOOTSCREEN - -// Show the bitmap in Marlin/_Statusscreen.h on the status screen. -//#define CUSTOM_STATUS_SCREEN_IMAGE - -// @section machine - -// Choose the name from boards.h that matches your setup -#ifndef MOTHERBOARD - #define MOTHERBOARD BOARD_MKS_GEN_L_V21 -#endif - -/** - * Select the serial port on the board to use for communication with the host. - * This allows the connection of wireless adapters (for instance) to non-default port pins. - * Serial port -1 is the USB emulated serial port, if available. - * Note: The first serial port (-1 or 0) will always be used by the Arduino bootloader. - * - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -#define SERIAL_PORT 0 - -/** - * Serial Port Baud Rate - * This is the default communication speed for all serial ports. - * Set the baud rate defaults for additional serial ports below. - * - * 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 9600 -//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate - -/** - * Select a secondary serial port on the board to use for communication with the host. - * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. - * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -//#define SERIAL_PORT_2 -1 -//#define BAUDRATE_2 250000 // Enable to override BAUDRATE - -/** - * Select a third serial port on the board to use for communication with the host. - * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1 - * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] - */ -//#define SERIAL_PORT_3 1 -//#define BAUDRATE_3 250000 // Enable to override BAUDRATE - -// Enable the Bluetooth serial interface on AT90USB devices -//#define BLUETOOTH - -// Name displayed in the LCD "Ready" message and Info menu -#define CUSTOM_MACHINE_NAME "Makerbot Replicator" - -// Printer's unique ID, used by some programs to differentiate between machines. -// Choose your own or use a service like https://www.uuidgenerator.net/version4 -//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000" - -/** - * Stepper Drivers - * - * These settings allow Marlin to tune stepper driver timing and enable advanced options for - * stepper drivers that support them. You may also override timing options in Configuration_adv.h. - * - * Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers. - * - * Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01, - * TB6560, TB6600, TMC2100, - * TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE, - * TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE, - * TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE, - * TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE - * :['A4988', 'A5984', 'DRV8825', 'LV8729', 'L6470', 'L6474', 'POWERSTEP01', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE'] - */ -#define X_DRIVER_TYPE TMC2209_STANDALONE -#define Y_DRIVER_TYPE TMC2209_STANDALONE -#define Z_DRIVER_TYPE TMC2209_STANDALONE -//#define X2_DRIVER_TYPE A4988 -//#define Y2_DRIVER_TYPE A4988 -//#define Z2_DRIVER_TYPE A4988 -//#define Z3_DRIVER_TYPE A4988 -//#define Z4_DRIVER_TYPE A4988 -//#define I_DRIVER_TYPE A4988 -//#define J_DRIVER_TYPE A4988 -//#define K_DRIVER_TYPE A4988 -#define E0_DRIVER_TYPE TMC2209_STANDALONE -#define E1_DRIVER_TYPE TMC2209_STANDALONE -//#define E2_DRIVER_TYPE A4988 -//#define E3_DRIVER_TYPE A4988 -//#define E4_DRIVER_TYPE A4988 -//#define E5_DRIVER_TYPE A4988 -//#define E6_DRIVER_TYPE A4988 -//#define E7_DRIVER_TYPE A4988 - -/** - * Additional Axis Settings - * - * AXISn_NAME defines the letter used to refer to the axis in (most) G-code commands. - * By convention the names and roles are typically: - * 'A' : Rotational axis parallel to X - * 'B' : Rotational axis parallel to Y - * 'C' : Rotational axis parallel to Z - * 'U' : Secondary linear axis parallel to X - * 'V' : Secondary linear axis parallel to Y - * 'W' : Secondary linear axis parallel to Z - * - * Regardless of these settings the axes are internally named I, J, K. - */ -#ifdef I_DRIVER_TYPE - #define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W'] -#endif -#ifdef J_DRIVER_TYPE - #define AXIS5_NAME 'B' // :['B', 'C', 'U', 'V', 'W'] -#endif -#ifdef K_DRIVER_TYPE - #define AXIS6_NAME 'C' // :['C', 'U', 'V', 'W'] -#endif - -// @section extruder - -// This defines the number of extruders -// :[0, 1, 2, 3, 4, 5, 6, 7, 8] -#define EXTRUDERS 2 - -// Generally expected filament diameter (1.75, 2.85, 3.0, ...). Used for Volumetric, Filament Width Sensor, etc. -#define DEFAULT_NOMINAL_FILAMENT_DIA 1.75 - -// For Cyclops or any "multi-extruder" that shares a single nozzle. -//#define SINGLENOZZLE - -// Save and restore temperature and fan speed on tool-change. -// Set standby for the unselected tool with M104/106/109 T... -#if ENABLED(SINGLENOZZLE) - //#define SINGLENOZZLE_STANDBY_TEMP - //#define SINGLENOZZLE_STANDBY_FAN -#endif - -/** - * Multi-Material Unit - * Set to one of these predefined models: - * - * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version) - * PRUSA_MMU2 : Průša MMU2 - * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5) - * EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) - * EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware) - * - * Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails. - * See additional options in Configuration_adv.h. - */ -//#define MMU_MODEL PRUSA_MMU2 - -// 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 (or both) of the nozzles -//#define SWITCHING_NOZZLE -#if ENABLED(SWITCHING_NOZZLE) - #define SWITCHING_NOZZLE_SERVO_NR 0 - //#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second - #define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 (single servo) or lowered/raised (dual servo) -#endif - -/** - * Two separate X-carriages with extruders that connect to a moving part - * via a solenoid docking mechanism. Requires SOL1_PIN and SOL2_PIN. - */ -//#define PARKING_EXTRUDER - -/** - * Two separate X-carriages with extruders that connect to a moving part - * via a magnetic docking mechanism using movements and no solenoid - * - * project : https://www.thingiverse.com/thing:3080893 - * movements : https://youtu.be/0xCEiG9VS3k - * https://youtu.be/Bqbcs0CU2FE - */ -//#define MAGNETIC_PARKING_EXTRUDER - -#if EITHER(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER) - - #define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders - #define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the 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 // (ms) Delay for magnetic field. No delay if 0 or not defined. - //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381 - - #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) - - #define MPE_FAST_SPEED 9000 // (mm/min) Speed for travel before last distance point - #define MPE_SLOW_SPEED 4500 // (mm/min) Speed for last distance travel to park and couple - #define MPE_TRAVEL_DISTANCE 10 // (mm) Last distance point - #define MPE_COMPENSATION 0 // Offset Compensation -1 , 0 , 1 (multiplier) only for coupling - - #endif - -#endif - -/** - * Switching Toolhead - * - * Support for swappable and dockable toolheads, such as - * the E3D Tool Changer. Toolheads are locked with a servo. - */ -//#define SWITCHING_TOOLHEAD - -/** - * Magnetic Switching Toolhead - * - * Support swappable and dockable toolheads with a magnetic - * docking mechanism using movement and no servo. - */ -//#define MAGNETIC_SWITCHING_TOOLHEAD - -/** - * Electromagnetic Switching Toolhead - * - * Parking for CoreXY / HBot kinematics. - * Toolheads are parked at one edge and held with an electromagnet. - * Supports more than 2 Toolheads. See https://youtu.be/JolbsAKTKf4 - */ -//#define ELECTROMAGNETIC_SWITCHING_TOOLHEAD - -#if ANY(SWITCHING_TOOLHEAD, MAGNETIC_SWITCHING_TOOLHEAD, ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Y_POS 235 // (mm) Y position of the toolhead dock - #define SWITCHING_TOOLHEAD_Y_SECURITY 10 // (mm) Security distance Y axis - #define SWITCHING_TOOLHEAD_Y_CLEAR 60 // (mm) Minimum distance from dock for unobstructed X axis - #define SWITCHING_TOOLHEAD_X_POS { 215, 0 } // (mm) X positions for parking the extruders - #if ENABLED(SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_SERVO_NR 2 // Index of the servo connector - #define SWITCHING_TOOLHEAD_SERVO_ANGLES { 0, 180 } // (degrees) Angles for Lock, Unlock - #elif ENABLED(MAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Y_RELEASE 5 // (mm) Security distance Y axis - #define SWITCHING_TOOLHEAD_X_SECURITY { 90, 150 } // (mm) Security distance X axis (T0,T1) - //#define PRIME_BEFORE_REMOVE // Prime the nozzle before release from the dock - #if ENABLED(PRIME_BEFORE_REMOVE) - #define SWITCHING_TOOLHEAD_PRIME_MM 20 // (mm) Extruder prime length - #define SWITCHING_TOOLHEAD_RETRACT_MM 10 // (mm) Retract after priming length - #define SWITCHING_TOOLHEAD_PRIME_FEEDRATE 300 // (mm/min) Extruder prime feedrate - #define SWITCHING_TOOLHEAD_RETRACT_FEEDRATE 2400 // (mm/min) Extruder retract feedrate - #endif - #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - #define SWITCHING_TOOLHEAD_Z_HOP 2 // (mm) Z raise for switching - #endif -#endif - -/** - * "Mixing Extruder" - * - Adds G-codes M163 and M164 to set and "commit" the current mix factors. - * - Extends the stepping routines to move multiple steppers in proportion to the mix. - * - Optional support for Repetier Firmware's 'M164 S' supporting virtual tools. - * - This implementation supports up to two mixing extruders. - * - Enable DIRECT_MIXING_IN_G1 for M165 and mixing in G1 (from 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 - //#define GRADIENT_MIX // Support for gradient mixing with M166 and LCD - //#define MIXING_PRESETS // Assign 8 default V-tool presets for 2 or 3 MIXING_STEPPERS - #if ENABLED(GRADIENT_MIX) - //#define GRADIENT_VTOOL // Add M166 T to use a V-tool index as a Gradient alias - #endif -#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, -34.00 } // (mm) relative X-offset for each nozzle -//#define HOTEND_OFFSET_Y { 0.0, 0.00 } // (mm) relative Y-offset for each nozzle -//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle - -// @section machine - -/** - * Power Supply Control - * - * Enable and connect the power supply to the PS_ON_PIN. - * Specify whether the power supply is active HIGH or active LOW. - */ -//#define PSU_CONTROL -//#define PSU_NAME "Power Supply" - -#if ENABLED(PSU_CONTROL) - //#define MKS_PWC // Using the MKS PWC add-on - //#define PS_OFF_CONFIRM // Confirm dialog when power off - //#define PS_OFF_SOUND // Beep 1s when power off - #define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box - - //#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80 - //#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power - //#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay - - //#define POWER_OFF_TIMER // Enable M81 D to power off after a delay - //#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown - - //#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on) - //#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off) - - //#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin - #if ENABLED(AUTO_POWER_CONTROL) - #define AUTO_POWER_FANS // Turn on PSU if fans need power - #define AUTO_POWER_E_FANS - #define AUTO_POWER_CONTROLLERFAN - #define AUTO_POWER_CHAMBER_FAN - #define AUTO_POWER_COOLER_FAN - #define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration - //#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time. - #endif - #if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) - //#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature - //#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature - //#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature - #endif -#endif - -//=========================================================================== -//============================= Thermal Settings ============================ -//=========================================================================== -// @section temperature - -/** - * --NORMAL IS 4.7kΩ PULLUP!-- 1kΩ pullup can be used on hotend sensor, using correct resistor and table - * - * Temperature sensors available: - * - * SPI RTD/Thermocouple Boards - IMPORTANT: Read the NOTE below! - * ------- - * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-1) - * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below. - * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-1) - * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-1) - * - * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default, - * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN, - * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the - * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported. - * - * Analog Themocouple Boards - * ------- - * -4 : AD8495 with Thermocouple - * -1 : AD595 with Thermocouple - * - * Analog Thermistors - 4.7kΩ pullup - Normal - * ------- - * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors - * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA - * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE - * 2 : 200kΩ ATC Semitec 204GT-2 - * 202 : 200kΩ Copymaster 3D - * 3 : ???Ω Mendel-parts thermistor - * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !! - * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C - * 501 : 100kΩ Zonestar - Tronxy X3A - * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M - * 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor - * 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor - * 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor - * 512 : 100kΩ RPW-Ultra hotend - * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple) - * 7 : 100kΩ Honeywell 135-104LAG-J01 - * 71 : 100kΩ Honeywell 135-104LAF-J01 - * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT - * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1 - * 10 : 100kΩ RS PRO 198-961 - * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1% - * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed - * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1% - * 15 : 100kΩ Calibrated for JGAurora A5 hotend - * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327 - * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input - * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input - * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950 - * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950 - * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950 - * 66 : 4.7MΩ Dyze Design High Temperature Thermistor - * 67 : 500kΩ SliceEngineering 450°C Thermistor - * 68 : PT100 amplifier board from Dyze Design - * 70 : 100kΩ bq Hephestos 2 - * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32 - * 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor - * - * Analog Thermistors - 1kΩ pullup - Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ. - * ------- (but gives greater accuracy and more stable PID) - * 51 : 100kΩ EPCOS (1kΩ pullup) - * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup) - * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup) - * - * Analog Thermistors - 10kΩ pullup - Atypical - * ------- - * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor - * - * Analog RTDs (Pt100/Pt1000) - * ------- - * 110 : Pt100 with 1kΩ pullup (atypical) - * 147 : Pt100 with 4.7kΩ pullup - * 1010 : Pt1000 with 1kΩ pullup (atypical) - * 1047 : Pt1000 with 4.7kΩ pullup (E3D) - * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage. - * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21. - * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply. - * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C. - * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x - * - * Custom/Dummy/Other Thermal Sensors - * ------ - * 0 : not used - * 1000 : Custom - Specify parameters in Configuration_adv.h - * - * !!! 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. - * - */ -#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_5 0 -#define TEMP_SENSOR_6 0 -#define TEMP_SENSOR_7 0 -#define TEMP_SENSOR_BED 1 -#define TEMP_SENSOR_PROBE 0 -#define TEMP_SENSOR_CHAMBER 0 -#define TEMP_SENSOR_COOLER 0 -#define TEMP_SENSOR_BOARD 0 -#define TEMP_SENSOR_REDUNDANT 0 - -// Dummy thermistor constant temperature readings, for use with 998 and 999 -#define DUMMY_THERMISTOR_998_VALUE 25 -#define DUMMY_THERMISTOR_999_VALUE 100 - -// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1 -//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000) -//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000 -//#define MAX31865_SENSOR_OHMS_1 100 -//#define MAX31865_CALIBRATION_OHMS_1 430 - -#define TEMP_RESIDENCY_TIME 0 // (seconds) Time to wait for hotend to "settle" in M109 -#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -#define TEMP_BED_RESIDENCY_TIME 0 // (seconds) Time to wait for bed to "settle" in M190 -#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191 -#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer -#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target - -/** - * Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT) - * - * Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another - * sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C), - * the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting - * the Bed sensor (-1) will disable bed heating/monitoring. - * - * For selecting source/target use: COOLER, PROBE, BOARD, CHAMBER, BED, E0, E1, E2, E3, E4, E5, E6, E7 - */ -#if TEMP_SENSOR_REDUNDANT - #define TEMP_SENSOR_REDUNDANT_SOURCE E1 // The sensor that will provide the redundant reading. - #define TEMP_SENSOR_REDUNDANT_TARGET E0 // The sensor that we are providing a redundant reading for. - #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort. -#endif - -// Below this temperature the heater will be switched off -// because it probably indicates a broken thermistor wire. -#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 HEATER_5_MINTEMP 5 -#define HEATER_6_MINTEMP 5 -#define HEATER_7_MINTEMP 5 -#define BED_MINTEMP 5 -#define CHAMBER_MINTEMP 5 - -// Above this temperature the heater will be switched off. -// This can protect components from overheating, but NOT from shorts and failures. -// (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 HEATER_5_MAXTEMP 260 -#define HEATER_6_MAXTEMP 260 -#define HEATER_7_MAXTEMP 260 -#define BED_MAXTEMP 110 -#define CHAMBER_MAXTEMP 60 - -/** - * Thermal Overshoot - * During heatup (and printing) the temperature can often "overshoot" the target by many degrees - * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees - * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP. - */ -#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT -#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT -#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT - -//=========================================================================== -//============================= PID Settings ================================ -//=========================================================================== - -// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model. -// temperature control. Disable both for bang-bang heating. -#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning -//#define MPCTEMP // ** EXPERIMENTAL ** - -#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current -#define PID_K1 0.95 // Smoothing factor within any PID loop - -#if ENABLED(PIDTEMP) - //#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders) - // Set/get with G-code: M301 E[extruder number, 0-2] - - #if ENABLED(PID_PARAMS_PER_HOTEND) - // Specify up to one value per hotend here, according to your setup. - // If there are fewer values, the last one applies to the remaining hotends. - #define DEFAULT_Kp_LIST { 20.03, 20.03 } - #define DEFAULT_Ki_LIST { 1.22, 1.22 } - #define DEFAULT_Kd_LIST { 82.05, 82.05 } - #else - #define DEFAULT_Kp 20.03 - #define DEFAULT_Ki 1.22 - #define DEFAULT_Kd 82.05 - #endif -#endif - -/** - * Model Predictive Control for hotend - * - * Use a physical model of the hotend to control temperature. When configured correctly - * this gives better responsiveness and stability than PID and it also removes the need - * for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 T to autotune the model. - */ -#if ENABLED(MPCTEMP) - //#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash) - //#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash) - - #define MPC_MAX BANG_MAX // (0..255) Current to nozzle while MPC is active. - #define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers. - - #define MPC_INCLUDE_FAN // Model the fan speed? - - // Measured physical constants from M306 - #define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities. - #define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block. - #define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off. - #if ENABLED(MPC_INCLUDE_FAN) - #define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full. - #endif - - // For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect. - #if ENABLED(MPC_INCLUDE_FAN) - //#define MPC_FAN_0_ALL_HOTENDS - //#define MPC_FAN_0_ACTIVE_HOTEND - #endif - - #define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA). - //#define FILAMENT_HEAT_CAPACITY_PERMM { 3.6e-3f } // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG). - - // Advanced options - #define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization. - #define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies. - #define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced. - - #define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height. - #define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position. -#endif - -//=========================================================================== -//====================== PID > Bed Temperature Control ====================== -//=========================================================================== - -/** - * PID Bed Heating - * - * If this option is enabled set PID constants below. - * If this option is disabled, bang-bang will be used and BED_LIMIT_SWITCHING will enable hysteresis. - * - * The PID frequency will be the same as the extruder PWM. - * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, - * which is fine for driving a square wave into a resistive load and does not significantly - * impact 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, don't use bed PID until someone else verifies that your hardware works. - */ -//#define PIDTEMPBED - -//#define BED_LIMIT_SWITCHING - -/** - * Max Bed Power - * Applies to all forms of bed control (PID, bang-bang, and bang-bang with hysteresis). - * When set to any value below 255, enables a form of PWM to the bed that acts like a divider - * so don'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 MIN_BED_POWER 0 - //#define PID_BED_DEBUG // Sends debug data to the serial port. - - // 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+) - // from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10) - #define DEFAULT_bedKp 10.00 - #define DEFAULT_bedKi .023 - #define DEFAULT_bedKd 305.4 - - // FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles. -#endif // PIDTEMPBED - -//=========================================================================== -//==================== PID > Chamber Temperature Control ==================== -//=========================================================================== - -/** - * PID Chamber Heating - * - * If this option is enabled set PID constants below. - * If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable - * hysteresis. - * - * The PID frequency will be the same as the extruder PWM. - * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz, - * which is fine for driving a square wave into a resistive load and does not significantly - * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W - * heater. If your configuration is significantly different than this and you don't understand - * the issues involved, don't use chamber PID until someone else verifies that your hardware works. - */ -//#define PIDTEMPCHAMBER -//#define CHAMBER_LIMIT_SWITCHING - -/** - * Max Chamber Power - * Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis). - * When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider - * so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER) - */ -#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current - -#if ENABLED(PIDTEMPCHAMBER) - #define MIN_CHAMBER_POWER 0 - //#define PID_CHAMBER_DEBUG // Sends debug data to the serial port. - - // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element - // and placed inside the small Creality printer enclosure tent. - // - #define DEFAULT_chamberKp 37.04 - #define DEFAULT_chamberKi 1.40 - #define DEFAULT_chamberKd 655.17 - // M309 P37.04 I1.04 D655.17 - - // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles. -#endif // PIDTEMPCHAMBER - -#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER) - //#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation. - //#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX - //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay - #define PID_FUNCTIONAL_RANGE 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 PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) - //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) -#endif - -// @section extruder - -/** - * Prevent extrusion if the temperature is below EXTRUDE_MINTEMP. - * Add M302 to set the minimum extrusion temperature and/or turn - * cold extrusion prevention on and off. - * - * *** IT IS HIGHLY RECOMMENDED TO LEAVE THIS OPTION ENABLED! *** - */ -#define PREVENT_COLD_EXTRUSION -#define EXTRUDE_MINTEMP 170 - -/** - * Prevent a single extrusion longer than EXTRUDE_MAXLENGTH. - * Note: For Bowden Extruders make this large enough to allow load/unload. - */ -#define PREVENT_LENGTHY_EXTRUDE -#define EXTRUDE_MAXLENGTH 200 - -//=========================================================================== -//======================== Thermal Runaway Protection ======================= -//=========================================================================== - -/** - * Thermal Protection provides additional protection to your printer from damage - * and fire. Marlin always includes safe min and max temperature ranges which - * protect against a broken or disconnected thermistor wire. - * - * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the 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 -#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber -#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling - -//=========================================================================== -//============================= Mechanical Settings ========================= -//=========================================================================== - -// @section machine - -// Enable one of the options below for CoreXY, CoreXZ, or CoreYZ kinematics, -// either in the usual order or reversed -//#define COREXY -//#define COREXZ -//#define COREYZ -//#define COREYX -//#define COREZX -//#define COREZY -//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042 -//#define MARKFORGED_YX - -// Enable for a belt style printer with endless "Z" motion -//#define BELTPRINTER - -// Enable for Polargraph Kinematics -//#define POLARGRAPH -#if ENABLED(POLARGRAPH) - #define POLARGRAPH_MAX_BELT_LEN 1035.0 - #define POLAR_SEGMENTS_PER_SECOND 5 -#endif - -// Enable for DELTA kinematics and configure below -//#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 EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU) - // Set the steprate for papertest probing - #define PROBE_MANUALLY_STEP 0.05 // (mm) - #endif - - // Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers). - #define DELTA_PRINTABLE_RADIUS 140.0 // (mm) - - // Maximum reachable area - #define DELTA_MAX_RADIUS 140.0 // (mm) - - // Center-to-center distance of the holes in the diagonal push rods. - #define DELTA_DIAGONAL_ROD 250.0 // (mm) - - // Distance between bed and nozzle Z home position - #define DELTA_HEIGHT 250.00 // (mm) Get this value from G33 auto calibrate - - #define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // Get these values from G33 auto calibrate - - // Horizontal distance bridged by diagonal push rods when effector is centered. - #define DELTA_RADIUS 124.0 // (mm) Get this value from G33 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 G33 auto calibrate - - // Delta radius and diagonal rod adjustments (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 - -/** - * MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013. - * Implemented and slightly reworked by JCERNY in June, 2014. - * - * Mostly Printed SCARA is an open source design by Tyler Williams. See: - * https://www.thingiverse.com/thing:2487048 - * https://www.thingiverse.com/thing:1241491 - */ -//#define MORGAN_SCARA -//#define MP_SCARA -#if EITHER(MORGAN_SCARA, MP_SCARA) - // 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) - - #if ENABLED(MORGAN_SCARA) - - //#define DEBUG_SCARA_KINEMATICS - #define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly - - // Radius around the center where the arm cannot reach - #define MIDDLE_DEAD_ZONE_R 0 // (mm) - - #define THETA_HOMING_OFFSET 0 // Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - #define PSI_HOMING_OFFSET 0 // Calculated from Calibration Guide and M364 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - - #elif ENABLED(MP_SCARA) - - #define SCARA_OFFSET_THETA1 12 // degrees - #define SCARA_OFFSET_THETA2 131 // degrees - - #endif - -#endif - -// Enable for TPARA kinematics and configure below -//#define AXEL_TPARA -#if ENABLED(AXEL_TPARA) - #define DEBUG_ROBOT_KINEMATICS - #define ROBOT_SEGMENTS_PER_SECOND 200 - - // Length of inner and outer support arms. Measure arm lengths precisely. - #define ROBOT_LINKAGE_1 120 // (mm) - #define ROBOT_LINKAGE_2 120 // (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 ROBOT_OFFSET_X 0 // (mm) - #define ROBOT_OFFSET_Y 0 // (mm) - #define ROBOT_OFFSET_Z 0 // (mm) - - #define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly - - // Radius around the center where the arm cannot reach - #define MIDDLE_DEAD_ZONE_R 0 // (mm) - - // Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073 - #define THETA_HOMING_OFFSET 0 - #define PSI_HOMING_OFFSET 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_IMIN_PLUG -//#define USE_JMIN_PLUG -//#define USE_KMIN_PLUG -#define USE_XMAX_PLUG -#define USE_YMAX_PLUG -//#define USE_ZMAX_PLUG -//#define USE_IMAX_PLUG -//#define USE_JMAX_PLUG -//#define USE_KMAX_PLUG - -// Enable pullup for all endstops to prevent a floating state -#define ENDSTOPPULLUPS -#if DISABLED(ENDSTOPPULLUPS) - // Disable ENDSTOPPULLUPS to set pullups individually - //#define ENDSTOPPULLUP_XMIN - //#define ENDSTOPPULLUP_YMIN - //#define ENDSTOPPULLUP_ZMIN - //#define ENDSTOPPULLUP_IMIN - //#define ENDSTOPPULLUP_JMIN - //#define ENDSTOPPULLUP_KMIN - //#define ENDSTOPPULLUP_XMAX - //#define ENDSTOPPULLUP_YMAX - //#define ENDSTOPPULLUP_ZMAX - //#define ENDSTOPPULLUP_IMAX - //#define ENDSTOPPULLUP_JMAX - //#define ENDSTOPPULLUP_KMAX - //#define ENDSTOPPULLUP_ZMIN_PROBE -#endif - -// Enable pulldown for all endstops to prevent a floating state -//#define ENDSTOPPULLDOWNS -#if DISABLED(ENDSTOPPULLDOWNS) - // Disable ENDSTOPPULLDOWNS to set pulldowns individually - //#define ENDSTOPPULLDOWN_XMIN - //#define ENDSTOPPULLDOWN_YMIN - //#define ENDSTOPPULLDOWN_ZMIN - //#define ENDSTOPPULLDOWN_IMIN - //#define ENDSTOPPULLDOWN_JMIN - //#define ENDSTOPPULLDOWN_KMIN - //#define ENDSTOPPULLDOWN_XMAX - //#define ENDSTOPPULLDOWN_YMAX - //#define ENDSTOPPULLDOWN_ZMAX - //#define ENDSTOPPULLDOWN_IMAX - //#define ENDSTOPPULLDOWN_JMAX - //#define ENDSTOPPULLDOWN_KMAX - //#define ENDSTOPPULLDOWN_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 I_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define J_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define K_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 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 I_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define J_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop. -#define K_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 - -/** - * Endstop Noise Threshold - * - * Enable if your probe or endstops falsely trigger due to noise. - * - * - Higher values may affect repeatability or accuracy of some bed probes. - * - To fix noise install a 100nF ceramic capacitor in parallel with the switch. - * - This feature is not required for common micro-switches mounted on PCBs - * based on the Makerbot design, which already have the 100nF capacitor. - * - * :[2,3,4,5,6,7] - */ -//#define ENDSTOP_NOISE_THRESHOLD 2 - -// Check for stuck or disconnected endstops during homing moves. -//#define DETECT_BROKEN_ENDSTOP - -//============================================================================= -//============================== 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 [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 94.139704, 94.139704, 400, 96.275201870 } - -/** - * Default Max Feed Rate (mm/s) - * Override with M203 - * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_MAX_FEEDRATE { 250, 250, 20, 100 } - -//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2 -#if ENABLED(LIMITED_MAX_FR_EDITING) - #define MAX_FEEDRATE_EDIT_VALUES { 600, 600, 10, 50 } // ...or, set your own edit limits -#endif - -/** - * Default Max Acceleration (change/s) change = mm/s - * (Maximum start speed for accelerated moves) - * Override with M201 - * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]] - */ -#define DEFAULT_MAX_ACCELERATION { 1000, 1000, 100, 5000 } - -//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2 -#if ENABLED(LIMITED_MAX_ACCEL_EDITING) - #define MAX_ACCEL_EDIT_VALUES { 6000, 6000, 200, 20000 } // ...or, set your own edit limits -#endif - -/** - * Default Acceleration (change/s) change = mm/s - * Override with M204 - * - * M204 P Acceleration - * M204 R Retract Acceleration - * M204 T Travel Acceleration - */ -#define DEFAULT_ACCELERATION 250 // X, Y, Z ... and E acceleration for printing moves -#define DEFAULT_RETRACT_ACCELERATION 5000 // E acceleration for retracts -#define DEFAULT_TRAVEL_ACCELERATION 500 // X, Y, Z ... acceleration for travel (non printing) moves - -/** - * Default Jerk limits (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 CLASSIC_JERK -#if ENABLED(CLASSIC_JERK) -#define DEFAULT_XJERK 20.0 -#define DEFAULT_YJERK 20.0 -#define DEFAULT_ZJERK 0.4 - //#define DEFAULT_IJERK 0.3 - //#define DEFAULT_JJERK 0.3 - //#define DEFAULT_KJERK 0.3 - - //#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves - - //#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2 - #if ENABLED(LIMITED_JERK_EDITING) - #define MAX_JERK_EDIT_VALUES { 20, 20, 0.6, 10 } // ...or, set your own edit limits - #endif -#endif - -#define DEFAULT_EJERK 2.0 // May be used by Linear Advance - -/** - * Junction Deviation Factor - * - * See: - * https://reprap.org/forum/read.php?1,739819 - * https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html - */ -#if DISABLED(CLASSIC_JERK) - #define JUNCTION_DEVIATION_MM 0.64 // (mm) Distance from real junction edge - #define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle - // for small segments (< 1mm) with large junction angles (> 135°). -#endif - -/** - * S-Curve Acceleration - * - * This option eliminates vibration during printing by fitting a Bézier - * curve to move acceleration, producing much smoother direction changes. - * - * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained - */ -#define S_CURVE_ACCELERATION - -//=========================================================================== -//============================= Z Probe Options ============================= -//=========================================================================== -// @section probes - -// -// See https://marlinfw.org/docs/configuration/probes.html -// - -/** - * Enable this option for a probe connected to the Z-MIN pin. - * The probe replaces the Z-MIN endstop and is used for Z homing. - * (Automatically enables USE_PROBE_FOR_Z_HOMING.) - */ -#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN - -// Force the use of the probe for Z-axis homing -//#define USE_PROBE_FOR_Z_HOMING - -/** - * Z_MIN_PROBE_PIN - * - * Define this pin if the probe is not connected to Z_MIN_PIN. - * If not defined the default pin for the selected MOTHERBOARD - * will be used. Most of the time the default is what you want. - * - * - 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. - */ -//#define Z_MIN_PROBE_PIN 32 // Pin 32 is the RAMPS default - -/** - * 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 - -/** - * Use the nozzle as the probe, as with a conductive - * nozzle system or a piezo-electric smart effector. - */ -//#define NOZZLE_AS_PROBE - -/** - * Z Servo Probe, such as an endstop switch on a rotating arm. - */ -//#define Z_PROBE_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 - -/** - * MagLev V4 probe by MDD - * - * This probe is deployed and activated by powering a built-in electromagnet. - */ -//#define MAGLEV4 -#if ENABLED(MAGLEV4) - //#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output - #define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil -#endif - -/** - * Touch-MI Probe by hotends.fr - * - * This probe is deployed and activated by moving the X-axis to a magnet at the edge of the bed. - * By default, the magnet is assumed to be on the left and activated by a home. If the magnet is - * on the right, enable and set TOUCH_MI_DEPLOY_XPOS to the deploy position. - * - * Also requires: BABYSTEPPING, BABYSTEP_ZPROBE_OFFSET, Z_SAFE_HOMING, - * and a minimum Z_HOMING_HEIGHT of 10. - */ -//#define TOUCH_MI_PROBE -#if ENABLED(TOUCH_MI_PROBE) - #define TOUCH_MI_RETRACT_Z 0.5 // Height at which the probe retracts - //#define TOUCH_MI_DEPLOY_XPOS (X_MAX_BED + 2) // For a magnet on the right side of the bed - //#define TOUCH_MI_MANUAL_DEPLOY // For manual deploy (LCD menu) -#endif - -// 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. - -// A probe deployed by moving the x-axis, such as the Wilson II's rack-and-pinion probe designed by Marty Rice. -//#define RACK_AND_PINION_PROBE -#if ENABLED(RACK_AND_PINION_PROBE) - #define Z_PROBE_DEPLOY_X X_MIN_POS - #define Z_PROBE_RETRACT_X X_MAX_POS -#endif - -// Duet Smart Effector (for delta printers) - https://bit.ly/2ul5U7J -// When the pin is defined you can use M672 to set/reset the probe sensitivity. -//#define DUET_SMART_EFFECTOR -#if ENABLED(DUET_SMART_EFFECTOR) - #define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin -#endif - -/** - * Use StallGuard2 to probe the bed with the nozzle. - * Requires stallGuard-capable Trinamic stepper drivers. - * CAUTION: This can damage machines with Z lead screws. - * Take extreme care when setting up this feature. - */ -//#define SENSORLESS_PROBING - -/** - * Allen key retractable z-probe as seen on many Kossel delta printers - https://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe - * Deploys by touching z-axis belt. Retracts by pushing the probe down. - */ -//#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 { 30.0, DELTA_PRINTABLE_RADIUS, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_DEPLOY_2 { 0.0, DELTA_PRINTABLE_RADIUS, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 - - #define Z_PROBE_ALLEN_KEY_DEPLOY_3 { 0.0, (DELTA_PRINTABLE_RADIUS) * 0.75, 100.0 } - #define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_1 { -64.0, 56.0, 23.0 } // Move the probe into position - #define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_2 { -64.0, 56.0, 3.0 } // Push it down - #define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_FEEDRATE)/10 - - #define Z_PROBE_ALLEN_KEY_STOW_3 { -64.0, 56.0, 50.0 } // Move it up to clear - #define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_FEEDRATE - - #define Z_PROBE_ALLEN_KEY_STOW_4 { 0.0, 0.0, 50.0 } - #define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_FEEDRATE - -#endif // Z_PROBE_ALLEN_KEY - -/** - * Nozzle-to-Probe offsets { X, Y, Z } - * - * X and Y offset - * Use a caliper or ruler to measure the distance from the tip of - * the Nozzle to the center-point of the Probe in the X and Y axes. - * - * Z offset - * - For the Z offset use your best known value and adjust at runtime. - * - Common probes trigger below the nozzle and have negative values for Z offset. - * - Probes triggering above the nozzle height are uncommon but do exist. When using - * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES - * to avoid collisions during probing. - * - * Tune and Adjust - * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc. - * - PROBE_OFFSET_WIZARD (configuration_adv.h) can be used for setting the Z offset. - * - * Assuming the typical work area orientation: - * - Probe to RIGHT of the Nozzle has a Positive X offset - * - Probe to LEFT of the Nozzle has a Negative X offset - * - Probe in BACK of the Nozzle has a Positive Y offset - * - Probe in FRONT of the Nozzle has a Negative Y offset - * - * Some examples: - * #define NOZZLE_TO_PROBE_OFFSET { 10, 10, -1 } // Example "1" - * #define NOZZLE_TO_PROBE_OFFSET {-10, 5, -1 } // Example "2" - * #define NOZZLE_TO_PROBE_OFFSET { 5, -5, -1 } // Example "3" - * #define NOZZLE_TO_PROBE_OFFSET {-15,-10, -1 } // Example "4" - * - * +-- BACK ---+ - * | [+] | - * L | 1 | R <-- Example "1" (right+, back+) - * E | 2 | I <-- Example "2" ( left-, back+) - * F |[-] N [+]| G <-- Nozzle - * T | 3 | H <-- Example "3" (right+, front-) - * | 4 | T <-- Example "4" ( left-, front-) - * | [-] | - * O-- FRONT --+ - */ -#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 } - -// Most probes should stay away from the edges of the bed, but -// with NOZZLE_AS_PROBE this can be negative for a wider probing area. -#define PROBING_MARGIN 10 - -// X and Y axis travel speed (mm/min) between probes -#define XY_PROBE_FEEDRATE (133*60) - -// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2) -#define Z_PROBE_FEEDRATE_FAST (4*60) - -// Feedrate (mm/min) for the "accurate" probe of each point -#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2) - -/** - * Probe Activation Switch - * A switch indicating proper deployment, or an optical - * switch triggered when the carriage is near the bed. - */ -//#define PROBE_ACTIVATION_SWITCH -#if ENABLED(PROBE_ACTIVATION_SWITCH) - #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active - //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin -#endif - -/** - * Tare Probe (determine zero-point) prior to each probe. - * Useful for a strain gauge or piezo sensor that needs to factor out - * elements such as cables pulling on the carriage. - */ -//#define PROBE_TARE -#if ENABLED(PROBE_TARE) - #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin - #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before - #define PROBE_TARE_STATE HIGH // State to write pin for tare - //#define PROBE_TARE_PIN PA5 // Override default pin - #if ENABLED(PROBE_ACTIVATION_SWITCH) - //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active - #endif -#endif - -/** - * Probe Enable / Disable - * The probe only provides a triggered signal when enabled. - */ -//#define PROBE_ENABLE_DISABLE -#if ENABLED(PROBE_ENABLE_DISABLE) - //#define PROBE_ENABLE_PIN -1 // Override the default pin here -#endif - -/** - * Multiple Probing - * - * You may get improved results by probing 2 or more times. - * With EXTRA_PROBING the more atypical reading(s) will be disregarded. - * - * A total of 2 does fast/slow probes with a weighted average. - * A total of 3 or more adds more slow probes, taking the average. - */ -//#define MULTIPLE_PROBING 2 -//#define EXTRA_PROBING 1 - -/** - * 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 NOZZLE_TO_PROBE_OFFSET, 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_MULTI_PROBE 5 // Z Clearance between multiple probes -//#define Z_AFTER_PROBING 5 // Z position after probing is done - -#define Z_PROBE_LOW_POINT -2 // Farthest distance below the trigger-point to go before stopping - -// 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 - -// Before deploy/stow pause for user confirmation -//#define PAUSE_BEFORE_DEPLOY_STOW -#if ENABLED(PAUSE_BEFORE_DEPLOY_STOW) - //#define PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED // For Manual Deploy Allenkey Probe -#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 -#if ENABLED(PROBING_HEATERS_OFF) - //#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy) - //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude) -#endif -//#define PROBING_FANS_OFF // Turn fans off when probing -//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing -//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders) -//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors - -// Require minimum nozzle and/or bed temperature for probing -//#define PREHEAT_BEFORE_PROBING -#if ENABLED(PREHEAT_BEFORE_PROBING) - #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time - #define PROBING_BED_TEMP 50 -#endif - -// 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 -//#define I_ENABLE_ON 0 -//#define J_ENABLE_ON 0 -//#define K_ENABLE_ON 0 - -// Disable axis steppers immediately when they're not being stepped. -// WARNING: When motors turn off there is a chance of losing position accuracy! -#define DISABLE_X false -#define DISABLE_Y false -#define DISABLE_Z false -//#define DISABLE_I false -//#define DISABLE_J false -//#define DISABLE_K false - -// Turn off the display blinking that warns about possible accuracy reduction -//#define DISABLE_REDUCED_ACCURACY_WARNING - -// @section extruder - -#define DISABLE_E false // Disable the extruder when not stepping -#define DISABLE_INACTIVE_EXTRUDER // 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 -//#define INVERT_I_DIR false -//#define INVERT_J_DIR false -//#define INVERT_K_DIR false - -// @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 -#define INVERT_E5_DIR false -#define INVERT_E6_DIR false -#define INVERT_E7_DIR false - -// @section homing - -//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. -//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety. - -/** - * Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled. - * - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed. - * - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle. - */ -#define Z_IDLE_HEIGHT Z_MAX_POS - -//#define Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ... - // Be sure to have this much clearance over your Z_MAX_POS to prevent grinding. - -//#define Z_AFTER_HOMING 10 // (mm) Height to move to after homing Z - -// 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 I_HOME_DIR -1 -//#define J_HOME_DIR -1 -//#define K_HOME_DIR -1 - -// @section machine - -// these values are used in your slicer -#define X_BED_SIZE 227 -#define Y_BED_SIZE 148 - -// Travel limits (mm) after homing, corresponding to endstop positions. -#define X_MIN_POS -115 -#define Y_MIN_POS -84 -#define Z_MIN_POS 0 -#define X_MAX_POS 152 -#define Y_MAX_POS 77 -#define Z_MAX_POS 150 -//#define I_MIN_POS 0 -//#define I_MAX_POS 50 -//#define J_MIN_POS 0 -//#define J_MAX_POS 50 -//#define K_MIN_POS 0 -//#define K_MAX_POS 50 - -/** - * Software Endstops - * - * - Prevent moves outside the set machine bounds. - * - Individual axes can be disabled, if desired. - * - X and Y only apply to Cartesian robots. - * - Use 'M211' to set software endstops on/off or report current state - */ - -// Min software endstops constrain movement within minimum coordinate bounds -#define MIN_SOFTWARE_ENDSTOPS -#if ENABLED(MIN_SOFTWARE_ENDSTOPS) - #define MIN_SOFTWARE_ENDSTOP_X - #define MIN_SOFTWARE_ENDSTOP_Y - #define MIN_SOFTWARE_ENDSTOP_Z - #define MIN_SOFTWARE_ENDSTOP_I - #define MIN_SOFTWARE_ENDSTOP_J - #define MIN_SOFTWARE_ENDSTOP_K -#endif - -// Max software endstops constrain movement within maximum coordinate bounds -#define MAX_SOFTWARE_ENDSTOPS -#if ENABLED(MAX_SOFTWARE_ENDSTOPS) - #define MAX_SOFTWARE_ENDSTOP_X - #define MAX_SOFTWARE_ENDSTOP_Y - #define MAX_SOFTWARE_ENDSTOP_Z - #define MAX_SOFTWARE_ENDSTOP_I - #define MAX_SOFTWARE_ENDSTOP_J - #define MAX_SOFTWARE_ENDSTOP_K -#endif - -#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) - //#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD -#endif - -/** - * Filament Runout Sensors - * Mechanical or opto endstops are used to check for the presence of filament. - * - * IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running. - * Marlin knows a print job is running when: - * 1. Running a print job from media started with M24. - * 2. The Print Job Timer has been started with M75. - * 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled. - * - * RAMPS-based boards use SERVO3_PIN for the first runout sensor. - * For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc. - */ -//#define FILAMENT_RUNOUT_SENSOR -#if ENABLED(FILAMENT_RUNOUT_SENSOR) - #define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500. - #define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each. - - #define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present. - #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins. - //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins. - //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder. - // This is automatically enabled for MIXING_EXTRUDERs. - - // Override individually if the runout sensors vary - //#define FIL_RUNOUT1_STATE LOW - //#define FIL_RUNOUT1_PULLUP - //#define FIL_RUNOUT1_PULLDOWN - - //#define FIL_RUNOUT2_STATE LOW - //#define FIL_RUNOUT2_PULLUP - //#define FIL_RUNOUT2_PULLDOWN - - //#define FIL_RUNOUT3_STATE LOW - //#define FIL_RUNOUT3_PULLUP - //#define FIL_RUNOUT3_PULLDOWN - - //#define FIL_RUNOUT4_STATE LOW - //#define FIL_RUNOUT4_PULLUP - //#define FIL_RUNOUT4_PULLDOWN - - //#define FIL_RUNOUT5_STATE LOW - //#define FIL_RUNOUT5_PULLUP - //#define FIL_RUNOUT5_PULLDOWN - - //#define FIL_RUNOUT6_STATE LOW - //#define FIL_RUNOUT6_PULLUP - //#define FIL_RUNOUT6_PULLDOWN - - //#define FIL_RUNOUT7_STATE LOW - //#define FIL_RUNOUT7_PULLUP - //#define FIL_RUNOUT7_PULLDOWN - - //#define FIL_RUNOUT8_STATE LOW - //#define FIL_RUNOUT8_PULLUP - //#define FIL_RUNOUT8_PULLDOWN - - // Commands to execute on filament runout. - // With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c") - // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply. - #define FILAMENT_RUNOUT_SCRIPT "M600" - - // After a runout is detected, continue printing this length of filament - // before executing the runout script. Useful for a sensor at the end of - // a feed tube. Requires 4 bytes SRAM per sensor, plus 4 bytes overhead. - //#define FILAMENT_RUNOUT_DISTANCE_MM 25 - - #ifdef FILAMENT_RUNOUT_DISTANCE_MM - // Enable this option to use an encoder disc that toggles the runout pin - // as the filament moves. (Be sure to set FILAMENT_RUNOUT_DISTANCE_MM - // large enough to avoid false positives.) - //#define FILAMENT_MOTION_SENSOR - #endif -#endif - -//=========================================================================== -//=============================== Bed Leveling ============================== -//=========================================================================== -// @section calibrate - -/** - * 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. - * - * - 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 - -/** - * Normally G28 leaves leveling disabled on completion. Enable one of - * these options to restore the prior leveling state or to always enable - * leveling immediately after G28. - */ -//#define RESTORE_LEVELING_AFTER_G28 -//#define ENABLE_LEVELING_AFTER_G28 - -/** - * Auto-leveling needs preheating - */ -//#define PREHEAT_BEFORE_LEVELING -#if ENABLED(PREHEAT_BEFORE_LEVELING) - #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time - #define LEVELING_BED_TEMP 50 -#endif - -/** - * 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 ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY) - // Set a height for the start of manual adjustment - #define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height -#endif - -#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, 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 - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. - #endif - - // For Cartesian machines, instead of dividing moves on mesh boundaries, - // split up moves into short segments like a Delta. This follows the - // contours of the bed more closely than edge-to-edge straight moves. - #define SEGMENT_LEVELED_MOVES - #define LEVELED_SEGMENT_LENGTH 5.0 // (mm) Length of all segments (except the last one) - - /** - * Enable the G26 Mesh Validation Pattern tool. - */ - //#define G26_MESH_VALIDATION - #if ENABLED(G26_MESH_VALIDATION) - #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. - #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. - #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26. - #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26. - #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves. - #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves. - #define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements. - #endif - -#endif - -#if EITHER(AUTO_BED_LEVELING_LINEAR, 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 - - // 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_UBL) - - //=========================================================================== - //========================= Unified Bed Leveling ============================ - //=========================================================================== - - //#define MESH_EDIT_GFX_OVERLAY // Display a graphics overlay while editing the mesh - - #define MESH_INSET 1 // Set Mesh bounds as an inset region of the bed - #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_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points - - #define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle - #define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500 - - //#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used - // as the Z-Height correction value. - - //#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh - -#elif ENABLED(MESH_BED_LEVELING) - - //=========================================================================== - //=================================== Mesh ================================== - //=========================================================================== - - #define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed - #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 - -/** - * Add a bed leveling sub-menu for ABL or MBL. - * Include a guided procedure if manual probing is enabled. - */ -//#define LCD_BED_LEVELING - -#if ENABLED(LCD_BED_LEVELING) - #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. - #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment - //#define MESH_EDIT_MENU // Add a menu to edit mesh points -#endif - -// Add a menu item to move between bed corners for manual bed adjustment -//#define LCD_BED_TRAMMING - -#if ENABLED(LCD_BED_TRAMMING) - #define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets - #define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points - #define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points - //#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner - //#define BED_TRAMMING_USE_PROBE - #if ENABLED(BED_TRAMMING_USE_PROBE) - #define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm) - #define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify - //#define BED_TRAMMING_AUDIO_FEEDBACK - #endif - - /** - * Corner Leveling Order - * - * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge. - * - * LF Left-Front RF Right-Front - * LB Left-Back RB Right-Back - * - * Examples: - * - * Default {LF,RB,LB,RF} {LF,RF} {LB,LF} - * LB --------- RB LB --------- RB LB --------- RB LB --------- RB - * | 4 3 | | 3 2 | | <3> | | 1 | - * | | | | | | | <3>| - * | 1 2 | | 1 4 | | 1 2 | | 2 | - * LF --------- RF LF --------- RF LF --------- RF LF --------- RF - */ - #define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB } -#endif - -/** - * 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 -//#define MANUAL_I_HOME_POS 0 -//#define MANUAL_J_HOME_POS 0 -//#define MANUAL_K_HOME_POS 0 - -/** - * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area. - * - * - Moves the Z probe (or nozzle) to a defined XY point before Z homing. - * - Allows Z homing only when XY positions are known and trusted. - * - If stepper drivers sleep, XY homing may be required again before Z homing. - */ -//#define Z_SAFE_HOMING - -#if ENABLED(Z_SAFE_HOMING) - #define Z_SAFE_HOMING_X_POINT X_CENTER // X point for Z homing - #define Z_SAFE_HOMING_Y_POINT Y_CENTER // Y point for Z homing -#endif - -// Homing speeds (mm/min) -#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) } - -// Validate that endstops are triggered on homing moves -#define VALIDATE_HOMING_ENDSTOPS - -// @section calibrate - -/** - * Bed Skew Compensation - * - * This feature corrects for misalignment in the XYZ axes. - * - * Take the following steps to get the bed skew in the XY plane: - * 1. Print a test square (e.g., https://www.thingiverse.com/thing:2563185) - * 2. For XY_DIAG_AC measure the diagonal A to C - * 3. For XY_DIAG_BD measure the diagonal B to D - * 4. For XY_SIDE_AD measure the edge A to D - * - * Marlin automatically computes skew factors from these measurements. - * Skew factors may also be computed and set manually: - * - * - Compute AB : SQRT(2*AC*AC+2*BD*BD-4*AD*AD)/2 - * - XY_SKEW_FACTOR : TAN(PI/2-ACOS((AC*AC-AB*AB-AD*AD)/(2*AB*AD))) - * - * If desired, follow the same procedure for XZ and YZ. - * Use these diagrams for reference: - * - * Y Z Z - * ^ B-------C ^ B-------C ^ B-------C - * | / / | / / | / / - * | / / | / / | / / - * | A-------D | A-------D | A-------D - * +-------------->X +-------------->X +-------------->Y - * XY_SKEW_FACTOR XZ_SKEW_FACTOR YZ_SKEW_FACTOR - */ -//#define SKEW_CORRECTION - -#if ENABLED(SKEW_CORRECTION) - // Input all length measurements here: - #define XY_DIAG_AC 282.8427124746 - #define XY_DIAG_BD 282.8427124746 - #define XY_SIDE_AD 200 - - // Or, set the default skew factors directly here - // to override the above measurements: - #define XY_SKEW_FACTOR 0.0 - - //#define SKEW_CORRECTION_FOR_Z - #if ENABLED(SKEW_CORRECTION_FOR_Z) - #define XZ_DIAG_AC 282.8427124746 - #define XZ_DIAG_BD 282.8427124746 - #define YZ_DIAG_AC 282.8427124746 - #define YZ_DIAG_BD 282.8427124746 - #define YZ_SIDE_AD 200 - #define XZ_SKEW_FACTOR 0.0 - #define YZ_SKEW_FACTOR 0.0 - #endif - - // Enable this option for M852 to set skew at runtime - //#define SKEW_CORRECTION_GCODE -#endif - -//============================================================================= -//============================= Additional Features =========================== -//============================================================================= - -// @section extras - -/** - * EEPROM - * - * Persistent storage to preserve configurable settings across reboots. - * - * M500 - Store settings to EEPROM. - * M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes) - * M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.) - */ -#define EEPROM_SETTINGS // Persistent storage with M500 and M501 -//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release! -#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. -#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load -#if ENABLED(EEPROM_SETTINGS) - #define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. - //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build. -#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. -#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating - -// -// G20/G21 Inch mode support -// -//#define INCH_MODE_SUPPORT - -// -// M149 Set temperature units support -// -//#define TEMPERATURE_UNITS_SUPPORT - -// @section temperature - -// -// Preheat Constants - Up to 6 are supported without changes -// -#define PREHEAT_1_LABEL "PLA" -#define PREHEAT_1_TEMP_HOTEND 200 -#define PREHEAT_1_TEMP_BED 50 -#define PREHEAT_1_TEMP_CHAMBER 35 -#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255 - -#define PREHEAT_2_LABEL "ABS" -#define PREHEAT_2_TEMP_HOTEND 220 -#define PREHEAT_2_TEMP_BED 100 -#define PREHEAT_2_TEMP_CHAMBER 35 -#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255 - -/** - * Nozzle Park - * - * 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_raise } - #define NOZZLE_PARK_POINT { (X_MAX_POS - 2), (Y_MAX_POS - 2), 20 } - #define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X - #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance - #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) - #define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers) -#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 for each tool as { { X, Y, Z }, { X, Y, Z } } - // Dual hotend system may use { { -20, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }, { 420, (Y_BED_SIZE / 2), (Z_MIN_POS + 1) }} - #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 - - // Move the nozzle to the initial position after cleaning - #define NOZZLE_CLEAN_GOBACK - - // For a purge/clean station that's always at the gantry height (thus no Z move) - //#define NOZZLE_CLEAN_NO_Z - - // For a purge/clean station mounted on the X axis - //#define NOZZLE_CLEAN_NO_Y - - // Require a minimum hotend temperature for cleaning - #define NOZZLE_CLEAN_MIN_TEMP 170 - //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe - - // Explicit wipe G-code script applies to a G12 with no arguments. - //#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0" - -#endif - -/** - * Print Job Timer - * - * Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191. - * The print job timer will only be stopped if the bed/chamber target temp is - * below BED_MINTEMP/CHAMBER_MINTEMP. - * - * M104 (hotend, no wait) - high temp = none, low temp = stop timer - * M109 (hotend, wait) - high temp = start timer, low temp = stop timer - * M140 (bed, no wait) - high temp = none, low temp = stop timer - * M190 (bed, wait) - high temp = start timer, low temp = none - * M141 (chamber, no wait) - high temp = none, low temp = stop timer - * M191 (chamber, wait) - high temp = start timer, low temp = none - * - * For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2. - * For M140/M190, high temp is anything over BED_MINTEMP. - * For M141/M191, high temp is anything over CHAMBER_MINTEMP. - * - * 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 -#if ENABLED(PRINTCOUNTER) - #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print -#endif - -/** - * Password - * - * Set a numerical password for the printer which can be requested: - * - * - When the printer boots up - * - Upon opening the 'Print from Media' Menu - * - When SD printing is completed or aborted - * - * The following G-codes can be used: - * - * M510 - Lock Printer. Blocks all commands except M511. - * M511 - Unlock Printer. - * M512 - Set, Change and Remove Password. - * - * If you forget the password and get locked out you'll need to re-flash - * the firmware with the feature disabled, reset EEPROM, and (optionally) - * re-flash the firmware again with this feature enabled. - */ -//#define PASSWORD_FEATURE -#if ENABLED(PASSWORD_FEATURE) - #define PASSWORD_LENGTH 4 // (#) Number of digits (1-9). 3 or 4 is recommended - #define PASSWORD_ON_STARTUP - #define PASSWORD_UNLOCK_GCODE // Unlock with the M511 P command. Disable to prevent brute-force attack. - #define PASSWORD_CHANGE_GCODE // Change the password with M512 P S. - //#define PASSWORD_ON_SD_PRINT_MENU // This does not prevent gcodes from running - //#define PASSWORD_AFTER_SD_PRINT_END - //#define PASSWORD_AFTER_SD_PRINT_ABORT - //#include "Configuration_Secure.h" // External file with PASSWORD_DEFAULT_VALUE -#endif - -//============================================================================= -//============================= LCD and SD support ============================ -//============================================================================= - -// @section lcd - -/** - * LCD LANGUAGE - * - * Select the language to display on the LCD. These languages are available: - * - * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it, - * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW - * - * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek (Greece)', 'el_CY':'Greek (Cyprus)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' } - */ -#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 https://marlinfw.org/docs/development/lcd_language.html - * - * :['JAPANESE', 'WESTERN', 'CYRILLIC'] - */ -#define DISPLAY_CHARSET_HD44780 JAPANESE - -/** - * Info Screen Style (0:Classic, 1:Průša) - * - * :[0:'Classic', 1:'Průša'] - */ -#define LCD_INFO_SCREEN_STYLE 0 - -/** - * 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: ENABLE CRC - * - * Use CRC checks and retries on the SD communication. - */ -#define SD_CHECK_AND_RETRY - -/** - * LCD Menu Items - * - * Disable all menus and only display the Status Screen, or - * just remove some extraneous menu items to recover space. - */ -//#define NO_LCD_MENUS -//#define SLIM_LCD_MENUS - -// -// 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 - -// -// This option reverses the encoder direction for Select Screen. -// -// If CLOCKWISE normally moves LEFT this makes it go RIGHT. -// If CLOCKWISE normally moves RIGHT this makes it go LEFT. -// -//#define REVERSE_SELECT_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 -//#define INDIVIDUAL_AXIS_HOMING_SUBMENU - -// -// 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 2 -//#define LCD_FEEDBACK_FREQUENCY_HZ 5000 - -//============================================================================= -//======================== LCD / Controller Selection ========================= -//======================== (Character-based LCDs) ========================= -//============================================================================= - -// -// RepRapDiscount Smart Controller. -// https://reprap.org/wiki/RepRapDiscount_Smart_Controller -// -// Note: Usually sold with a white PCB. -// -//#define REPRAP_DISCOUNT_SMART_CONTROLLER - -// -// GT2560 (YHCB2004) LCD Display -// -// Requires Testato, Koepel softwarewire library and -// Andriy Golovnya's LiquidCrystal_AIP31068 library. -// -//#define YHCB2004 - -// -// Original RADDS LCD Display+Encoder+SDCardReader -// http://doku.radds.org/dokumentation/lcd-display/ -// -//#define RADDS_DISPLAY - -// -// ULTIMAKER Controller. -// -//#define ULTIMAKERCONTROLLER - -// -// ULTIPANEL as seen on Thingiverse. -// -//#define ULTIPANEL - -// -// PanelOne from T3P3 (via RAMPS 1.4 AUX2/AUX3) -// https://reprap.org/wiki/PanelOne -// -//#define PANEL_ONE - -// -// GADGETS3D G3D LCD/SD Controller -// https://reprap.org/wiki/RAMPS_1.3/1.4_GADGETS3D_Shield_with_Panel -// -// Note: Usually sold with a blue PCB. -// -//#define G3D_PANEL - -// -// RigidBot Panel V1.0 -// http://www.inventapart.com/ -// -//#define RIGIDBOT_PANEL - -// -// Makeboard 3D Printer Parts 3D Printer Mini Display 1602 Mini Controller -// https://www.aliexpress.com/item/32765887917.html -// -//#define MAKEBOARD_MINI_2_LINE_DISPLAY_1602 - -// -// ANET and Tronxy 20x4 Controller -// -//#define ZONESTAR_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. - // This is a LCD2004 display with 5 analog buttons. - -// -// Generic 16x2, 16x4, 20x2, or 20x4 character-based LCD. -// -//#define ULTRA_LCD - -//============================================================================= -//======================== LCD / Controller Selection ========================= -//===================== (I2C and Shift-Register LCDs) ===================== -//============================================================================= - -// -// 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 (YwRobot) LCD Displays -// -// These require F.Malpartida's LiquidCrystal_I2C library -// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home -// -//#define LCD_SAINSMART_I2C_1602 -//#define LCD_SAINSMART_I2C_2004 - -// -// 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 - -// -// CONTROLLER TYPE: Shift register panels -// - -// -// 2-wire Non-latching LCD SR from https://goo.gl/aJJ4sH -// LCD configuration: https://reprap.org/wiki/SAV_3D_LCD -// -//#define SAV_3DLCD - -// -// 3-wire SR LCD with strobe using 74HC4094 -// https://github.com/mikeshub/SailfishLCD -// Uses the code directly from Sailfish -// -//#define FF_INTERFACEBOARD - -// -// TFT GLCD Panel with Marlin UI -// Panel connected to main board by SPI or I2C interface. -// See https://github.com/Serhiy-K/TFTGLCDAdapter -// -//#define TFTGLCD_PANEL_SPI -//#define TFTGLCD_PANEL_I2C - -//============================================================================= -//======================= LCD / Controller Selection ======================= -//========================= (Graphical LCDs) ======================== -//============================================================================= - -// -// CONTROLLER TYPE: Graphical 128x64 (DOGM) -// -// IMPORTANT: The U8glib library is required for Graphical Display! -// https://github.com/olikraus/U8glib_Arduino -// -// NOTE: If the LCD is unresponsive you may need to reverse the plugs. -// - -// -// RepRapDiscount FULL GRAPHIC Smart Controller -// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller -// -//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER - -// -// K.3D Full Graphic Smart Controller -// -//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER - -// -// 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 -// https://www.panucatt.com -// -//#define VIKI2 -//#define miniVIKI - -// -// Alfawise Ex8 printer LCD marked as WYH L12864 COG -// -//#define WYH_L12864 - -// -// MakerLab Mini Panel with graphic -// controller and SD support - https://reprap.org/wiki/Mini_panel -// -//#define MINIPANEL - -// -// MaKr3d Makr-Panel with graphic controller and SD support. -// https://reprap.org/wiki/MaKr3d_MaKrPanel -// -//#define MAKRPANEL - -// -// Adafruit ST7565 Full Graphic Controller. -// https://github.com/eboston/Adafruit-ST7565-Full-Graphic-Controller/ -// -//#define ELB_FULL_GRAPHIC_CONTROLLER - -// -// 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 - -// -// LCD for Melzi Card with Graphical LCD -// -//#define LCD_FOR_MELZI - -// -// Original Ulticontroller from Ultimaker 2 printer with SSD1309 I2C display and encoder -// https://github.com/Ultimaker/Ultimaker2/tree/master/1249_Ulticontroller_Board_(x1) -// -//#define ULTI_CONTROLLER - -// -// MKS MINI12864 with graphic controller and SD support -// https://reprap.org/wiki/MKS_MINI_12864 -// -//#define MKS_MINI_12864 - -// -// MKS MINI12864 V3 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. -// -#define MKS_MINI_12864_V3 - -// -// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout. -// https://www.aliexpress.com/item/33018110072.html -// -//#define MKS_LCD12864A -//#define MKS_LCD12864B - -// -// FYSETC variant of the MINI12864 graphic controller with SD support -// https://wiki.fysetc.com/Mini12864_Panel/ -// -//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default -//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on) -//#define FYSETC_MINI_12864_2_0 // Type A/B. Discreet RGB Backlight -//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight -//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight. - -// -// BigTreeTech Mini 12864 V1.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight. -// -//#define BTT_MINI_12864_V1 - -// -// Factory display for Creality CR-10 -// https://www.aliexpress.com/item/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 - -// -// Ender-2 OEM display, a variant of the MKS_MINI_12864 -// -//#define ENDER2_STOCKDISPLAY - -// -// ANET and Tronxy Graphical Controller -// -// 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). Enable one of these. -// -//#define ANET_FULL_GRAPHICS_LCD -//#define ANET_FULL_GRAPHICS_LCD_ALT_WIRING - -// -// AZSMZ 12864 LCD with SD -// https://www.aliexpress.com/item/32837222770.html -// -//#define AZSMZ_12864 - -// -// Silvergate GLCD controller -// https://github.com/android444/Silvergate -// -//#define SILVER_GATE_GLCD_CONTROLLER - -//============================================================================= -//============================== OLED Displays ============================== -//============================================================================= - -// -// 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 - -// -// TinyBoy2 128x64 OLED / Encoder Panel -// -//#define OLED_PANEL_TINYBOY2 - -// -// MKS OLED 1.3" 128×64 Full Graphics Controller -// https://reprap.org/wiki/MKS_12864OLED -// -// Tiny, but very sharp OLED display -// -//#define MKS_12864OLED // Uses the SH1106 controller (default) -//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller - -// -// Zonestar OLED 128×64 Full Graphics Controller -// -//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller -//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default) -//#define ZONESTAR_12864OLED_SSD1306 // 0.96" OLED with SSD1306 controller - -// -// Einstart S OLED SSD1306 -// -//#define U8GLIB_SH1106_EINSTART - -// -// Overlord OLED display/controller with i2c buzzer and LEDs -// -//#define OVERLORD_OLED - -// -// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB -// Where to find : https://www.aliexpress.com/item/4000345255731.html -//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller - -// -// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller -// -//#define K3D_242_OLED_CONTROLLER // Software SPI - -//============================================================================= -//========================== Extensible UI Displays =========================== -//============================================================================= - -/** - * DGUS Touch Display with DWIN OS. (Choose one.) - * ORIGIN : https://www.aliexpress.com/item/32993409517.html - * FYSETC : https://www.aliexpress.com/item/32961471929.html - * MKS : https://www.aliexpress.com/item/1005002008179262.html - * - * Flash display with DGUS Displays for Marlin: - * - Format the SD card to FAT32 with an allocation size of 4kb. - * - Download files as specified for your type of display. - * - Plug the microSD card into the back of the display. - * - Boot the display and wait for the update to complete. - * - * ORIGIN (Marlin DWIN_SET) - * - Download https://github.com/coldtobi/Marlin_DGUS_Resources - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * FYSETC (Supplier default) - * - Download https://github.com/FYSETC/FYSTLCD-2.0 - * - Copy the downloaded SCREEN folder to the SD card. - * - * HIPRECY (Supplier default) - * - Download https://github.com/HiPrecy/Touch-Lcd-LEO - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * MKS (MKS-H43) (Supplier default) - * - Download https://github.com/makerbase-mks/MKS-H43 - * - Copy the downloaded DWIN_SET folder to the SD card. - * - * RELOADED (T5UID1) - * - Download https://github.com/Desuuuu/DGUS-reloaded/releases - * - Copy the downloaded DWIN_SET folder to the SD card. - */ -//#define DGUS_LCD_UI_ORIGIN -//#define DGUS_LCD_UI_FYSETC -//#define DGUS_LCD_UI_HIPRECY -//#define DGUS_LCD_UI_MKS -//#define DGUS_LCD_UI_RELOADED -#if ENABLED(DGUS_LCD_UI_MKS) - #define USE_MKS_GREEN_UI -#endif - -// -// Touch-screen LCD for Malyan M200/M300 printers -// -//#define MALYAN_LCD - -// -// Touch UI for FTDI EVE (FT800/FT810) displays -// See Configuration_adv.h for all configuration options. -// -//#define TOUCH_UI_FTDI_EVE - -// -// Touch-screen LCD for Anycubic printers -// -//#define ANYCUBIC_LCD_I3MEGA -//#define ANYCUBIC_LCD_CHIRON -#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON) - //#define ANYCUBIC_LCD_DEBUG -#endif - -// -// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028 -// -//#define NEXTION_TFT - -// -// Third-party or vendor-customized controller interfaces. -// Sources should be installed in 'src/lcd/extui'. -// -//#define EXTENSIBLE_UI - -#if ENABLED(EXTENSIBLE_UI) - //#define EXTUI_LOCAL_BEEPER // Enables use of local Beeper pin with external display -#endif - -//============================================================================= -//=============================== Graphical TFTs ============================== -//============================================================================= - -/** - * Specific TFT Model Presets. Enable one of the following options - * or enable TFT_GENERIC and set sub-options. - */ - -// -// 480x320, 3.5", SPI Display with Rotary Encoder from MKS -// Usually paired with MKS Robin Nano V2 & V3 -// -//#define MKS_TS35_V2_0 - -// -// 320x240, 2.4", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT24 - -// -// 320x240, 2.8", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT28 - -// -// 320x240, 3.2", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT32 - -// -// 480x320, 3.5", FSMC Display From MKS -// Usually paired with MKS Robin Nano V1.2 -// -//#define MKS_ROBIN_TFT35 - -// -// 480x272, 4.3", FSMC Display From MKS -// -//#define MKS_ROBIN_TFT43 - -// -// 320x240, 3.2", FSMC Display From MKS -// Usually paired with MKS Robin -// -//#define MKS_ROBIN_TFT_V1_1R - -// -// 480x320, 3.5", FSMC Stock Display from TronxXY -// -//#define TFT_TRONXY_X5SA - -// -// 480x320, 3.5", FSMC Stock Display from AnyCubic -// -//#define ANYCUBIC_TFT35 - -// -// 320x240, 2.8", FSMC Stock Display from Longer/Alfawise -// -//#define LONGER_LK_TFT28 - -// -// 320x240, 2.8", FSMC Stock Display from ET4 -// -//#define ANET_ET4_TFT28 - -// -// 480x320, 3.5", FSMC Stock Display from ET5 -// -//#define ANET_ET5_TFT35 - -// -// 1024x600, 7", RGB Stock Display with Rotary Encoder from BIQU-BX -// -//#define BIQU_BX_TFT70 - -// -// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series -// -//#define BTT_TFT35_SPI_V1_0 - -// -// Generic TFT with detailed options -// -//#define TFT_GENERIC -#if ENABLED(TFT_GENERIC) - // :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ] - #define TFT_DRIVER AUTO - - // Interface. Enable one of the following options: - //#define TFT_INTERFACE_FSMC - //#define TFT_INTERFACE_SPI - - // TFT Resolution. Enable one of the following options: - //#define TFT_RES_320x240 - //#define TFT_RES_480x272 - //#define TFT_RES_480x320 - //#define TFT_RES_1024x600 -#endif - -/** - * TFT UI - User Interface Selection. Enable one of the following options: - * - * TFT_CLASSIC_UI - Emulated DOGM - 128x64 Upscaled - * TFT_COLOR_UI - Marlin Default Menus, Touch Friendly, using full TFT capabilities - * TFT_LVGL_UI - A Modern UI using LVGL - * - * For LVGL_UI also copy the 'assets' folder from the build directory to the - * root of your SD card, together with the compiled firmware. - */ -//#define TFT_CLASSIC_UI -//#define TFT_COLOR_UI -//#define TFT_LVGL_UI - -#if ENABLED(TFT_LVGL_UI) - //#define MKS_WIFI_MODULE // MKS WiFi module -#endif - -/** - * TFT Rotation. Set to one of the following values: - * - * TFT_ROTATE_90, TFT_ROTATE_90_MIRROR_X, TFT_ROTATE_90_MIRROR_Y, - * TFT_ROTATE_180, TFT_ROTATE_180_MIRROR_X, TFT_ROTATE_180_MIRROR_Y, - * TFT_ROTATE_270, TFT_ROTATE_270_MIRROR_X, TFT_ROTATE_270_MIRROR_Y, - * TFT_MIRROR_X, TFT_MIRROR_Y, TFT_NO_ROTATION - */ -//#define TFT_ROTATION TFT_NO_ROTATION - -//============================================================================= -//============================ Other Controllers ============================ -//============================================================================= - -// -// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder. -// -//#define DWIN_CREALITY_LCD // Creality UI -//#define DWIN_LCD_PROUI // Pro UI by MRiscoC -//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers -//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation) -//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation) - -// -// Touch Screen Settings -// -//#define TOUCH_SCREEN -#if ENABLED(TOUCH_SCREEN) - #define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens - #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus - - //#define TOUCH_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn) - - #define TOUCH_SCREEN_CALIBRATION - - //#define TOUCH_CALIBRATION_X 12316 - //#define TOUCH_CALIBRATION_Y -8981 - //#define TOUCH_OFFSET_X -43 - //#define TOUCH_OFFSET_Y 257 - //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE - - #if BOTH(TOUCH_SCREEN_CALIBRATION, EEPROM_SETTINGS) - #define TOUCH_CALIBRATION_AUTO_SAVE // Auto save successful calibration values to EEPROM - #endif - - #if ENABLED(TFT_COLOR_UI) - //#define SINGLE_TOUCH_NAVIGATION - #endif -#endif - -// -// RepRapWorld REPRAPWORLD_KEYPAD v1.1 -// https://reprapworld.com/products/electronics/ramps/keypad_v1_0_fully_assembled/ -// -//#define REPRAPWORLD_KEYPAD -//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press - -// -// EasyThreeD ET-4000+ with button input and status LED -// -//#define EASYTHREED_UI - -//============================================================================= -//=============================== Extra Features ============================== -//============================================================================= - -// @section extras - -// Set number of user-controlled fans. Disable to use all board-defined fans. -// :[1,2,3,4,5,6,7,8] -//#define NUM_M106_FANS 1 - -// 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. -// :[0,1,2,3,4,5,6,7] -#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 - -// Support for the BariCUDA Paste Extruder -//#define BARICUDA - -// Support for BlinkM/CyzRgb -//#define BLINKM - -// Support for PCA9632 PWM LED driver -//#define PCA9632 - -// Support for PCA9533 PWM LED driver -#define PCA9533 - -/** - * 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 an overall brightness parameter is also available. - * - * *** CAUTION *** - * LED Strips require a MOSFET Chip between PWM lines and LEDs, - * as the Arduino cannot handle the current the LEDs will require. - * Failure to follow this precaution can destroy your Arduino! - * NOTE: A separate 5V power supply is required! The NeoPixel LED needs - * more current than the Arduino 5V linear regulator can produce. - * *** CAUTION *** - * - * LED Type. Enable only one of the following two options. - */ -//#define RGB_LED -//#define RGBW_LED - -#if EITHER(RGB_LED, 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_RGBW, NEO_GRB, NEO_RBG, etc. - // See https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h - //#define NEOPIXEL_PIN 4 // LED driving pin - //#define NEOPIXEL2_TYPE NEOPIXEL_TYPE - //#define NEOPIXEL2_PIN 5 - #define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.) - #define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once. - #define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255) - //#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup - - // Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ... - //#define NEOPIXEL2_SEPARATE - #if ENABLED(NEOPIXEL2_SEPARATE) - #define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip - #define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255) - #define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup - #else - //#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel - #endif - - // Use some of the NeoPixel LEDs for static (background) lighting - //#define NEOPIXEL_BKGD_INDEX_FIRST 0 // Index of the first background LED - //#define NEOPIXEL_BKGD_INDEX_LAST 5 // Index of the last background LED - //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W - //#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off -#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 ANY(BLINKM, RGB_LED, RGBW_LED, PCA9632, PCA9533, NEOPIXEL_LED) - #define PRINTER_EVENT_LEDS -#endif - -/** - * Number of servos - * - * For some servo-related options NUM_SERVOS will be set automatically. - * Set this manually if there are extra servos needing manual control. - * Set to 0 to turn off servo support. - */ -//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands - -// (ms) Delay 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 } - -// Only power servos during movement, otherwise leave off to prevent jitter -//#define DEACTIVATE_SERVOS_AFTER_MOVE - -// Edit servo angles with M281 and save to EEPROM with M500 -//#define EDITABLE_SERVO_ANGLES - -// Disable servo with M282 to reduce power consumption, noise, and heat when not in use -//#define SERVO_DETACH_GCODE diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h deleted file mode 100644 index fde19f5..0000000 --- a/Marlin/Configuration_adv.h +++ /dev/null @@ -1,4354 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CONFIG_EXAMPLES_DIR "FlashForge/CreatorPro" - -/** - * 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 - */ -#define CONFIGURATION_ADV_H_VERSION 02000905 - -//=========================================================================== -//============================= Thermal Settings ============================ -//=========================================================================== -// @section temperature - -/** - * Thermocouple sensors are quite sensitive to noise. Any noise induced in - * the sensor wires, such as by stepper motor wires run in parallel to them, - * may result in the thermocouple sensor reporting spurious errors. This - * value is the number of errors which can occur in a row before the error - * is reported. This allows us to ignore intermittent error conditions while - * still detecting an actual failure, which should result in a continuous - * stream of errors from the sensor. - * - * Set this value to 0 to fail on the first error to occur. - */ -#define THERMOCOUPLE_MAX_ERRORS 15 - -// -// Custom Thermistor 1000 parameters -// -#if TEMP_SENSOR_0 == 1000 - #define HOTEND0_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND0_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND0_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_1 == 1000 - #define HOTEND1_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND1_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND1_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_2 == 1000 - #define HOTEND2_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND2_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND2_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_3 == 1000 - #define HOTEND3_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND3_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND3_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_4 == 1000 - #define HOTEND4_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND4_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND4_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_5 == 1000 - #define HOTEND5_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND5_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND5_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_6 == 1000 - #define HOTEND6_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND6_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND6_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_7 == 1000 - #define HOTEND7_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define HOTEND7_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define HOTEND7_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_BED == 1000 - #define BED_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define BED_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define BED_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_CHAMBER == 1000 - #define CHAMBER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define CHAMBER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define CHAMBER_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_COOLER == 1000 - #define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define COOLER_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_PROBE == 1000 - #define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define PROBE_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_BOARD == 1000 - #define BOARD_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define BOARD_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define BOARD_BETA 3950 // Beta value -#endif - -#if TEMP_SENSOR_REDUNDANT == 1000 - #define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor - #define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C - #define REDUNDANT_BETA 3950 // Beta value -#endif - -/** - * Thermocouple Options — for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5). - */ -//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus. -//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board. -//#define MAX31865_SENSOR_WIRES_1 2 - -//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz. -//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors. - -//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature. -//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals. -//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439). - -//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings. -//#define MAX31865_WIRE_OHMS_1 0.0f - -/** - * Hephestos 2 24V heated bed upgrade kit. - * https://store.bq.com/en/heated-bed-kit-hephestos2 - */ -//#define HEPHESTOS2_HEATED_BED_KIT -#if ENABLED(HEPHESTOS2_HEATED_BED_KIT) - #undef TEMP_SENSOR_BED - #define TEMP_SENSOR_BED 70 - #define HEATER_BED_INVERTING true -#endif - -// -// Heated Bed Bang-Bang options -// -#if DISABLED(PIDTEMPBED) - #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control - #if ENABLED(BED_LIMIT_SWITCHING) - #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS - #endif -#endif - -// -// Heated Chamber options -// -#if DISABLED(PIDTEMPCHAMBER) - #define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control - #if ENABLED(CHAMBER_LIMIT_SWITCHING) - #define CHAMBER_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS - #endif -#endif - -#if TEMP_SENSOR_CHAMBER - //#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug) - //#define HEATER_CHAMBER_INVERTING false - //#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug) - - //#define CHAMBER_FAN // Enable a fan on the chamber - #if ENABLED(CHAMBER_FAN) - //#define CHAMBER_FAN_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan) - #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on. - #if CHAMBER_FAN_MODE == 0 - #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) - #elif CHAMBER_FAN_MODE == 1 - #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target - #elif CHAMBER_FAN_MODE == 2 - #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target - #elif CHAMBER_FAN_MODE == 3 - #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255) - #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target - #endif - #endif - - //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber - #if ENABLED(CHAMBER_VENT) - #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo - #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber - #define LOW_EXCESS_HEAT_LIMIT 3 - #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 - #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 - #endif -#endif - -// -// Laser Cooler options -// -#if TEMP_SENSOR_COOLER - #define COOLER_MINTEMP 8 // (°C) - #define COOLER_MAXTEMP 26 // (°C) - #define COOLER_DEFAULT_TEMP 16 // (°C) - #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target - #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay) - #define COOLER_INVERTING false - #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required. - #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc. - #define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g. - #if ENABLED(COOLER_FAN) - #define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target - #define COOLER_FAN_FACTOR 25 // PWM increase per °C above target - #endif -#endif - -// -// Motherboard Sensor options -// -#if TEMP_SENSOR_BOARD - #define THERMAL_PROTECTION_BOARD // Halt the printer if the board sensor leaves the temp range below. - #define BOARD_MINTEMP 8 // (°C) - #define BOARD_MAXTEMP 70 // (°C) - #ifndef TEMP_BOARD_PIN - //#define TEMP_BOARD_PIN -1 // Board temp sensor pin, if not set in pins file. - #endif -#endif - -/** - * Thermal Protection provides additional protection to your printer from damage - * and fire. Marlin always includes safe min and max temperature ranges which - * protect against a broken or disconnected thermistor wire. - * - * The issue: If a thermistor falls out, it will report the much lower - * temperature of the air in the room, and the 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 - - //#define ADAPTIVE_FAN_SLOWING // Slow part cooling fan if temperature drops - #if BOTH(ADAPTIVE_FAN_SLOWING, PIDTEMP) - //#define NO_FAN_SLOWING_IN_PID_TUNING // Don't slow fan speed during M303 - #endif - - /** - * Whenever an M104, M109, or M303 increases the target temperature, the - * firmware will wait for the WATCH_TEMP_PERIOD to expire. If the temperature - * hasn't increased by WATCH_TEMP_INCREASE degrees, the machine is halted and - * requires a hard reset. This test restarts with any M104/M109/M303, 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 set - * below 2. - */ - #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) - #define THERMAL_PROTECTION_BED_PERIOD 20 // Seconds - #define THERMAL_PROTECTION_BED_HYSTERESIS 2 // Degrees Celsius - - /** - * As described above, except for the bed (M140/M190/M303). - */ - #define WATCH_BED_TEMP_PERIOD 60 // Seconds - #define WATCH_BED_TEMP_INCREASE 2 // Degrees Celsius -#endif - -/** - * Thermal Protection parameters for the heated chamber. - */ -#if ENABLED(THERMAL_PROTECTION_CHAMBER) - #define THERMAL_PROTECTION_CHAMBER_PERIOD 20 // Seconds - #define THERMAL_PROTECTION_CHAMBER_HYSTERESIS 2 // Degrees Celsius - - /** - * Heated chamber watch settings (M141/M191). - */ - #define WATCH_CHAMBER_TEMP_PERIOD 60 // Seconds - #define WATCH_CHAMBER_TEMP_INCREASE 2 // Degrees Celsius -#endif - -/** - * Thermal Protection parameters for the laser cooler. - */ -#if ENABLED(THERMAL_PROTECTION_COOLER) - #define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds - #define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius - - /** - * Laser cooling watch settings (M143/M193). - */ - #define WATCH_COOLER_TEMP_PERIOD 60 // Seconds - #define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius -#endif - -#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER) - /** - * Thermal Protection Variance Monitor - EXPERIMENTAL. - * Kill the machine on a stuck temperature sensor. Disable if you get false positives. - */ - //#define THERMAL_PROTECTION_VARIANCE_MONITOR // Detect a sensor malfunction preventing temperature updates -#endif - -#if ENABLED(PIDTEMP) - // Add an experimental additional term to the heater power, proportional to the extrusion speed. - // A well-chosen Kc value should add just enough power to melt the increased material volume. - //#define PID_EXTRUSION_SCALING - #if ENABLED(PID_EXTRUSION_SCALING) - #define DEFAULT_Kc (100) // heating power = Kc * e_speed - #define LPQ_MAX_LEN 50 - #endif - - /** - * Add an experimental additional term to the heater power, proportional to the fan speed. - * A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan. - * You can either just add a constant compensation with the DEFAULT_Kf value - * or follow the instruction below to get speed-dependent compensation. - * - * Constant compensation (use only with fanspeeds of 0% and 100%) - * --------------------------------------------------------------------- - * A good starting point for the Kf-value comes from the calculation: - * kf = (power_fan * eff_fan) / power_heater * 255 - * where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater. - * - * Example: - * Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8 - * Kf = (2.4W * 0.8) / 40W * 255 = 12.24 - * - * Fan-speed dependent compensation - * -------------------------------- - * 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%). - * Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled. - * If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature - * drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big. - * 2. Note the Kf-value for fan-speed at 100% - * 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving. - * 4. Repeat step 1. and 2. for this fan speed. - * 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in - * PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED - */ - //#define PID_FAN_SCALING - #if ENABLED(PID_FAN_SCALING) - //#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION - #if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION) - // The alternative definition is used for an easier configuration. - // Just figure out Kf at fullspeed (255) and PID_FAN_SCALING_MIN_SPEED. - // DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly. - - #define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf - #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf - #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING - - #define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED) - #define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0 - - #else - #define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed) - #define DEFAULT_Kf 10 // A constant value added to the PID-tuner - #define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING - #endif - #endif -#endif - -/** - * Automatic Temperature Mode - * - * Dynamically adjust the hotend target temperature based on planned E moves. - * - * (Contrast with PID_EXTRUSION_SCALING, which tracks E movement and adjusts PID - * behavior using an additional kC value.) - * - * Autotemp is calculated by (mintemp + factor * mm_per_sec), capped to maxtemp. - * - * Enable Autotemp Mode with M104/M109 F S B. - * Disable by sending M104/M109 with no F parameter (or F0 with AUTOTEMP_PROPORTIONAL). - */ -#define AUTOTEMP -#if ENABLED(AUTOTEMP) - #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0) - // Turn on AUTOTEMP on M104/M109 by default using proportions set here - //#define AUTOTEMP_PROPORTIONAL - #if ENABLED(AUTOTEMP_PROPORTIONAL) - #define AUTOTEMP_MIN_P 0 // (°C) Added to the target temperature - #define AUTOTEMP_MAX_P 5 // (°C) Added to the target temperature - #define AUTOTEMP_FACTOR_P 1 // Apply this F parameter by default (overridden by M104/M109 F) - #endif -#endif - -// Show 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 TEMP_SENSOR_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/min) - #define EXTRUDER_RUNOUT_EXTRUDE 5 // (mm) -#endif - -/** - * Hotend Idle Timeout - * Prevent filament in the nozzle from charring and causing a critical jam. - */ -//#define HOTEND_IDLE_TIMEOUT -#if ENABLED(HOTEND_IDLE_TIMEOUT) - #define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection - #define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection - #define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout - #define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout -#endif - -// @section temperature - -// Calibration for AD595 / AD8495 sensor to adjust temperature measurements. -// The final temperature is calculated as (measuredTemp * GAIN) + OFFSET. -#define TEMP_SENSOR_AD595_OFFSET 0.0 -#define TEMP_SENSOR_AD595_GAIN 1.0 -#define TEMP_SENSOR_AD8495_OFFSET 0.0 -#define TEMP_SENSOR_AD8495_GAIN 1.0 - -/** - * Controller Fan - * To cool down the stepper drivers and MOSFETs. - * - * The fan turns on automatically whenever any driver is enabled and turns - * off (or reduces to idle speed) shortly after drivers are turned off. - */ -//#define USE_CONTROLLER_FAN -#if ENABLED(USE_CONTROLLER_FAN) - //#define CONTROLLER_FAN_PIN -1 // Set a custom pin for the controller fan - //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered - //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled. - #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.) - #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled - #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled - #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors - - // Use TEMP_SENSOR_BOARD as a trigger for enabling the controller fan - //#define CONTROLLER_FAN_MIN_BOARD_TEMP 40 // (°C) Turn on the fan if the board reaches this temperature - - //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings - #if ENABLED(CONTROLLER_FAN_EDITABLE) - #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu - #endif -#endif - -// When first starting the main fan, run it at full speed for the -// 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 - -// Some coolers may require a non-zero "off" state. -//#define FAN_OFF_PWM 1 - -/** - * PWM Fan Scaling - * - * Define the min/max speeds for PWM fans (as set with M106). - * - * With these options the M106 0-255 value range is scaled to a subset - * to ensure that the fan has enough power to spin, or to run lower - * current fans with higher current. (e.g., 5V/12V fans with 12V/24V) - * Value 0 always turns off the fan. - * - * Define one or both of these to override the default 0-255 range. - */ -//#define FAN_MIN_PWM 50 -//#define FAN_MAX_PWM 128 - -/** - * Fan Fast PWM - * - * Combinations of PWM Modes, prescale values and TOP resolutions are used internally - * to produce a frequency as close as possible to the desired frequency. - * - * FAST_PWM_FAN_FREQUENCY - * Set this to your desired frequency. - * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1) - * i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers. - * For non AVR, if left undefined this defaults to F = 1Khz. - * This F value is only to protect the hardware from an absence of configuration - * and not to complete it when users are not aware that the frequency must be specifically set to support the target board. - * - * NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior. - * Setting very high frequencies can damage your hardware. - * - * USE_OCR2A_AS_TOP [undefined by default] - * Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2: - * 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz] - * 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz] - * A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of - * PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.) - * USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies. - */ -//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino -#if ENABLED(FAST_PWM_FAN) - //#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below - //#define USE_OCR2A_AS_TOP - #ifndef FAST_PWM_FAN_FREQUENCY - #ifdef __AVR__ - #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1)) - #else - #define FAST_PWM_FAN_FREQUENCY 1000U - #endif - #endif -#endif - -/** - * Use one of the PWM fans as a redundant part-cooling fan - */ -//#define REDUNDANT_PART_COOLING_FAN 2 // Index of the fan to sync with FAN 0. - -// @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 E5_AUTO_FAN_PIN -1 -#define E6_AUTO_FAN_PIN -1 -#define E7_AUTO_FAN_PIN -1 -#define CHAMBER_AUTO_FAN_PIN -1 -#define COOLER_AUTO_FAN_PIN -1 - -#define EXTRUDER_AUTO_FAN_TEMPERATURE 50 -#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed -#define CHAMBER_AUTO_FAN_TEMPERATURE 30 -#define CHAMBER_AUTO_FAN_SPEED 255 -#define COOLER_AUTO_FAN_TEMPERATURE 18 -#define COOLER_AUTO_FAN_SPEED 255 - -/** - * Hotend Cooling Fans tachometers - * - * Define one or more tachometer pins to enable fan speed - * monitoring, and reporting of fan speeds with M123. - * - * NOTE: Only works with fans up to 7000 RPM. - */ -//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed -//#define E0_FAN_TACHO_PIN -1 -//#define E0_FAN_TACHO_PULLUP -//#define E0_FAN_TACHO_PULLDOWN -//#define E1_FAN_TACHO_PIN -1 -//#define E1_FAN_TACHO_PULLUP -//#define E1_FAN_TACHO_PULLDOWN -//#define E2_FAN_TACHO_PIN -1 -//#define E2_FAN_TACHO_PULLUP -//#define E2_FAN_TACHO_PULLDOWN -//#define E3_FAN_TACHO_PIN -1 -//#define E3_FAN_TACHO_PULLUP -//#define E3_FAN_TACHO_PULLDOWN -//#define E4_FAN_TACHO_PIN -1 -//#define E4_FAN_TACHO_PULLUP -//#define E4_FAN_TACHO_PULLDOWN -//#define E5_FAN_TACHO_PIN -1 -//#define E5_FAN_TACHO_PULLUP -//#define E5_FAN_TACHO_PULLDOWN -//#define E6_FAN_TACHO_PIN -1 -//#define E6_FAN_TACHO_PULLUP -//#define E6_FAN_TACHO_PULLDOWN -//#define E7_FAN_TACHO_PIN -1 -//#define E7_FAN_TACHO_PULLUP -//#define E7_FAN_TACHO_PULLDOWN - -/** - * 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 CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting. - //#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255) - //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu - #if ENABLED(NEOPIXEL_LED) - //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light - #endif - #if EITHER(RGB_LED, RGBW_LED) - //#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light - #endif - #if EITHER(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) - #define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White } - #endif -#endif - -// @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. - -// Employ an external closed loop controller. Override pins here if needed. -//#define EXTERNAL_CLOSED_LOOP_CONTROLLER -#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - //#define CLOSED_LOOP_ENABLE_PIN -1 - //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1 -#endif - -/** - * Dual X Carriage - * - * This setup has two X carriages that can move independently, each with its own hotend. - * The carriages can be used to print an object with two colors or materials, or in - * "duplication mode" it can print two identical or X-mirrored objects simultaneously. - * The inactive carriage is parked automatically to prevent oozing. - * X1 is the left carriage, X2 the right. They park and home at opposite ends of the X axis. - * By default the X2 stepper is assigned to the first unused E plug on the board. - * - * The following Dual X Carriage modes can be selected with M605 S: - * - * 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) - * - * 1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so - * that additional slicer support is not required. (M605 S1) - * - * 2 : (DUPLICATION) The firmware moves the second X-carriage and extruder in synchronization with - * the first X-carriage and extruder, to print 2 copies of the same object at the same time. - * Set the constant X-offset and temperature differential with M605 S2 X[offs] R[deg] and - * follow with M605 S2 to initiate duplicated movement. - * - * 3 : (MIRRORED) Formbot/Vivedino-inspired mirrored mode in which the second extruder duplicates - * the movement of the first except the second extruder is reversed in the X axis. - * Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and - * follow with M605 S3 to initiate mirrored movement. - */ -//#define DUAL_X_CARRIAGE -#if ENABLED(DUAL_X_CARRIAGE) - #define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS - #define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage - #define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage - #define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position - #define X2_HOME_DIR 1 // Set to 1. The X2 carriage always homes to the max endstop position - #define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS. - // NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS. - // This allows recalibration of endstops distance without a rebuild. - // Remember to set the second extruder's X-offset to 0 in your slicer. - - // This is the default power-up mode which can be changed later using M605 S. - #define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE - - // Default x offset in duplication mode (typically set to half print bed width) - #define DEFAULT_DUPLICATION_X_OFFSET 100 - - // Default action to execute following M605 mode change commands. Typically G28X to apply new mode. - //#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X" -#endif - -/** - * Multi-Stepper / Multi-Endstop - * - * When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem. - * The following explanations for X also apply to Y and Z multi-stepper setups. - * Endstop offsets may be changed by 'M666 X Y Z' and stored to EEPROM. - * - * - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X. - * - * - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset. - * - * - Extra endstops are included in the output of 'M119'. - * - * - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop. - * Applied to the X2 motor on 'G28' / 'G28 X'. - * Get the offset by homing X and measuring the error. - * Also set with 'M666 X' and stored to EEPROM with 'M500'. - * - * - Use X2_USE_ENDSTOP to set the endstop plug by name. (_XMIN_, _XMAX_, _YMIN_, _YMAX_, _ZMIN_, _ZMAX_) - */ -#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE) - //#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X - //#define X_DUAL_ENDSTOPS // X2 has its own endstop - #if ENABLED(X_DUAL_ENDSTOPS) - #define X2_USE_ENDSTOP _XMAX_ // X2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop - #endif -#endif - -#if HAS_DUAL_Y_STEPPERS - //#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y - //#define Y_DUAL_ENDSTOPS // Y2 has its own endstop - #if ENABLED(Y_DUAL_ENDSTOPS) - #define Y2_USE_ENDSTOP _YMAX_ // Y2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop - #endif -#endif - -// -// Multi-Z steppers -// -#ifdef Z2_DRIVER_TYPE - //#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z - - //#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z2_USE_ENDSTOP _XMAX_ // Z2 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Y endstop - #endif - #ifdef Z3_DRIVER_TYPE - //#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z3_USE_ENDSTOP _YMAX_ // Z3 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Y endstop - #endif - #endif - #ifdef Z4_DRIVER_TYPE - //#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z - #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z4_USE_ENDSTOP _ZMAX_ // Z4 endstop board plug. Don't forget to enable USE_*_PLUG. - #define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Y endstop - #endif - #endif -#endif - -// Drive the E axis with two synchronized steppers -//#define E_DUAL_STEPPER_DRIVERS -#if ENABLED(E_DUAL_STEPPER_DRIVERS) - //#define INVERT_E1_VS_E0_DIR // E direction signals are opposites -#endif - -// Activate a solenoid on the active extruder with M380. Disable all with M381. -// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid. -//#define EXT_SOLENOID - -// @section homing - -/** - * Homing Procedure - * Homing (G28) does an indefinite move towards the endstops to establish - * the position of the toolhead relative to the workspace. - */ - -//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (mm) Backoff from endstops before sensorless homing - -#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump -#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate) - -//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (mm) Backoff from endstops after homing - -#define QUICK_HOME // If G28 contains XY do a diagonal move first -//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X -//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe). -//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first - -// @section bltouch - -#if ENABLED(BLTOUCH) - /** - * Either: Use the defaults (recommended) or: For special purposes, use the following DEFINES - * Do not activate settings that the probe might not understand. Clones might misunderstand - * advanced commands. - * - * Note: If the probe is not deploying, do a "Reset" and "Self-Test" and then check the - * wiring of the BROWN, RED and ORANGE wires. - * - * Note: If the trigger signal of your probe is not being recognized, it has been very often - * because the BLACK and WHITE wires needed to be swapped. They are not "interchangeable" - * like they would be with a real switch. So please check the wiring first. - * - * Settings for all BLTouch and clone probes: - */ - - // Safety: The probe needs time to recognize the command. - // Minimum command delay (ms). Enable and increase if needed. - //#define BLTOUCH_DELAY 500 - - /** - * Settings for BLTOUCH Classic 1.2, 1.3 or BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1, and most clones: - */ - - // Feature: Switch into SW mode after a deploy. It makes the output pulse longer. Can be useful - // in special cases, like noisy or filtered input configurations. - //#define BLTOUCH_FORCE_SW_MODE - - /** - * Settings for BLTouch Smart 3.0 and 3.1 - * Summary: - * - Voltage modes: 5V and OD (open drain - "logic voltage free") output modes - * - High-Speed mode - * - Disable LCD voltage options - */ - - /** - * Danger: Don't activate 5V mode unless attached to a 5V-tolerant controller! - * V3.0 or 3.1: Set default mode to 5V mode at Marlin startup. - * If disabled, OD mode is the hard-coded default on 3.0 - * On startup, Marlin will compare its eeprom to this value. If the selected mode - * differs, a mode set eeprom write will be completed at initialization. - * Use the option below to force an eeprom write to a V3.1 probe regardless. - */ - //#define BLTOUCH_SET_5V_MODE - - /** - * Safety: Activate if connecting a probe with an unknown voltage mode. - * V3.0: Set a probe into mode selected above at Marlin startup. Required for 5V mode on 3.0 - * V3.1: Force a probe with unknown mode into selected mode at Marlin startup ( = Probe EEPROM write ) - * To preserve the life of the probe, use this once then turn it off and re-flash. - */ - //#define BLTOUCH_FORCE_MODE_SET - - /** - * Enable "HIGH SPEED" option for probing. - * Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems. - * This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians - * might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM. - * - * Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset. - */ - //#define BLTOUCH_HS_MODE true - - // Safety: Enable voltage mode settings in the LCD menu. - //#define BLTOUCH_LCD_VOLTAGE_MENU - -#endif // BLTOUCH - -// @section extras - -/** - * Z Steppers Auto-Alignment - * Add the G34 command to align multiple Z steppers using a bed probe. - */ -//#define Z_STEPPER_AUTO_ALIGN -#if ENABLED(Z_STEPPER_AUTO_ALIGN) - /** - * Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]] - * These positions are machine-relative and do not shift with the M206 home offset! - * If not defined, probe limits will be used. - * Override with 'M422 S X Y'. - */ - //#define Z_STEPPER_ALIGN_XY { { 10, 190 }, { 100, 10 }, { 190, 190 } } - - /** - * Orientation for the automatically-calculated probe positions. - * Override Z stepper align points with 'M422 S X Y' - * - * 2 Steppers: (0) (1) - * | | 2 | - * | 1 2 | | - * | | 1 | - * - * 3 Steppers: (0) (1) (2) (3) - * | 3 | 1 | 2 1 | 2 | - * | | 3 | | 3 | - * | 1 2 | 2 | 3 | 1 | - * - * 4 Steppers: (0) (1) (2) (3) - * | 4 3 | 1 4 | 2 1 | 3 2 | - * | | | | | - * | 1 2 | 2 3 | 3 4 | 4 1 | - */ - #ifndef Z_STEPPER_ALIGN_XY - //#define Z_STEPPERS_ORIENTATION 0 - #endif - - /** - * Z Stepper positions for more rapid convergence in bed alignment. - * Requires 3 or 4 Z steppers. - * - * Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw - * positions in the bed carriage, with one position per Z stepper in stepper - * driver order. - */ - //#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } } - - #ifndef Z_STEPPER_ALIGN_STEPPER_XY - // Amplification factor. Used to scale the correction step up or down in case - // the stepper (spindle) position is farther out than the test point. - #define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability! - #endif - - // On a 300mm bed a 5% grade would give a misalignment of ~1.5cm - #define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle - #define Z_STEPPER_ALIGN_ITERATIONS 3 // Number of iterations to apply during alignment - #define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this - #define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done? - // After G34, re-home Z (G28 Z) or just calculate it from the last probe heights? - // Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed. - #define HOME_AFTER_G34 -#endif - -// -// Add the G35 command to read bed corners to help adjust screws. Requires a bed probe. -// -//#define ASSISTED_TRAMMING -#if ENABLED(ASSISTED_TRAMMING) - - // Define positions for probe points. - #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } } - - // Define position names for probe points. - #define TRAMMING_POINT_NAME_1 "Front-Left" - #define TRAMMING_POINT_NAME_2 "Front-Right" - #define TRAMMING_POINT_NAME_3 "Back-Right" - #define TRAMMING_POINT_NAME_4 "Back-Left" - - #define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation - //#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first - - //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu - - //#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment - - /** - * Screw thread: - * M3: 30 = Clockwise, 31 = Counter-Clockwise - * M4: 40 = Clockwise, 41 = Counter-Clockwise - * M5: 50 = Clockwise, 51 = Counter-Clockwise - */ - #define TRAMMING_SCREW_THREAD 30 - -#endif - -// @section motion - -#define AXIS_RELATIVE_MODES { false, false, false, false } - -// Add a Duplicate option for well-separated conjoined nozzles -//#define MULTI_NOZZLE_DUPLICATION - -// 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_I_STEP_PIN false -#define INVERT_J_STEP_PIN false -#define INVERT_K_STEP_PIN false -#define INVERT_E_STEP_PIN false - -/** - * Idle Stepper Shutdown - * Set DISABLE_INACTIVE_? 'true' to shut down axis steppers after an idle period. - * The Deactive Time can be overridden with M18 and M84. Set to 0 for No Timeout. - */ -#define DEFAULT_STEPPER_DEACTIVE_TIME 120 -#define DISABLE_INACTIVE_X true -#define DISABLE_INACTIVE_Y true -#define DISABLE_INACTIVE_Z false // Set 'false' if the nozzle could fall onto your printed part! -#define DISABLE_INACTIVE_I true -#define DISABLE_INACTIVE_J true -#define DISABLE_INACTIVE_K true -#define DISABLE_INACTIVE_E true - -// Default Minimum Feedrates for printing and travel moves -#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S. -#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T. - -// Minimum time that a segment needs to take as the buffer gets emptied -#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B. - -// Slow down the machine if the lookahead buffer is (by default) half full. -// Increase the slowdown divisor for larger buffer sizes. -#define SLOWDOWN -#if ENABLED(SLOWDOWN) - #define SLOWDOWN_DIVISOR 2 -#endif - -/** - * XY Frequency limit - * Reduce resonance by limiting the frequency of small zigzag infill moves. - * See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html - * Use M201 F G to change limits at runtime. - */ -//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F. -#ifdef XY_FREQUENCY_LIMIT - #define XY_FREQUENCY_MIN_PERCENT 5 // (percent) Minimum FR percentage to apply. Set with M201 G. -#endif - -// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end -// of the buffer and all stops. This should not be much greater than zero and should only be changed -// if unwanted behavior is observed on a user's machine when running at very slow speeds. -#define MINIMUM_PLANNER_SPEED 0.05 // (mm/s) - -// -// Backlash Compensation -// Adds extra movement to axes on direction-changes to account for backlash. -// -//#define BACKLASH_COMPENSATION -#if ENABLED(BACKLASH_COMPENSATION) - // Define values for backlash distance and correction. - // If BACKLASH_GCODE is enabled these values are the defaults. - #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm) One value for each linear axis - #define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction - - // Add steps for motor direction changes on CORE kinematics - //#define CORE_BACKLASH - - // Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments - // to reduce print artifacts. (Enabling this is costly in memory and computation!) - //#define BACKLASH_SMOOTHING_MM 3 // (mm) - - // Add runtime configuration and tuning of backlash values (M425) - //#define BACKLASH_GCODE - - #if ENABLED(BACKLASH_GCODE) - // Measure the Z backlash when probing (G29) and set with "M425 Z" - #define MEASURE_BACKLASH_WHEN_PROBING - - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - // When measuring, the probe will move up to BACKLASH_MEASUREMENT_LIMIT - // mm away from point of contact in BACKLASH_MEASUREMENT_RESOLUTION - // increments while checking for the contact to be broken. - #define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm) - #define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm) - #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min) - #endif - #endif -#endif - -/** - * Automatic backlash, position and hotend offset calibration - * - * Enable G425 to run automatic calibration using an electrically- - * conductive cube, bolt, or washer mounted on the bed. - * - * G425 uses the probe to touch the top and sides of the calibration object - * on the bed and measures and/or correct positional offsets, axis backlash - * and hotend offsets. - * - * Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within - * ±5mm of true values for G425 to succeed. - */ -//#define CALIBRATION_GCODE -#if ENABLED(CALIBRATION_GCODE) - - //#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..." - //#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved" - - #define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm - - #define CALIBRATION_FEEDRATE_SLOW 60 // mm/min - #define CALIBRATION_FEEDRATE_FAST 1200 // mm/min - #define CALIBRATION_FEEDRATE_TRAVEL 3000 // mm/min - - // The following parameters refer to the conical section of the nozzle tip. - #define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm - #define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // mm - - // Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM). - //#define CALIBRATION_REPORTING - - // The true location and dimension the cube/bolt/washer on the bed. - #define CALIBRATION_OBJECT_CENTER { 264.0, -22.0, -2.0 } // mm - #define CALIBRATION_OBJECT_DIMENSIONS { 10.0, 10.0, 10.0 } // mm - - // Comment out any sides which are unreachable by the probe. For best - // auto-calibration results, all sides must be reachable. - #define CALIBRATION_MEASURE_RIGHT - #define CALIBRATION_MEASURE_FRONT - #define CALIBRATION_MEASURE_LEFT - #define CALIBRATION_MEASURE_BACK - - //#define CALIBRATION_MEASURE_IMIN - //#define CALIBRATION_MEASURE_IMAX - //#define CALIBRATION_MEASURE_JMIN - //#define CALIBRATION_MEASURE_JMAX - //#define CALIBRATION_MEASURE_KMIN - //#define CALIBRATION_MEASURE_KMAX - - // Probing at the exact top center only works if the center is flat. If - // probing on a screwhead or hollow washer, probe near the edges. - //#define CALIBRATION_MEASURE_AT_TOP_EDGES - - // Define the pin to read during calibration - #ifndef CALIBRATION_PIN - //#define CALIBRATION_PIN -1 // Define here to override the default pin - #define CALIBRATION_PIN_INVERTING false // Set to true to invert the custom pin - //#define CALIBRATION_PIN_PULLDOWN - #define CALIBRATION_PIN_PULLUP - #endif -#endif - -/** - * Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies - * below 1kHz (for AVR) or 10kHz (for ARM), where aliasing between axes in multi-axis moves causes audible - * vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the - * lowest stepping frequencies. - */ -//#define ADAPTIVE_STEP_SMOOTHING - -/** - * Custom Microstepping - * Override as-needed for your setup. Up to 3 MS pins are supported. - */ -//#define MICROSTEP1 LOW,LOW,LOW -//#define MICROSTEP2 HIGH,LOW,LOW -//#define MICROSTEP4 LOW,HIGH,LOW -//#define MICROSTEP8 HIGH,HIGH,LOW -//#define MICROSTEP16 LOW,LOW,HIGH -//#define MICROSTEP32 HIGH,LOW,HIGH - -// Microstep settings (Requires a board with pins named X_MS1, X_MS2, etc.) -#define MICROSTEP_MODES { 16, 16, 16, 16, 16, 16 } // [1,2,4,8,16] - -/** - * @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, AZTEEG_X5_MINI_WIFI, 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 - -/** - * I2C-based DIGIPOTs (e.g., Azteeg X3 Pro) - */ -//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster -//#define DIGIPOT_MCP4451 -#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451) - #define DIGIPOT_I2C_NUM_CHANNELS 5 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5 - - // Actual motor currents in Amps, need as many here as DIGIPOT_I2C_NUM_CHANNELS - #define DIGIPOT_I2C_MOTOR_CURRENTS { 0.84, 0.84, 0.4, 1.0, 1.0 } // AZTEEG_X3_PRO - - //#define DIGIPOT_USE_RAW_VALUES // Use DIGIPOT_MOTOR_CURRENT raw wiper values (instead of A4988 motor currents) - - /** - * Common slave addresses: - * - * A (A shifted) B (B shifted) IC - * Smoothie 0x2C (0x58) 0x2D (0x5A) MCP4451 - * AZTEEG_X3_PRO 0x2C (0x58) 0x2E (0x5C) MCP4451 - * AZTEEG_X5_MINI 0x2C (0x58) 0x2E (0x5C) MCP4451 - * AZTEEG_X5_MINI_WIFI 0x58 0x5C MCP4451 - * MIGHTYBOARD_REVE 0x2F (0x5E) MCP4018 - */ - //#define DIGIPOT_I2C_ADDRESS_A 0x2C // Unshifted slave address for first DIGIPOT - //#define DIGIPOT_I2C_ADDRESS_B 0x2D // Unshifted slave address for second DIGIPOT -#endif - -//=========================================================================== -//=============================Additional Features=========================== -//=========================================================================== - -// @section lcd - -#if HAS_MANUAL_MOVE_MENU - #define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel - #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines - #if IS_ULTIPANEL - #define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position" - //#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen - #endif -#endif - -// Change values more rapidly when the encoder is rotated faster -#define ENCODER_RATE_MULTIPLIER -#if ENABLED(ENCODER_RATE_MULTIPLIER) - #define ENCODER_10X_STEPS_PER_SEC 30 // (steps/s) Encoder rate for 10x speed - #define ENCODER_100X_STEPS_PER_SEC 80 // (steps/s) Encoder rate for 100x speed -#endif - -// Play a beep when the feedrate is changed from the Status Screen -//#define BEEP_ON_FEEDRATE_CHANGE -#if ENABLED(BEEP_ON_FEEDRATE_CHANGE) - #define FEEDRATE_CHANGE_BEEP_DURATION 10 - #define FEEDRATE_CHANGE_BEEP_FREQUENCY 440 -#endif - -// -// LCD Backlight Timeout -// -//#define LCD_BACKLIGHT_TIMEOUT 30 // (s) Timeout before turning off the backlight - -#if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI) - //#define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu - #if ENABLED(PROBE_OFFSET_WIZARD) - /** - * Enable to init the Probe Z-Offset when starting the Wizard. - * Use a height slightly above the estimated nozzle-to-probe Z offset. - * For example, with an offset of -5, consider a starting height of -4. - */ - //#define PROBE_OFFSET_WIZARD_START_Z -4.0 - - // Set a convenient position to do the calibration (probing point and nozzle/bed-distance) - //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER } - #endif -#endif - -#if HAS_MARLINUI_MENU - - #if HAS_BED_PROBE - // Add calibration in the Probe Offsets menu to compensate for X-axis twist. - //#define X_AXIS_TWIST_COMPENSATION - #if ENABLED(X_AXIS_TWIST_COMPENSATION) - /** - * Enable to init the Probe Z-Offset when starting the Wizard. - * Use a height slightly above the estimated nozzle-to-probe Z offset. - * For example, with an offset of -5, consider a starting height of -4. - */ - #define XATC_START_Z 0.0 - #define XATC_MAX_POINTS 3 // Number of points to probe in the wizard - #define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe - #define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points - #endif - #endif - - // Include a page of printer information in the LCD Main Menu - //#define LCD_INFO_MENU - #if ENABLED(LCD_INFO_MENU) - //#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages - #endif - - // BACK menu items keep the highlight at the top - //#define TURBO_BACK_MENU_ITEM - - // Insert a menu for preheating at the top level to allow for quick access - //#define PREHEAT_SHORTCUT_MENU_ITEM - -#endif // HAS_MARLINUI_MENU - -#if ANY(HAS_DISPLAY, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI) - //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu - #define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state -#endif - -#if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI) - // The timeout to return to the status screen from sub-menus - //#define LCD_TIMEOUT_TO_STATUS 15000 // (ms) - - #if ENABLED(SHOW_BOOTSCREEN) - #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s) - #if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI) - #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash) - #endif - #endif - - // Scroll a longer status message into view - //#define STATUS_MESSAGE_SCROLLING - - // Apply a timeout to low-priority status messages - //#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds) - - // On the Info Screen, display XY with one decimal place when possible - //#define LCD_DECIMAL_SMALL_XY - - // Add an 'M73' G-code to set the current percentage - //#define LCD_SET_PROGRESS_MANUALLY - - // Show the E position (filament used) during printing - //#define LCD_SHOW_E_TOTAL - - /** - * LED Control Menu - * Add LED Control to the LCD menu - */ - #define LED_CONTROL_MENU - #if ENABLED(LED_CONTROL_MENU) - #define LED_COLOR_PRESETS // Enable the Preset Color menu option - //#define NEO2_COLOR_PRESETS // Enable a second NeoPixel Preset Color menu option - #if ENABLED(LED_COLOR_PRESETS) - #define LED_USER_PRESET_RED 255 // User defined RED value - #define LED_USER_PRESET_GREEN 255 // User defined GREEN value - #define LED_USER_PRESET_BLUE 255 // User defined BLUE value - #define LED_USER_PRESET_WHITE 255 // User defined WHITE value - #define LED_USER_PRESET_BRIGHTNESS 255 // User defined intensity - #define LED_USER_PRESET_STARTUP RED // Have the printer display the user preset color on startup - #endif - #if ENABLED(NEO2_COLOR_PRESETS) - #define NEO2_USER_PRESET_RED 255 // User defined RED value - #define NEO2_USER_PRESET_GREEN 128 // User defined GREEN value - #define NEO2_USER_PRESET_BLUE 0 // User defined BLUE value - #define NEO2_USER_PRESET_WHITE 255 // User defined WHITE value - #define NEO2_USER_PRESET_BRIGHTNESS 255 // User defined intensity - //#define NEO2_USER_PRESET_STARTUP // Have the printer display the user preset color on startup for the second strip - #endif - #endif - -#endif - -// LCD Print Progress options -#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) - #if CAN_SHOW_REMAINING_TIME - //#define SHOW_REMAINING_TIME // Display estimated time to completion - #if ENABLED(SHOW_REMAINING_TIME) - //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation - //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time - #endif - #endif - - #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI) - //#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits - #endif - - #if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) - //#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing - #if ENABLED(LCD_PROGRESS_BAR) - #define PROGRESS_BAR_BAR_TIME 2000 // (ms) Amount of time to show the bar - #define PROGRESS_BAR_MSG_TIME 3000 // (ms) Amount of time to show the status message - #define PROGRESS_MSG_EXPIRE 0 // (ms) Amount of time to retain the status message (0=forever) - //#define PROGRESS_MSG_ONCE // Show the message for MSG_TIME then clear it - //#define LCD_PROGRESS_BAR_TEST // Add a menu item to test the progress bar - #endif - #endif -#endif - -#if ENABLED(SDSUPPORT) - /** - * SD Card SPI Speed - * May be required to resolve "volume init" errors. - * - * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED - * otherwise full speed will be applied. - * - * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED'] - */ - //#define SD_SPI_SPEED SPI_HALF_SPEED - - // The standard SD detect circuit reads LOW when media is inserted and HIGH when empty. - // Enable this option and set to HIGH if your SD cards are incorrectly detected. - //#define SD_DETECT_STATE HIGH - - //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up - //#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash) - - //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping - - #define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls - - #define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished - #define SD_FINISHED_RELEASECOMMAND "M84" // Use "M84XYE" to keep Z enabled so your bed stays in place - - // Reverse SD sort to show "more recent" files first, according to the card's FAT. - // Since the FAT gets out of order with usage, SDCARD_SORT_ALPHA is recommended. - #define SDCARD_RATHERRECENTFIRST - - #define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing - - //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM - //#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files - - //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted - - //#define MEDIA_MENU_AT_TOP // Force the media menu to be listed on the top of the main menu - - #define EVENT_GCODE_SD_ABORT "G27" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27") - - #if ENABLED(PRINTER_EVENT_LEDS) - #define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination - #endif - - /** - * Continue after Power-Loss (Creality3D) - * - * Store the current state to the SD Card at the start of each layer - * during SD printing. If the recovery file is found at boot time, present - * an option on the LCD screen to continue the print from the last-known - * point in the file. - */ - //#define POWER_LOSS_RECOVERY - #if ENABLED(POWER_LOSS_RECOVERY) - #define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500) - //#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss - //#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS) - //#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module. - //#define POWER_LOSS_STATE HIGH // State of pin indicating power loss - //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor - //#define POWER_LOSS_PULLDOWN - //#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume - //#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power. - - // Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card, - // especially with "vase mode" printing. Set too high and vases cannot be continued. - #define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data - - // Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled! - //#define POWER_LOSS_RECOVER_ZHOME - #if ENABLED(POWER_LOSS_RECOVER_ZHOME) - //#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed - #endif - #endif - - /** - * 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! - #define SDSORT_CACHE_VFATS 2 // Maximum number of 13-byte VFAT entries to use for sorting. - // Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM. - #endif - - // Allow international symbols in long filenames. To display correctly, the - // LCD's font must contain the characters. Check your selected LCD language. - //#define UTF_FILENAME_SUPPORT - - //#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 ' and list long filenames with 'M20 L' - //#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol - - //#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu - - //#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!) - - /** - * Abort SD printing when any endstop is triggered. - * This feature is enabled with 'M540 S1' or from the LCD menu. - * Endstops must be activated for this option to work. - */ - //#define SD_ABORT_ON_ENDSTOP_HIT - - //#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file - - //#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S' - - /** - * Support for USB thumb drives using an Arduino USB Host Shield or - * equivalent MAX3421E breakout board. The USB thumb drive will appear - * to Marlin as an SD card. - * - * The MAX3421E can be assigned the same pins as the SD card reader, with - * the following pin mapping: - * - * SCLK, MOSI, MISO --> SCLK, MOSI, MISO - * INT --> SD_DETECT_PIN [1] - * SS --> SDSS - * - * [1] On AVR an interrupt-capable pin is best for UHS3 compatibility. - */ - //#define USB_FLASH_DRIVE_SUPPORT - #if ENABLED(USB_FLASH_DRIVE_SUPPORT) - /** - * USB Host Shield Library - * - * - UHS2 uses no interrupts and has been production-tested - * on a LulzBot TAZ Pro with a 32-bit Archim board. - * - * - UHS3 is newer code with better USB compatibility. But it - * is less tested and is known to interfere with Servos. - * [1] This requires USB_INTR_PIN to be interrupt-capable. - */ - //#define USE_UHS2_USB - //#define USE_UHS3_USB - - /** - * Native USB Host supported by some boards (USB OTG) - */ - //#define USE_OTG_USB_HOST - - #if DISABLED(USE_OTG_USB_HOST) - #define USB_CS_PIN SDSS - #define USB_INTR_PIN SD_DETECT_PIN - #endif - #endif - - /** - * When using a bootloader that supports SD-Firmware-Flashing, - * add a menu item to activate SD-FW-Update on the next reboot. - * - * Requires ATMEGA2560 (Arduino Mega) - * - * Tested with this bootloader: - * https://github.com/FleetProbe/MicroBridge-Arduino-ATMega2560 - */ - //#define SD_FIRMWARE_UPDATE - #if ENABLED(SD_FIRMWARE_UPDATE) - #define SD_FIRMWARE_UPDATE_EEPROM_ADDR 0x1FF - #define SD_FIRMWARE_UPDATE_ACTIVE_VALUE 0xF0 - #define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF - #endif - - /** - * Enable this option if you have more than ~3K of unused flash space. - * Marlin will embed all settings in the firmware binary as compressed data. - * Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'. - * See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'. - */ - //#define CONFIGURATION_EMBEDDING - - // Add an optimized binary file transfer mode, initiated with 'M28 B1' - //#define BINARY_FILE_TRANSFER - - #if ENABLED(BINARY_FILE_TRANSFER) - // Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER - //#define CUSTOM_FIRMWARE_UPLOAD - #endif - - /** - * Set this option to one of the following (or the board's defaults apply): - * - * LCD - Use the SD drive in the external LCD controller. - * ONBOARD - Use the SD drive on the control board. - * CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file). - * - * :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ] - */ - //#define SDCARD_CONNECTION LCD - - // Enable if SD detect is rendered useless (e.g., by using an SD extender) - //#define NO_SD_DETECT - - /** - * Multiple volume support - EXPERIMENTAL. - * Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive. - */ - //#define MULTI_VOLUME - #if ENABLED(MULTI_VOLUME) - #define VOLUME_SD_ONBOARD - #define VOLUME_USB_FLASH_DRIVE - #define DEFAULT_VOLUME SV_SD_ONBOARD - #define DEFAULT_SHARED_VOLUME SV_USB_FLASH_DRIVE - #endif - -#endif // SDSUPPORT - -/** - * By default an onboard SD card reader may be shared as a USB mass- - * storage device. This option hides the SD card from the host PC. - */ -//#define NO_SD_HOST_DRIVE // Disable SD Card access over USB (for security). - -/** - * 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 HAS_MARLINUI_U8GLIB - // Save many cycles by drawing a hollow frame or no frame on the Info Screen - //#define XYZ_NO_FRAME - #define XYZ_HOLLOW_FRAME - - // A bigger font is available for edit items. Costs 3120 bytes of flash. - // 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 2434 bytes of flash. - // Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese. - //#define USE_SMALL_INFOFONT - - /** - * Graphical Display Sleep - * - * The U8G library provides sleep / wake functions for SH1106, SSD1306, - * SSD1309, and some other DOGM displays. - * Enable this option to save energy and prevent OLED pixel burn-in. - * Adds the menu item Configuration > LCD Timeout (m) to set a wait period - * from 0 (disabled) to 99 minutes. - */ - //#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen - - /** - * ST7920-based LCDs can emulate a 16 x 4 character display using - * the ST7920 character-generator for very fast screen updates. - * Enable LIGHTWEIGHT_UI to use this special display mode. - * - * Since LIGHTWEIGHT_UI has limited space, the position and status - * message occupy the same line. Set STATUS_EXPIRE_SECONDS to the - * length of time to display the status message before clearing. - * - * Set STATUS_EXPIRE_SECONDS to zero to never clear the status. - * This will prevent position updates from being displayed. - */ - #if IS_U8GLIB_ST7920 - // Enable this option and reduce the value to optimize screen updates. - // The normal delay is 10µs. Use the lowest value that still gives a reliable display. - //#define DOGM_SPI_DELAY_US 5 - - //#define LIGHTWEIGHT_UI - #if ENABLED(LIGHTWEIGHT_UI) - #define STATUS_EXPIRE_SECONDS 20 - #endif - #endif - - /** - * Status (Info) Screen customizations - * These options may affect code size and screen render time. - * Custom status screens can forcibly override these settings. - */ - //#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones - //#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends) - #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends) - #define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating - #define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating - #define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating - //#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active - //#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling - //#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow - //#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap - //#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap - //#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames - //#define STATUS_HEAT_PERCENT // Show heating in a progress bar - //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash. - - // Frivolous Game Options - //#define MARLIN_BRICKOUT - //#define MARLIN_INVADERS - //#define MARLIN_SNAKE - //#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu - -#endif // HAS_MARLINUI_U8GLIB - -#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI - // Show SD percentage next to the progress bar - //#define SHOW_SD_PERCENT - - // Enable to save many cycles by drawing a hollow frame on Menu Screens - #define MENU_HOLLOW_FRAME - - // Swap the CW/CCW indicators in the graphics overlay - //#define OVERLAY_GFX_REVERSE -#endif - -// -// Additional options for DGUS / DWIN displays -// -#if HAS_DGUS_LCD - #define LCD_BAUDRATE 115200 - - #define DGUS_RX_BUFFER_SIZE 128 - #define DGUS_TX_BUFFER_SIZE 48 - //#define SERIAL_STATS_RX_BUFFER_OVERRUNS // Fix Rx overrun situation (Currently only for AVR) - - #define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates - - #if ANY(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS, DGUS_LCD_UI_HIPRECY) - #define DGUS_PRINT_FILENAME // Display the filename during printing - #define DGUS_PREHEAT_UI // Display a preheat screen during heatup - - #if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS) - //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS - #else - #define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY - #endif - - #define DGUS_FILAMENT_LOADUNLOAD - #if ENABLED(DGUS_FILAMENT_LOADUNLOAD) - #define DGUS_FILAMENT_PURGE_LENGTH 10 - #define DGUS_FILAMENT_LOAD_LENGTH_PER_TIME 0.5 // (mm) Adjust in proportion to DGUS_UPDATE_INTERVAL_MS - #endif - - #define DGUS_UI_WAITING // Show a "waiting" screen between some screens - #if ENABLED(DGUS_UI_WAITING) - #define DGUS_UI_WAITING_STATUS 10 - #define DGUS_UI_WAITING_STATUS_PERIOD 8 // Increase to slower waiting status looping - #endif - #endif -#endif // HAS_DGUS_LCD - -// -// Additional options for AnyCubic Chiron TFT displays -// -#if ENABLED(ANYCUBIC_LCD_CHIRON) - // By default the type of panel is automatically detected. - // Enable one of these options if you know the panel type. - //#define CHIRON_TFT_STANDARD - //#define CHIRON_TFT_NEW - - // Enable the longer Anycubic powerup startup tune - //#define AC_DEFAULT_STARTUP_TUNE - - /** - * Display Folders - * By default the file browser lists all G-code files (including those in subfolders) in a flat list. - * Enable this option to display a hierarchical file browser. - * - * NOTES: - * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders. - * - When used with the "new" panel, folder names will also have '.gcode' appended to their names. - * This hack is currently required to force the panel to show folders. - */ - #define AC_SD_FOLDER_VIEW -#endif - -// -// Specify additional languages for the UI. Default specified by LCD_LANGUAGE. -// -#if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE, IS_DWIN_MARLINUI) - //#define LCD_LANGUAGE_2 fr - //#define LCD_LANGUAGE_3 de - //#define LCD_LANGUAGE_4 es - //#define LCD_LANGUAGE_5 it - #ifdef LCD_LANGUAGE_2 - //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change - #endif -#endif - -// -// Touch UI for the FTDI Embedded Video Engine (EVE) -// -#if ENABLED(TOUCH_UI_FTDI_EVE) - // Display board used - //#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240) - //#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272) - //#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" (480x272) - //#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480) - //#define LCD_LULZBOT_CLCD_UI // LulzBot Color LCD UI - //#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480) - //#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815 - //#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813 - - // Correct the resolution if not using the stock TFT panel. - //#define TOUCH_UI_320x240 - //#define TOUCH_UI_480x272 - //#define TOUCH_UI_800x480 - - // Mappings for boards with a standard RepRapDiscount Display connector - //#define AO_EXP1_PINMAP // LulzBot CLCD UI EXP1 mapping - //#define AO_EXP2_PINMAP // LulzBot CLCD UI EXP2 mapping - //#define CR10_TFT_PINMAP // Rudolph Riedel's CR10 pin mapping - //#define S6_TFT_PINMAP // FYSETC S6 pin mapping - //#define F6_TFT_PINMAP // FYSETC F6 pin mapping - - //#define OTHER_PIN_LAYOUT // Define pins manually below - #if ENABLED(OTHER_PIN_LAYOUT) - // Pins for CS and MOD_RESET (PD) must be chosen - #define CLCD_MOD_RESET 9 - #define CLCD_SPI_CS 10 - - // If using software SPI, specify pins for SCLK, MOSI, MISO - //#define CLCD_USE_SOFT_SPI - #if ENABLED(CLCD_USE_SOFT_SPI) - #define CLCD_SOFT_SPI_MOSI 11 - #define CLCD_SOFT_SPI_MISO 12 - #define CLCD_SOFT_SPI_SCLK 13 - #endif - #endif - - // Display Orientation. An inverted (i.e. upside-down) display - // is supported on the FT800. The FT810 and beyond also support - // portrait and mirrored orientations. - //#define TOUCH_UI_INVERTED - //#define TOUCH_UI_PORTRAIT - //#define TOUCH_UI_MIRRORED - - // UTF8 processing and rendering. - // Unsupported characters are shown as '?'. - //#define TOUCH_UI_USE_UTF8 - #if ENABLED(TOUCH_UI_USE_UTF8) - // Western accents support. These accented characters use - // combined bitmaps and require relatively little storage. - #define TOUCH_UI_UTF8_WESTERN_CHARSET - #if ENABLED(TOUCH_UI_UTF8_WESTERN_CHARSET) - // Additional character groups. These characters require - // full bitmaps and take up considerable storage: - //#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³ - //#define TOUCH_UI_UTF8_COPYRIGHT // © ® - //#define TOUCH_UI_UTF8_GERMANIC // ß - //#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ à Ø Þ æ ð ø þ - //#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡ - //#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥ - //#define TOUCH_UI_UTF8_ORDINALS // º ª - //#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷ - //#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾ - //#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬ - #endif - - // Cyrillic character set, costs about 27KiB of flash - //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET - #endif - - // Use a smaller font when labels don't fit buttons - #define TOUCH_UI_FIT_TEXT - - // Use a numeric passcode for "Screen lock" keypad. - // (recommended for smaller displays) - //#define TOUCH_UI_PASSCODE - - // Output extra debug info for Touch UI events - //#define TOUCH_UI_DEBUG - - // Developer menu (accessed by touching "About Printer" copyright text) - //#define TOUCH_UI_DEVELOPER_MENU -#endif - -// -// Classic UI Options -// -#if TFT_SCALED_DOGLCD - //#define TFT_MARLINUI_COLOR 0xFFFF // White - //#define TFT_MARLINBG_COLOR 0x0000 // Black - //#define TFT_DISABLED_COLOR 0x0003 // Almost black - //#define TFT_BTCANCEL_COLOR 0xF800 // Red - //#define TFT_BTARROWS_COLOR 0xDEE6 // 11011 110111 00110 Yellow - //#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan -#endif - -// -// ADC Button Debounce -// -#if HAS_ADC_BUTTONS - #define ADC_BUTTON_DEBOUNCE_DELAY 16 // Increase if buttons bounce or repeat too fast -#endif - -// @section safety - -/** - * The watchdog hardware timer will do a reset and disable all outputs - * if the firmware gets too overloaded to read the temperature sensors. - * - * If you find that watchdog reboot causes your AVR board to hang forever, - * enable WATCHDOG_RESET_MANUAL to use a custom timer instead of WDTO. - * NOTE: This method is less reliable as it can only catch hangups while - * interrupts are enabled. - */ -#define USE_WATCHDOG -#if ENABLED(USE_WATCHDOG) - //#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 INTEGRATED_BABYSTEPPING // EXPERIMENTAL integration of babystepping into the Stepper ISR - //#define BABYSTEP_WITHOUT_HOMING - //#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement). - //#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA! - #define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way - //#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps - #define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep - #define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep - - //#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping. - #if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING) - #define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds. - // Note: Extra time may be added to mitigate controller latency. - //#define MOVE_Z_WHEN_IDLE // Jump to the move Z menu on doubleclick when printer is idle. - #if ENABLED(MOVE_Z_WHEN_IDLE) - #define MOVE_Z_IDLE_MULTIPLICATOR 1 // Multiply 1mm by this factor for the move step size. - #endif - #endif - - //#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28 - - //#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping - #if ENABLED(BABYSTEP_ZPROBE_OFFSET) - //#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets - //#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor - #endif -#endif - -// @section extruder - -/** - * Linear Pressure Control v1.5 - * - * Assumption: advance [steps] = k * (delta velocity [steps/s]) - * K=0 means advance disabled. - * - * NOTE: K values for LIN_ADVANCE 1.5 differ from earlier versions! - * - * Set K around 0.22 for 3mm PLA Direct Drive with ~6.5cm between the drive gear and heatbreak. - * Larger K values will be needed for flexible filament and greater distances. - * If this algorithm produces a higher speed offset than the extruder can handle (compared to E jerk) - * print acceleration will be reduced during the affected moves to keep within the limit. - * - * See https://marlinfw.org/docs/features/lin_advance.html for full instructions. - */ -//#define LIN_ADVANCE -#if ENABLED(LIN_ADVANCE) - //#define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants - #define LIN_ADVANCE_K 0.22 // Unit: mm compression per 1mm/s extruder speed - //#define LA_DEBUG // If enabled, this will generate debug information output over USB. - //#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration - //#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends. -#endif - -// @section leveling - -/** - * Points to probe for all 3-point Leveling procedures. - * Override if the automatically selected points are inadequate. - */ -#if EITHER(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_UBL) - //#define PROBE_PT_1_X 15 - //#define PROBE_PT_1_Y 180 - //#define PROBE_PT_2_X 15 - //#define PROBE_PT_2_Y 20 - //#define PROBE_PT_3_X 170 - //#define PROBE_PT_3_Y 20 -#endif - -/** - * Probing Margins - * - * Override PROBING_MARGIN for each side of the build plate - * Useful to get probe points to exact positions on targets or - * to allow leveling to avoid plate clamps on only specific - * sides of the bed. With NOZZLE_AS_PROBE negative values are - * allowed, to permit probing outside the bed. - * - * If you are replacing the prior *_PROBE_BED_POSITION options, - * LEFT and FRONT values in most cases will map directly over - * RIGHT and REAR would be the inverse such as - * (X/Y_BED_SIZE - RIGHT/BACK_PROBE_BED_POSITION) - * - * This will allow all positions to match at compilation, however - * should the probe position be modified with M851XY then the - * probe points will follow. This prevents any change from causing - * the probe to be unable to reach any points. - */ -#if PROBE_SELECTED && !IS_KINEMATIC - //#define PROBING_MARGIN_LEFT PROBING_MARGIN - //#define PROBING_MARGIN_RIGHT PROBING_MARGIN - //#define PROBING_MARGIN_FRONT PROBING_MARGIN - //#define PROBING_MARGIN_BACK PROBING_MARGIN -#endif - -#if EITHER(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL) - // Override the mesh area if the automatic (max) area is too large - //#define MESH_MIN_X MESH_INSET - //#define MESH_MIN_Y MESH_INSET - //#define MESH_MAX_X X_BED_SIZE - (MESH_INSET) - //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET) -#endif - -#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS) - //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space -#endif - -/** - * Repeatedly attempt G29 leveling until it succeeds. - * Stop after G29_MAX_RETRIES attempts. - */ -//#define G29_RETRY_AND_RECOVER -#if ENABLED(G29_RETRY_AND_RECOVER) - #define G29_MAX_RETRIES 3 - #define G29_HALT_ON_FAILURE - /** - * Specify the GCODE commands that will be executed when leveling succeeds, - * between attempts, and after the maximum number of retries have been tried. - */ - #define G29_SUCCESS_COMMANDS "M117 Bed leveling done." - #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0" - #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1" - -#endif - -/** - * Thermal Probe Compensation - * - * Adjust probe measurements to compensate for distortion associated with the temperature - * of the probe, bed, and/or hotend. - * Use G76 to automatically calibrate this feature for probe and bed temperatures. - * (Extruder temperature/offset values must be calibrated manually.) - * Use M871 to set temperature/offset values manually. - * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html - */ -//#define PTC_PROBE // Compensate based on probe temperature -//#define PTC_BED // Compensate based on bed temperature -//#define PTC_HOTEND // Compensate based on hotend temperature - -#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND) - /** - * If the probe is outside the defined range, use linear extrapolation with the closest - * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the - * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START. - */ - //#define PTC_LINEAR_EXTRAPOLATION 4 - - #if ENABLED(PTC_PROBE) - // Probe temperature calibration generates a table of values starting at PTC_PROBE_START - // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples. - #define PTC_PROBE_START 30 // (°C) - #define PTC_PROBE_RES 5 // (°C) - #define PTC_PROBE_COUNT 10 - #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - #if ENABLED(PTC_BED) - // Bed temperature calibration builds a similar table. - #define PTC_BED_START 60 // (°C) - #define PTC_BED_RES 5 // (°C) - #define PTC_BED_COUNT 10 - #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - #if ENABLED(PTC_HOTEND) - // Note: There is no automatic calibration for the hotend. Use M871. - #define PTC_HOTEND_START 180 // (°C) - #define PTC_HOTEND_RES 5 // (°C) - #define PTC_HOTEND_COUNT 20 - #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample - #endif - - // G76 options - #if BOTH(PTC_PROBE, PTC_BED) - // Park position to wait for probe cooldown - #define PTC_PARK_POS { 0, 0, 100 } - - // Probe position to probe and wait for probe to reach target temperature - //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed - #define PTC_PROBE_POS { 90, 100 } - - // The temperature the probe should be at while taking measurements during - // bed temperature calibration. - #define PTC_PROBE_TEMP 30 // (°C) - - // Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster. - // Note: The Z=0.0 offset is determined by the probe Z offset (e.g., as set with M851 Z). - #define PTC_PROBE_HEATING_OFFSET 0.5 - #endif -#endif // PTC_PROBE || PTC_BED || PTC_HOTEND - -// @section extras - -// -// G60/G61 Position Save and Return -// -//#define SAVED_POSITIONS 1 // Each saved position slot costs 12 bytes - -// -// G2/G3 Arc Support -// -#define ARC_SUPPORT // Requires ~3226 bytes -#if ENABLED(ARC_SUPPORT) - #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment - #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment - #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle - //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length - #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections - //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles - //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure -#endif - -// G5 Bézier Curve Support with XYZE destination and IJPQ offsets -//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes - -#if EITHER(ARC_SUPPORT, BEZIER_CURVE_SUPPORT) - //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes -#endif - -/** - * Direct Stepping - * - * Comparable to the method used by Klipper, G6 direct stepping significantly - * reduces motion calculations, increases top printing speeds, and results in - * less step aliasing by calculating all motions in advance. - * Preparing your G-code: https://github.com/colinrgodsey/step-daemon - */ -//#define DIRECT_STEPPING - -/** - * G38 Probe Target - * - * This option adds G38.2 and G38.3 (probe towards target) - * and optionally G38.4 and G38.5 (probe away from target). - * Set MULTIPLE_PROBING for G38 to probe more than once. - */ -//#define G38_PROBE_TARGET -#if ENABLED(G38_PROBE_TARGET) - //#define G38_PROBE_AWAY // Include G38.4 and G38.5 to probe away from target - #define G38_MINIMUM_MOVE 0.0275 // (mm) Minimum distance that will produce a move. -#endif - -// Moves (or segments) with fewer steps than this will be joined with the next move -#define MIN_STEPS_PER_SEGMENT 6 - -/** - * Minimum delay before and after setting the stepper DIR (in ns) - * 0 : No delay (Expect at least 10µS since one Stepper ISR must transpire) - * 20 : Minimum for TMC2xxx drivers - * 200 : Minimum for A4988 drivers - * 400 : Minimum for A5984 drivers - * 500 : Minimum for LV8729 drivers (guess, no info in datasheet) - * 650 : Minimum for DRV8825 drivers - * 1500 : Minimum for TB6600 drivers (guess, no info in datasheet) - * 15000 : Minimum for TB6560 drivers (guess, no info in datasheet) - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MINIMUM_STEPPER_POST_DIR_DELAY 650 -//#define MINIMUM_STEPPER_PRE_DIR_DELAY 650 - -/** - * Minimum stepper driver pulse width (in µs) - * 0 : Smallest possible width the MCU can produce, compatible with TMC2xxx drivers - * 0 : Minimum 500ns for LV8729, adjusted in stepper.h - * 1 : Minimum for A4988 and A5984 stepper drivers - * 2 : Minimum for DRV8825 stepper drivers - * 3 : Minimum for TB6600 stepper drivers - * 30 : Minimum for TB6560 stepper drivers - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MINIMUM_STEPPER_PULSE 2 - -/** - * Maximum stepping rate (in Hz) the stepper driver allows - * If undefined, defaults to 1MHz / (2 * MINIMUM_STEPPER_PULSE) - * 5000000 : Maximum for TMC2xxx stepper drivers - * 1000000 : Maximum for LV8729 stepper driver - * 500000 : Maximum for A4988 stepper driver - * 250000 : Maximum for DRV8825 stepper driver - * 150000 : Maximum for TB6600 stepper driver - * 15000 : Maximum for TB6560 stepper driver - * - * Override the default value based on the driver type set in Configuration.h. - */ -//#define MAXIMUM_STEPPER_RATE 250000 - -// @section temperature - -// Control heater 0 and heater 1 in parallel. -//#define HEATERS_PARALLEL - -//=========================================================================== -//================================= Buffers ================================= -//=========================================================================== - -// @section motion - -// The number of linear moves that can be in the planner at once. -// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g., 8, 16, 32) -#if BOTH(SDSUPPORT, DIRECT_STEPPING) - #define BLOCK_BUFFER_SIZE 8 -#elif ENABLED(SDSUPPORT) - #define BLOCK_BUFFER_SIZE 16 -#else - #define BLOCK_BUFFER_SIZE 16 -#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 flash (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 - -// Monitor RX buffer usage -// Dump an error to the serial port if the serial receive buffer overflows. -// If you see these errors, increase the RX_BUFFER_SIZE value. -// Not supported on all platforms. -//#define RX_BUFFER_MONITOR - -/** - * Emergency Command Parser - * - * Add a low-level parser to intercept certain commands as they - * enter the serial receive buffer, so they cannot be blocked. - * Currently handles M108, M112, M410, M876 - * NOTE: Not yet implemented for all platforms. - */ -//#define EMERGENCY_PARSER - -/** - * Realtime Reporting (requires EMERGENCY_PARSER) - * - * - Report position and state of the machine (like Grbl). - * - Auto-report position during long moves. - * - Useful for CNC/LASER. - * - * Adds support for commands: - * S000 : Report State and Position while moving. - * P000 : Instant Pause / Hold while moving. - * R000 : Resume from Pause / Hold. - * - * - During Hold all Emergency Parser commands are available, as usual. - * - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports. - */ -//#define REALTIME_REPORTING_COMMANDS -#if ENABLED(REALTIME_REPORTING_COMMANDS) - //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC -#endif - -// 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 - -// Printrun may have trouble receiving long strings all at once. -// This option inserts short delays between lines of serial output. -#define SERIAL_OVERRUN_PROTECTION - -// For serial echo, the number of digits after the decimal point -//#define SERIAL_FLOAT_PRECISION 4 - -/** - * 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 - -// @section extras - -/** - * Extra Fan Speed - * Adds a secondary fan speed for each print-cooling fan. - * 'M106 P T3-255' : Set a secondary speed for - * 'M106 P T2' : Use the set secondary speed - * 'M106 P T1' : Restore the previous fan speed - */ -//#define EXTRA_FAN_SPEED - -/** - * 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 -#if ENABLED(FWRETRACT) - #define FWRETRACT_AUTORETRACT // Override slicer retractions - #if ENABLED(FWRETRACT_AUTORETRACT) - #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length - #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length - #endif - #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value) - #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value) - #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting - #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise - #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover) - #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange) - #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction - #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction - #if ENABLED(MIXING_EXTRUDER) - //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously - #endif -#endif - -/** - * Universal tool change settings. - * Applies to all types of extruders except where explicitly noted. - */ -#if HAS_MULTI_EXTRUDER - // Z raise distance for tool-change, as needed for some extruders - #define TOOLCHANGE_ZRAISE 0 // (mm) - //#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled) - //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change - #if ENABLED(TOOLCHANGE_NO_RETURN) - //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change - #endif - - /** - * Extra G-code to run while executing tool-change commands. Can be used to use an additional - * stepper motor (I axis, see option LINEAR_AXES in Configuration.h) to drive the tool-changer. - */ - //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0 - //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1 - //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution! - - /** - * Tool Sensors detect when tools have been picked up or dropped. - * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc. - */ - //#define TOOL_SENSOR - - /** - * Retract and prime filament on tool-change to reduce - * ooze and stringing and to get cleaner transitions. - */ - //#define TOOLCHANGE_FILAMENT_SWAP - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - // Load / Unload - #define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length - #define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B. - #define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading) - #define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down) - - // Longer prime to clean out a SINGLENOZZLE - #define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length - #define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate - #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc. - - // Cool after prime to reduce stringing - #define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip - #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 - #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) - - // Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed - //#define TOOLCHANGE_FS_SLOW_FIRST_PRIME - - /** - * Prime T0 the first time T0 is sent to the printer: - * [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ] - * If disabled, no priming on T0 until switching back to T0 from another extruder: - * [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ] - * Enable with M217 V1 before printing to avoid unwanted priming on host connect. - */ - //#define TOOLCHANGE_FS_PRIME_FIRST_USED - - /** - * Tool Change Migration - * This feature provides G-code and LCD options to switch tools mid-print. - * All applicable tool properties are migrated so the print can continue. - * Tools must be closely matching and other restrictions may apply. - * Useful to: - * - Change filament color without interruption - * - Switch spools automatically on filament runout - * - Switch to a different nozzle on an extruder jam - */ - #define TOOLCHANGE_MIGRATION_FEATURE - - #endif - - /** - * Position to park head during tool change. - * Doesn't apply to SWITCHING_TOOLHEAD, DUAL_X_CARRIAGE, or PARKING_EXTRUDER - */ - //#define TOOLCHANGE_PARK - #if ENABLED(TOOLCHANGE_PARK) - #define TOOLCHANGE_PARK_XY { X_MIN_POS + 10, Y_MIN_POS + 10 } - #define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min) - //#define TOOLCHANGE_PARK_X_ONLY // X axis only move - //#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move - #endif -#endif // HAS_MULTI_EXTRUDER - -/** - * Advanced Pause for Filament Change - * - Adds the G-code M600 Filament Change to initiate a filament change. - * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT. - * - * Requirements: - * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE. - * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER. - * - * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park. - */ -#define ADVANCED_PAUSE_FEATURE -#if ENABLED(ADVANCED_PAUSE_FEATURE) - #define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate. - #define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract. - // This short retract is done immediately, before parking the nozzle. - #define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast. - #define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. - #define FILAMENT_CHANGE_UNLOAD_LENGTH 80 // (mm) The length of filament for a complete unload. - // For Bowden, the full length of the tube and nozzle. - // For direct drive, the full length of the nozzle. - // Set to 0 for manual unloading. - #define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load. - #define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 80 // (mm) Slow length, to allow time to insert material. - // 0 to disable start loading and skip to fast load only - #define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 6 // (mm/s) Load filament feedrate. This can be pretty fast. - #define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate. - #define FILAMENT_CHANGE_FAST_LOAD_LENGTH 0 // (mm) Load length of filament, from extruder gear to nozzle. - // For Bowden, the full length of the tube and nozzle. - // For direct drive, the full length of the nozzle. - //#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted. - #define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate. - #define ADVANCED_PAUSE_PURGE_LENGTH 50 // (mm) Length to extrude after loading. - // Set to 0 for manual extrusion. - // Filament can be extruded repeatedly from the Filament Change menu - // until extrusion is consistent, and to purge old filament. - #define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park. - //#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused. - - // Filament Unload does a Retract, Delay, and Purge first: - #define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length. - #define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract. - #define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged. - #define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload - - #define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety. - #define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed. - #define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change. - //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again. - //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing. - - #define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change. - //#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change - - #define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu. - //#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302) -#endif - -// @section tmc - -/** - * TMC26X Stepper Driver options - * - * The TMC26XStepper library is required for this stepper driver. - * https://github.com/trinamic/TMC26XStepper - */ -#if HAS_DRIVER(TMC26X) - - #if AXIS_DRIVER_TYPE_X(TMC26X) - #define X_MAX_CURRENT 1000 // (mA) - #define X_SENSE_RESISTOR 91 // (mOhms) - #define X_MICROSTEPS 16 // Number of microsteps - #endif - - #if AXIS_DRIVER_TYPE_X2(TMC26X) - #define X2_MAX_CURRENT 1000 - #define X2_SENSE_RESISTOR 91 - #define X2_MICROSTEPS X_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Y(TMC26X) - #define Y_MAX_CURRENT 1000 - #define Y_SENSE_RESISTOR 91 - #define Y_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_Y2(TMC26X) - #define Y2_MAX_CURRENT 1000 - #define Y2_SENSE_RESISTOR 91 - #define Y2_MICROSTEPS Y_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z(TMC26X) - #define Z_MAX_CURRENT 1000 - #define Z_SENSE_RESISTOR 91 - #define Z_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_Z2(TMC26X) - #define Z2_MAX_CURRENT 1000 - #define Z2_SENSE_RESISTOR 91 - #define Z2_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z3(TMC26X) - #define Z3_MAX_CURRENT 1000 - #define Z3_SENSE_RESISTOR 91 - #define Z3_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_Z4(TMC26X) - #define Z4_MAX_CURRENT 1000 - #define Z4_SENSE_RESISTOR 91 - #define Z4_MICROSTEPS Z_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_I(TMC26X) - #define I_MAX_CURRENT 1000 - #define I_SENSE_RESISTOR 91 - #define I_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_J(TMC26X) - #define J_MAX_CURRENT 1000 - #define J_SENSE_RESISTOR 91 - #define J_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_K(TMC26X) - #define K_MAX_CURRENT 1000 - #define K_SENSE_RESISTOR 91 - #define K_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_E0(TMC26X) - #define E0_MAX_CURRENT 1000 - #define E0_SENSE_RESISTOR 91 - #define E0_MICROSTEPS 16 - #endif - - #if AXIS_DRIVER_TYPE_E1(TMC26X) - #define E1_MAX_CURRENT 1000 - #define E1_SENSE_RESISTOR 91 - #define E1_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E2(TMC26X) - #define E2_MAX_CURRENT 1000 - #define E2_SENSE_RESISTOR 91 - #define E2_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E3(TMC26X) - #define E3_MAX_CURRENT 1000 - #define E3_SENSE_RESISTOR 91 - #define E3_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E4(TMC26X) - #define E4_MAX_CURRENT 1000 - #define E4_SENSE_RESISTOR 91 - #define E4_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E5(TMC26X) - #define E5_MAX_CURRENT 1000 - #define E5_SENSE_RESISTOR 91 - #define E5_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E6(TMC26X) - #define E6_MAX_CURRENT 1000 - #define E6_SENSE_RESISTOR 91 - #define E6_MICROSTEPS E0_MICROSTEPS - #endif - - #if AXIS_DRIVER_TYPE_E7(TMC26X) - #define E7_MAX_CURRENT 1000 - #define E7_SENSE_RESISTOR 91 - #define E7_MICROSTEPS E0_MICROSTEPS - #endif - -#endif // TMC26X - -// @section tmc_smart - -/** - * To use TMC2130, TMC2160, TMC2660, TMC5130, TMC5160 stepper drivers in SPI mode - * connect your SPI 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.). - * You may also use software SPI if you wish to use general purpose IO pins. - * - * To use TMC2208 stepper UART-configurable stepper drivers connect #_SERIAL_TX_PIN - * to the driver side PDN_UART pin with a 1K resistor. - * To use the reading capabilities, also connect #_SERIAL_RX_PIN to PDN_UART without - * a resistor. - * The drivers can also be used with hardware serial. - * - * TMCStepper library is required to use TMC stepper drivers. - * https://github.com/teemuatlut/TMCStepper - */ -#if HAS_TRINAMIC_CONFIG - - #define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current - - /** - * Interpolate microsteps to 256 - * Override for each driver with _INTERPOLATE settings below - */ - #define INTERPOLATE true - - #if AXIS_IS_TMC(X) - #define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current. - #define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing - #define X_MICROSTEPS 16 // 0..256 - #define X_RSENSE 0.11 - #define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ... - //#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis - //#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis - #endif - - #if AXIS_IS_TMC(X2) - #define X2_CURRENT 800 - #define X2_CURRENT_HOME X2_CURRENT - #define X2_MICROSTEPS X_MICROSTEPS - #define X2_RSENSE 0.11 - #define X2_CHAIN_POS -1 - //#define X2_INTERPOLATE true - //#define X2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Y) - #define Y_CURRENT 800 - #define Y_CURRENT_HOME Y_CURRENT - #define Y_MICROSTEPS 16 - #define Y_RSENSE 0.11 - #define Y_CHAIN_POS -1 - //#define Y_INTERPOLATE true - //#define Y_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Y2) - #define Y2_CURRENT 800 - #define Y2_CURRENT_HOME Y2_CURRENT - #define Y2_MICROSTEPS Y_MICROSTEPS - #define Y2_RSENSE 0.11 - #define Y2_CHAIN_POS -1 - //#define Y2_INTERPOLATE true - //#define Y2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z) - #define Z_CURRENT 800 - #define Z_CURRENT_HOME Z_CURRENT - #define Z_MICROSTEPS 16 - #define Z_RSENSE 0.11 - #define Z_CHAIN_POS -1 - //#define Z_INTERPOLATE true - //#define Z_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z2) - #define Z2_CURRENT 800 - #define Z2_CURRENT_HOME Z2_CURRENT - #define Z2_MICROSTEPS Z_MICROSTEPS - #define Z2_RSENSE 0.11 - #define Z2_CHAIN_POS -1 - //#define Z2_INTERPOLATE true - //#define Z2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z3) - #define Z3_CURRENT 800 - #define Z3_CURRENT_HOME Z3_CURRENT - #define Z3_MICROSTEPS Z_MICROSTEPS - #define Z3_RSENSE 0.11 - #define Z3_CHAIN_POS -1 - //#define Z3_INTERPOLATE true - //#define Z3_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(Z4) - #define Z4_CURRENT 800 - #define Z4_CURRENT_HOME Z4_CURRENT - #define Z4_MICROSTEPS Z_MICROSTEPS - #define Z4_RSENSE 0.11 - #define Z4_CHAIN_POS -1 - //#define Z4_INTERPOLATE true - //#define Z4_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(I) - #define I_CURRENT 800 - #define I_CURRENT_HOME I_CURRENT - #define I_MICROSTEPS 16 - #define I_RSENSE 0.11 - #define I_CHAIN_POS -1 - //#define I_INTERPOLATE true - //#define I_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(J) - #define J_CURRENT 800 - #define J_CURRENT_HOME J_CURRENT - #define J_MICROSTEPS 16 - #define J_RSENSE 0.11 - #define J_CHAIN_POS -1 - //#define J_INTERPOLATE true - //#define J_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(K) - #define K_CURRENT 800 - #define K_CURRENT_HOME K_CURRENT - #define K_MICROSTEPS 16 - #define K_RSENSE 0.11 - #define K_CHAIN_POS -1 - //#define K_INTERPOLATE true - //#define K_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E0) - #define E0_CURRENT 800 - #define E0_MICROSTEPS 16 - #define E0_RSENSE 0.11 - #define E0_CHAIN_POS -1 - //#define E0_INTERPOLATE true - //#define E0_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E1) - #define E1_CURRENT 800 - #define E1_MICROSTEPS E0_MICROSTEPS - #define E1_RSENSE 0.11 - #define E1_CHAIN_POS -1 - //#define E1_INTERPOLATE true - //#define E1_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E2) - #define E2_CURRENT 800 - #define E2_MICROSTEPS E0_MICROSTEPS - #define E2_RSENSE 0.11 - #define E2_CHAIN_POS -1 - //#define E2_INTERPOLATE true - //#define E2_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E3) - #define E3_CURRENT 800 - #define E3_MICROSTEPS E0_MICROSTEPS - #define E3_RSENSE 0.11 - #define E3_CHAIN_POS -1 - //#define E3_INTERPOLATE true - //#define E3_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E4) - #define E4_CURRENT 800 - #define E4_MICROSTEPS E0_MICROSTEPS - #define E4_RSENSE 0.11 - #define E4_CHAIN_POS -1 - //#define E4_INTERPOLATE true - //#define E4_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E5) - #define E5_CURRENT 800 - #define E5_MICROSTEPS E0_MICROSTEPS - #define E5_RSENSE 0.11 - #define E5_CHAIN_POS -1 - //#define E5_INTERPOLATE true - //#define E5_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E6) - #define E6_CURRENT 800 - #define E6_MICROSTEPS E0_MICROSTEPS - #define E6_RSENSE 0.11 - #define E6_CHAIN_POS -1 - //#define E6_INTERPOLATE true - //#define E6_HOLD_MULTIPLIER 0.5 - #endif - - #if AXIS_IS_TMC(E7) - #define E7_CURRENT 800 - #define E7_MICROSTEPS E0_MICROSTEPS - #define E7_RSENSE 0.11 - #define E7_CHAIN_POS -1 - //#define E7_INTERPOLATE true - //#define E7_HOLD_MULTIPLIER 0.5 - #endif - - /** - * Override default SPI pins for TMC2130, TMC2160, TMC2660, TMC5130 and TMC5160 drivers here. - * The default pins can be found in your board's pins file. - */ - //#define X_CS_PIN -1 - //#define Y_CS_PIN -1 - //#define Z_CS_PIN -1 - //#define X2_CS_PIN -1 - //#define Y2_CS_PIN -1 - //#define Z2_CS_PIN -1 - //#define Z3_CS_PIN -1 - //#define Z4_CS_PIN -1 - //#define I_CS_PIN -1 - //#define J_CS_PIN -1 - //#define K_CS_PIN -1 - //#define E0_CS_PIN -1 - //#define E1_CS_PIN -1 - //#define E2_CS_PIN -1 - //#define E3_CS_PIN -1 - //#define E4_CS_PIN -1 - //#define E5_CS_PIN -1 - //#define E6_CS_PIN -1 - //#define E7_CS_PIN -1 - - /** - * Software option for SPI driven drivers (TMC2130, TMC2160, TMC2660, TMC5130 and TMC5160). - * The default SW SPI pins are defined the respective pins files, - * but you can override or define them here. - */ - //#define TMC_USE_SW_SPI - //#define TMC_SW_MOSI -1 - //#define TMC_SW_MISO -1 - //#define TMC_SW_SCK -1 - - /** - * Four TMC2209 drivers can use the same HW/SW serial port with hardware configured addresses. - * Set the address using jumpers on pins MS1 and MS2. - * Address | MS1 | MS2 - * 0 | LOW | LOW - * 1 | HIGH | LOW - * 2 | LOW | HIGH - * 3 | HIGH | HIGH - * - * Set *_SERIAL_TX_PIN and *_SERIAL_RX_PIN to match for all drivers - * on the same serial port, either here or in your board's pins file. - */ - //#define X_SLAVE_ADDRESS 0 - //#define Y_SLAVE_ADDRESS 0 - //#define Z_SLAVE_ADDRESS 0 - //#define X2_SLAVE_ADDRESS 0 - //#define Y2_SLAVE_ADDRESS 0 - //#define Z2_SLAVE_ADDRESS 0 - //#define Z3_SLAVE_ADDRESS 0 - //#define Z4_SLAVE_ADDRESS 0 - //#define I_SLAVE_ADDRESS 0 - //#define J_SLAVE_ADDRESS 0 - //#define K_SLAVE_ADDRESS 0 - //#define E0_SLAVE_ADDRESS 0 - //#define E1_SLAVE_ADDRESS 0 - //#define E2_SLAVE_ADDRESS 0 - //#define E3_SLAVE_ADDRESS 0 - //#define E4_SLAVE_ADDRESS 0 - //#define E5_SLAVE_ADDRESS 0 - //#define E6_SLAVE_ADDRESS 0 - //#define E7_SLAVE_ADDRESS 0 - - /** - * Software enable - * - * Use for drivers that do not use a dedicated enable pin, but rather handle the same - * function through a communication line such as SPI or UART. - */ - //#define SOFTWARE_DRIVER_ENABLE - - /** - * TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only - * Use Trinamic's ultra quiet stepping mode. - * When disabled, Marlin will use spreadCycle stepping mode. - */ - #define STEALTHCHOP_XY - #define STEALTHCHOP_Z - #define STEALTHCHOP_I - #define STEALTHCHOP_J - #define STEALTHCHOP_K - #define STEALTHCHOP_E - - /** - * Optimize spreadCycle chopper parameters by using predefined parameter sets - * or with the help of an example included in the library. - * Provided parameter sets are - * CHOPPER_DEFAULT_12V - * CHOPPER_DEFAULT_19V - * CHOPPER_DEFAULT_24V - * CHOPPER_DEFAULT_36V - * CHOPPER_09STEP_24V // 0.9 degree steppers (24V) - * CHOPPER_PRUSAMK3_24V // Imported parameters from the official Průša firmware for MK3 (24V) - * CHOPPER_MARLIN_119 // Old defaults from Marlin v1.1.9 - * - * Define your own with: - * { , , hysteresis_start[1..8] } - */ - #define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below) - //#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below) - //#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X - //#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below) - //#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y - //#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below) - //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z - //#define CHOPPER_TIMING_I CHOPPER_TIMING - //#define CHOPPER_TIMING_J CHOPPER_TIMING - //#define CHOPPER_TIMING_K CHOPPER_TIMING - //#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below) - //#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E - //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E - - /** - * Monitor Trinamic drivers - * for error conditions like overtemperature and short to ground. - * To manage over-temp Marlin can decrease the driver current until the error condition clears. - * Other detected conditions can be used to stop the current print. - * Relevant G-codes: - * M906 - Set or get motor current in milliamps using axis codes X, Y, Z, E. Report values if no axis codes given. - * M911 - Report stepper driver overtemperature pre-warn condition. - * M912 - Clear stepper driver overtemperature pre-warn condition flag. - * M122 - Report driver parameters (Requires TMC_DEBUG) - */ - //#define MONITOR_DRIVER_STATUS - - #if ENABLED(MONITOR_DRIVER_STATUS) - #define CURRENT_STEP_DOWN 50 // [mA] - #define REPORT_CURRENT_CHANGE - #define STOP_ON_ERROR - #endif - - /** - * TMC2130, TMC2160, TMC2208, TMC2209, TMC5130 and TMC5160 only - * 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_(XY|Z|E) must be enabled to use HYBRID_THRESHOLD. - * 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 3 - #define Z2_HYBRID_THRESHOLD 3 - #define Z3_HYBRID_THRESHOLD 3 - #define Z4_HYBRID_THRESHOLD 3 - #define I_HYBRID_THRESHOLD 3 - #define J_HYBRID_THRESHOLD 3 - #define K_HYBRID_THRESHOLD 3 - #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 - #define E5_HYBRID_THRESHOLD 30 - #define E6_HYBRID_THRESHOLD 30 - #define E7_HYBRID_THRESHOLD 30 - - /** - * Use StallGuard to home / probe X, Y, Z. - * - * TMC2130, TMC2160, TMC2209, TMC2660, TMC5130, and TMC5160 only - * Connect the stepper driver's DIAG1 pin to the X/Y endstop pin. - * X, Y, and Z homing will always be done in spreadCycle mode. - * - * X/Y/Z_STALL_SENSITIVITY is the default stall threshold. - * Use M914 X Y Z to set the stall threshold at runtime: - * - * Sensitivity TMC2209 Others - * HIGHEST 255 -64 (Too sensitive => False positive) - * LOWEST 0 63 (Too insensitive => No trigger) - * - * It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }. - * - * SPI_ENDSTOPS *** Beta feature! *** TMC2130/TMC5160 Only *** - * Poll the driver through SPI to determine load when homing. - * Removes the need for a wire from DIAG1 to an endstop pin. - * - * IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when - * homing and adds a guard period for endstop triggering. - * - * Comment *_STALL_SENSITIVITY to disable sensorless homing for that axis. - */ - //#define SENSORLESS_HOMING // StallGuard capable drivers only - - #if EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING) - // TMC2209: 0...255. TMC2130: -64...63 - #define X_STALL_SENSITIVITY 8 - #define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY - #define Y_STALL_SENSITIVITY 8 - #define Y2_STALL_SENSITIVITY Y_STALL_SENSITIVITY - //#define Z_STALL_SENSITIVITY 8 - //#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY - //#define I_STALL_SENSITIVITY 8 - //#define J_STALL_SENSITIVITY 8 - //#define K_STALL_SENSITIVITY 8 - //#define SPI_ENDSTOPS // TMC2130 only - //#define IMPROVE_HOMING_RELIABILITY - #endif - - /** - * TMC Homing stepper phase. - * - * Improve homing repeatability by homing to stepper coil's nearest absolute - * phase position. Trinamic drivers use a stepper phase table with 1024 values - * spanning 4 full steps with 256 positions each (ergo, 1024 positions). - * Full step positions (128, 384, 640, 896) have the highest holding torque. - * - * Values from 0..1023, -1 to disable homing phase for that axis. - */ - //#define TMC_HOME_PHASE { 896, 896, 896 } - - /** - * Beta feature! - * Create a 50/50 square wave step pulse optimal for stepper drivers. - */ - //#define SQUARE_WAVE_STEPPING - - /** - * Enable M122 debugging command for TMC stepper drivers. - * M122 S0/1 will enable continuous reporting. - */ - //#define TMC_DEBUG - - /** - * 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/TMCStepper - * - * Example: - * #define TMC_ADV() { \ - * stepperX.diag0_otpw(1); \ - * stepperY.intpol(0); \ - * } - */ - #define TMC_ADV() { } - -#endif // HAS_TRINAMIC_CONFIG - -// @section L64XX - -/** - * L64XX Stepper Driver options - * - * Arduino-L6470 library (0.8.0 or higher) is required. - * https://github.com/ameyer/Arduino-L6470 - * - * Requires the following to be defined in your pins_YOUR_BOARD file - * L6470_CHAIN_SCK_PIN - * L6470_CHAIN_MISO_PIN - * L6470_CHAIN_MOSI_PIN - * L6470_CHAIN_SS_PIN - * ENABLE_RESET_L64XX_CHIPS(Q) where Q is 1 to enable and 0 to reset - */ - -#if HAS_L64XX - - //#define L6470_CHITCHAT // Display additional status info - - #if AXIS_IS_L64XX(X) - #define X_MICROSTEPS 128 // Number of microsteps (VALID: 1, 2, 4, 8, 16, 32, 128) - L6474 max is 16 - #define X_OVERCURRENT 2000 // (mA) Current where the driver detects an over current - // L6470 & L6474 - VALID: 375 x (1 - 16) - 6A max - rounds down - // POWERSTEP01: VALID: 1000 x (1 - 32) - 32A max - rounds down - #define X_STALLCURRENT 1500 // (mA) Current where the driver detects a stall (VALID: 31.25 * (1-128) - 4A max - rounds down) - // L6470 & L6474 - VALID: 31.25 * (1-128) - 4A max - rounds down - // POWERSTEP01: VALID: 200 x (1 - 32) - 6.4A max - rounds down - // L6474 - STALLCURRENT setting is used to set the nominal (TVAL) current - #define X_MAX_VOLTAGE 127 // 0-255, Maximum effective voltage seen by stepper - not used by L6474 - #define X_CHAIN_POS -1 // Position in SPI chain, 0=Not in chain, 1=Nearest MOSI - #define X_SLEW_RATE 1 // 0-3, Slew 0 is slowest, 3 is fastest - #endif - - #if AXIS_IS_L64XX(X2) - #define X2_MICROSTEPS X_MICROSTEPS - #define X2_OVERCURRENT 2000 - #define X2_STALLCURRENT 1500 - #define X2_MAX_VOLTAGE 127 - #define X2_CHAIN_POS -1 - #define X2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Y) - #define Y_MICROSTEPS 128 - #define Y_OVERCURRENT 2000 - #define Y_STALLCURRENT 1500 - #define Y_MAX_VOLTAGE 127 - #define Y_CHAIN_POS -1 - #define Y_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Y2) - #define Y2_MICROSTEPS Y_MICROSTEPS - #define Y2_OVERCURRENT 2000 - #define Y2_STALLCURRENT 1500 - #define Y2_MAX_VOLTAGE 127 - #define Y2_CHAIN_POS -1 - #define Y2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z) - #define Z_MICROSTEPS 128 - #define Z_OVERCURRENT 2000 - #define Z_STALLCURRENT 1500 - #define Z_MAX_VOLTAGE 127 - #define Z_CHAIN_POS -1 - #define Z_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z2) - #define Z2_MICROSTEPS Z_MICROSTEPS - #define Z2_OVERCURRENT 2000 - #define Z2_STALLCURRENT 1500 - #define Z2_MAX_VOLTAGE 127 - #define Z2_CHAIN_POS -1 - #define Z2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z3) - #define Z3_MICROSTEPS Z_MICROSTEPS - #define Z3_OVERCURRENT 2000 - #define Z3_STALLCURRENT 1500 - #define Z3_MAX_VOLTAGE 127 - #define Z3_CHAIN_POS -1 - #define Z3_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(Z4) - #define Z4_MICROSTEPS Z_MICROSTEPS - #define Z4_OVERCURRENT 2000 - #define Z4_STALLCURRENT 1500 - #define Z4_MAX_VOLTAGE 127 - #define Z4_CHAIN_POS -1 - #define Z4_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(I) - #define I_MICROSTEPS 128 - #define I_OVERCURRENT 2000 - #define I_STALLCURRENT 1500 - #define I_MAX_VOLTAGE 127 - #define I_CHAIN_POS -1 - #define I_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(J) - #define J_MICROSTEPS 128 - #define J_OVERCURRENT 2000 - #define J_STALLCURRENT 1500 - #define J_MAX_VOLTAGE 127 - #define J_CHAIN_POS -1 - #define J_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(K) - #define K_MICROSTEPS 128 - #define K_OVERCURRENT 2000 - #define K_STALLCURRENT 1500 - #define K_MAX_VOLTAGE 127 - #define K_CHAIN_POS -1 - #define K_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E0) - #define E0_MICROSTEPS 128 - #define E0_OVERCURRENT 2000 - #define E0_STALLCURRENT 1500 - #define E0_MAX_VOLTAGE 127 - #define E0_CHAIN_POS -1 - #define E0_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E1) - #define E1_MICROSTEPS E0_MICROSTEPS - #define E1_OVERCURRENT 2000 - #define E1_STALLCURRENT 1500 - #define E1_MAX_VOLTAGE 127 - #define E1_CHAIN_POS -1 - #define E1_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E2) - #define E2_MICROSTEPS E0_MICROSTEPS - #define E2_OVERCURRENT 2000 - #define E2_STALLCURRENT 1500 - #define E2_MAX_VOLTAGE 127 - #define E2_CHAIN_POS -1 - #define E2_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E3) - #define E3_MICROSTEPS E0_MICROSTEPS - #define E3_OVERCURRENT 2000 - #define E3_STALLCURRENT 1500 - #define E3_MAX_VOLTAGE 127 - #define E3_CHAIN_POS -1 - #define E3_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E4) - #define E4_MICROSTEPS E0_MICROSTEPS - #define E4_OVERCURRENT 2000 - #define E4_STALLCURRENT 1500 - #define E4_MAX_VOLTAGE 127 - #define E4_CHAIN_POS -1 - #define E4_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E5) - #define E5_MICROSTEPS E0_MICROSTEPS - #define E5_OVERCURRENT 2000 - #define E5_STALLCURRENT 1500 - #define E5_MAX_VOLTAGE 127 - #define E5_CHAIN_POS -1 - #define E5_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E6) - #define E6_MICROSTEPS E0_MICROSTEPS - #define E6_OVERCURRENT 2000 - #define E6_STALLCURRENT 1500 - #define E6_MAX_VOLTAGE 127 - #define E6_CHAIN_POS -1 - #define E6_SLEW_RATE 1 - #endif - - #if AXIS_IS_L64XX(E7) - #define E7_MICROSTEPS E0_MICROSTEPS - #define E7_OVERCURRENT 2000 - #define E7_STALLCURRENT 1500 - #define E7_MAX_VOLTAGE 127 - #define E7_CHAIN_POS -1 - #define E7_SLEW_RATE 1 - #endif - - /** - * Monitor L6470 drivers for error conditions like over temperature and over current. - * In the case of over temperature Marlin can decrease the drive until the error condition clears. - * Other detected conditions can be used to stop the current print. - * Relevant G-codes: - * M906 - I1/2/3/4/5 Set or get motor drive level using axis codes X, Y, Z, E. Report values if no axis codes given. - * I not present or I0 or I1 - X, Y, Z or E0 - * I2 - X2, Y2, Z2 or E1 - * I3 - Z3 or E3 - * I4 - Z4 or E4 - * I5 - E5 - * M916 - Increase drive level until get thermal warning - * M917 - Find minimum current thresholds - * M918 - Increase speed until max or error - * M122 S0/1 - Report driver parameters - */ - //#define MONITOR_L6470_DRIVER_STATUS - - #if ENABLED(MONITOR_L6470_DRIVER_STATUS) - #define KVAL_HOLD_STEP_DOWN 1 - //#define L6470_STOP_ON_ERROR - #endif - -#endif // HAS_L64XX - -// @section i2cbus - -// -// I2C Master ID for LPC176x LCD and Digital Current control -// Does not apply to other peripherals based on the Wire library. -// -//#define I2C_MASTER_ID 1 // Set a value from 0 to 2 - -/** - * 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 - */ - -//#define EXPERIMENTAL_I2CBUS -#if ENABLED(EXPERIMENTAL_I2CBUS) - #define I2C_SLAVE_ADDRESS 0 // Set a value from 8 to 127 to act as a slave -#endif - -// @section extras - -/** - * Photo G-code - * Add the M240 G-code to take a photo. - * The photo can be triggered by a digital pin or a physical movement. - */ -//#define PHOTO_GCODE -#if ENABLED(PHOTO_GCODE) - // A position to move to (and raise Z) before taking the photo - //#define PHOTO_POSITION { X_MAX_POS - 5, Y_MAX_POS, 0 } // { xpos, ypos, zraise } (M240 X Y Z) - //#define PHOTO_DELAY_MS 100 // (ms) Duration to pause before moving back (M240 P) - //#define PHOTO_RETRACT_MM 6.5 // (mm) E retract/recover for the photo move (M240 R S) - - // Canon RC-1 or homebrew digital camera trigger - // Data from: https://www.doc-diy.net/photo/rc-1_hacked/ - //#define PHOTOGRAPH_PIN 23 - - // Canon Hack Development Kit - // https://captain-slow.dk/2014/03/09/3d-printing-timelapses/ - //#define CHDK_PIN 4 - - // Optional second move with delay to trigger the camera shutter - //#define PHOTO_SWITCH_POSITION { X_MAX_POS, Y_MAX_POS } // { xpos, ypos } (M240 I J) - - // Duration to hold the switch or keep CHDK_PIN high - //#define PHOTO_SWITCH_MS 50 // (ms) (M240 D) - - /** - * PHOTO_PULSES_US may need adjustment depending on board and camera model. - * Pin must be running at 48.4kHz. - * Be sure to use a PHOTOGRAPH_PIN which can rise and fall quick enough. - * (e.g., MKS SBase temp sensor pin was too slow, so used P1.23 on J8.) - * - * Example pulse data for Nikon: https://bit.ly/2FKD0Aq - * IR Wiring: https://git.io/JvJf7 - */ - //#define PHOTO_PULSES_US { 2000, 27850, 400, 1580, 400, 3580, 400 } // (µs) Durations for each 48.4kHz oscillation - #ifdef PHOTO_PULSES_US - #define PHOTO_PULSE_DELAY_US 13 // (µs) Approximate duration of each HIGH and LOW pulse in the oscillation - #endif -#endif - -/** - * 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 https://marlinfw.org/docs/configuration/2.0.9/laser_spindle.html for more config details. - */ -//#define SPINDLE_FEATURE -//#define LASER_FEATURE -#if EITHER(SPINDLE_FEATURE, LASER_FEATURE) - #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH - - #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower - #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC) - // ESP32: If SPINDLE_LASER_PWM_PIN is onboard then <=78125Hz. For I2S expander - // the frequency determines the PWM resolution. 2500Hz = 0-100, 977Hz = 0-255, ... - // (250000 / SPINDLE_LASER_FREQUENCY) = max value. - #endif - - //#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11 - #if ENABLED(AIR_EVACUATION) - #define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH - //#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin - #endif - - //#define AIR_ASSIST // Air Assist control with G-codes M8-M9 - #if ENABLED(AIR_ASSIST) - #define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin - //#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin - #endif - - //#define SPINDLE_SERVO // A servo converting an angle to spindle power - #ifdef SPINDLE_SERVO - #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control - #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle - #endif - - /** - * Speed / Power can be set ('M3 S') and displayed in terms of: - * - PWM255 (S0 - S255) - * - PERCENT (S0 - S100) - * - RPM (S0 - S50000) Best for use with a spindle - * - SERVO (S0 - S180) - */ - #define CUTTER_POWER_UNIT PWM255 - - /** - * Relative Cutter Power - * Normally, 'M3 O' sets - * OCR power is relative to the range SPEED_POWER_MIN...SPEED_POWER_MAX. - * so input powers of 0...255 correspond to SPEED_POWER_MIN...SPEED_POWER_MAX - * instead of normal range (0 to SPEED_POWER_MAX). - * Best used with (e.g.) SuperPID router controller: S0 = 5,000 RPM and S255 = 30,000 RPM - */ - //#define CUTTER_POWER_RELATIVE // Set speed proportional to [SPEED_POWER_MIN...SPEED_POWER_MAX] - - #if ENABLED(SPINDLE_FEATURE) - //#define SPINDLE_CHANGE_DIR // Enable if your spindle controller can change spindle direction - #define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction - #define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed - - #define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power - #define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop - - /** - * M3/M4 Power Equation - * - * Each tool uses different value ranges for speed / power control. - * These parameters are used to convert between tool power units and PWM. - * - * Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE - * PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE - */ - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage - #define SPEED_POWER_MIN 5000 // (RPM) - #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM - #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments) - #endif - - #else - - #if ENABLED(SPINDLE_LASER_USE_PWM) - #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage - #define SPEED_POWER_MIN 0 // (%) 0-100 - #define SPEED_POWER_MAX 100 // (%) 0-100 - #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments) - #endif - - // Define the minimum and maximum test pulse time values for a laser test fire function - #define LASER_TEST_PULSE_MIN 1 // (ms) Used with Laser Control Menu - #define LASER_TEST_PULSE_MAX 999 // (ms) Caution: Menu may not show more than 3 characters - - #define SPINDLE_LASER_POWERUP_DELAY 50 // (ms) Delay to allow the spindle/laser to come up to speed/power - #define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop - - /** - * Laser Safety Timeout - * - * The laser should be turned off when there is no movement for a period of time. - * Consider material flammability, cut rate, and G-code order when setting this - * value. Too low and it could turn off during a very slow move; too high and - * the material could ignite. - */ - #define LASER_SAFETY_TIMEOUT_MS 1000 // (ms) - - /** - * Any M3 or G1/2/3/5 command with the 'I' parameter enables continuous inline power mode. - * - * e.g., 'M3 I' enables continuous inline power which is processed by the planner. - * Power is stored in move blocks and applied when blocks are processed by the Stepper ISR. - * - * 'M4 I' sets dynamic mode which uses the current feedrate to calculate a laser power OCR value. - * - * Any move in dynamic mode will use the current feedrate to calculate the laser power. - * Feed rates are set by the F parameter of a move command e.g. G1 X0 Y10 F6000 - * Laser power would be calculated by bit shifting off 8 LSB's. In binary this is div 256. - * The calculation gives us ocr values from 0 to 255, values over F65535 will be set as 255 . - * More refined power control such as compesation for accell/decell will be addressed in future releases. - * - * M5 I clears inline mode and set power to 0, M5 sets the power output to 0 but leaves inline mode on. - */ - - /** - * Enable M3 commands for laser mode inline power planner syncing. - * This feature enables any M3 S-value to be injected into the block buffers while in - * CUTTER_MODE_CONTINUOUS. The option allows M3 laser power to be commited without waiting - * for a planner syncronization - */ - //#define LASER_POWER_SYNC - - /** - * Scale the laser's power in proportion to the movement rate. - * - * - Sets the entry power proportional to the entry speed over the nominal speed. - * - Ramps the power up every N steps to approximate the speed trapezoid. - * - Due to the limited power resolution this is only approximate. - */ - //#define LASER_POWER_TRAP - - // - // Laser I2C Ammeter (High precision INA226 low/high side module) - // - //#define I2C_AMMETER - #if ENABLED(I2C_AMMETER) - #define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range - #define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value - #endif - - // - // Laser Coolant Flow Meter - // - //#define LASER_COOLANT_FLOW_METER - #if ENABLED(LASER_COOLANT_FLOW_METER) - #define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21) - #define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin - #define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds - #define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below - #if ENABLED(FLOWMETER_SAFETY) - #define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled - #endif - #endif - - #endif -#endif // SPINDLE_FEATURE || LASER_FEATURE - -/** - * Synchronous Laser Control with M106/M107 - * - * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing - * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan - * header (as with some add-on laser kits). Enable this option to set fan/laser - * speeds with much more exact timing for improved print fidelity. - * - * NOTE: This option sacrifices some cooling fan speed options. - */ -//#define LASER_SYNCHRONOUS_M106_M107 - -/** - * Coolant Control - * - * Add the M7, M8, and M9 commands to turn mist or flood coolant on and off. - * - * Note: COOLANT_MIST_PIN and/or COOLANT_FLOOD_PIN must also be defined. - */ -//#define COOLANT_CONTROL -#if ENABLED(COOLANT_CONTROL) - #define COOLANT_MIST // Enable if mist coolant is present - #define COOLANT_FLOOD // Enable if flood coolant is present - #define COOLANT_MIST_INVERT false // Set "true" if the on/off function is reversed - #define COOLANT_FLOOD_INVERT false // Set "true" if the on/off function is reversed -#endif - -/** - * 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 - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - #define FILAMENT_SENSOR_EXTRUDER_NUM 0 // Index of the extruder that has the filament sensor. :[0,1,2,3,4] - #define MEASUREMENT_DELAY_CM 14 // (cm) The distance from the filament sensor to the melting chamber - - #define FILWIDTH_ERROR_MARGIN 1.0 // (mm) If a measurement differs too much from nominal width ignore it - #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 - -/** - * Power Monitor - * Monitor voltage (V) and/or current (A), and -when possible- power (W) - * - * Read and configure with M430 - * - * The current sensor feeds DC voltage (relative to the measured current) to an analog pin - * The voltage sensor feeds DC voltage (relative to the measured voltage) to an analog pin - */ -//#define POWER_MONITOR_CURRENT // Monitor the system current -//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage - -#if ENABLED(POWER_MONITOR_CURRENT) - #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF! - #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current - #define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display) -#endif - -#if ENABLED(POWER_MONITOR_VOLTAGE) - #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF! - #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage -#endif - -/** - * Stepper Driver Anti-SNAFU Protection - * - * If the SAFE_POWER_PIN is defined for your board, Marlin will check - * that stepper drivers are properly plugged in before applying power. - * Disable protection if your stepper drivers don't support the feature. - */ -//#define DISABLE_DRIVER_SAFE_POWER_PROTECT - -/** - * CNC Coordinate Systems - * - * Enables G53 and G54-G59.3 commands to select coordinate systems - * and G92.1 to reset the workspace to native machine space. - */ -//#define CNC_COORDINATE_SYSTEMS - -/** - * Auto-report fan speed with M123 S - * Requires fans with tachometer pins - */ -//#define AUTO_REPORT_FANS - -/** - * Auto-report temperatures with M155 S - */ -#define AUTO_REPORT_TEMPERATURES -#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT - //#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report -#endif - -/** - * Auto-report position with M154 S - */ -//#define AUTO_REPORT_POSITION - -/** - * Include capabilities in M115 output - */ -#define EXTENDED_CAPABILITIES_REPORT -#if ENABLED(EXTENDED_CAPABILITIES_REPORT) - //#define M115_GEOMETRY_REPORT -#endif - -/** - * Expected Printer Check - * Add the M16 G-code to compare a string to the MACHINE_NAME. - * M16 with a non-matching string causes the printer to halt. - */ -//#define EXPECTED_PRINTER_CHECK - -/** - * Disable all Volumetric extrusion options - */ -//#define NO_VOLUMETRICS - -#if DISABLED(NO_VOLUMETRICS) - /** - * 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 (and enable volumetric). - * M200 S0/S1 to disable/enable volumetric extrusion. - */ - //#define VOLUMETRIC_DEFAULT_ON - - //#define VOLUMETRIC_EXTRUDER_LIMIT - #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - /** - * Default volumetric extrusion limit in cubic mm per second (mm^3/sec). - * This factory setting applies to all extruders. - * Use 'M200 [T] L' to override and 'M502' to reset. - * A non-zero value activates Volume-based Extrusion Limiting. - */ - #define DEFAULT_VOLUMETRIC_EXTRUDER_LIMIT 0.00 // (mm^3/sec) - #endif -#endif - -/** - * 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 - -// Extra options for the M114 "Current Position" report -//#define M114_DETAIL // Use 'M114` for details to check planner calculations -//#define M114_REALTIME // Real current position based on forward kinematics -//#define M114_LEGACY // M114 used to synchronize on every call. Enable if needed. - -//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others) - -/** - * Spend 28 bytes of SRAM to optimize the G-code parser - */ -#define FASTER_GCODE_PARSER - -#if ENABLED(FASTER_GCODE_PARSER) - //#define GCODE_QUOTED_STRINGS // Support for quoted string parameters -#endif - -// Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack) -//#define MEATPACK_ON_SERIAL_PORT_1 -//#define MEATPACK_ON_SERIAL_PORT_2 - -//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase - -//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW - -/** - * CNC G-code options - * Support CNC-style G-code dialects used by laser cutters, drawing machine cams, etc. - * Note that G0 feedrates should be used with care for 3D printing (if used at all). - * High feedrates may cause ringing and harm print quality. - */ -//#define PAREN_COMMENTS // Support for parentheses-delimited comments -//#define GCODE_MOTION_MODES // Remember the motion mode (G0 G1 G2 G3 G5 G38.X) and apply for X Y Z E F, etc. - -// Enable and set a (default) feedrate for all G0 moves -//#define G0_FEEDRATE 3000 // (mm/min) -#ifdef G0_FEEDRATE - //#define VARIABLE_G0_FEEDRATE // The G0 feedrate is set by F in G0 motion mode -#endif - -/** - * Startup commands - * - * Execute certain G-code commands immediately after power-on. - */ -//#define STARTUP_COMMANDS "M17 Z" - -/** - * G-code Macros - * - * Add G-codes M810-M819 to define and run G-code macros. - * Macros are not saved to EEPROM. - */ -//#define GCODE_MACROS -#if ENABLED(GCODE_MACROS) - #define GCODE_MACROS_SLOTS 5 // Up to 10 may be used - #define GCODE_MACROS_SLOT_SIZE 50 // Maximum length of a single macro -#endif - -/** - * User-defined menu items to run custom G-code. - * Up to 25 may be defined, but the actual number is LCD-dependent. - */ - -// Custom Menu: Main Menu -//#define CUSTOM_MENU_MAIN -#if ENABLED(CUSTOM_MENU_MAIN) - //#define CUSTOM_MENU_MAIN_TITLE "Custom Commands" - #define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done" - #define CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK - //#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script - #define CUSTOM_MENU_MAIN_ONLY_IDLE // Only show custom menu when the machine is idle - - #define MAIN_MENU_ITEM_1_DESC "Home & UBL Info" - #define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W" - //#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action - - #define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL - #define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) - //#define MAIN_MENU_ITEM_2_CONFIRM - - //#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL - //#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) - //#define MAIN_MENU_ITEM_3_CONFIRM - - //#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level" - //#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29" - //#define MAIN_MENU_ITEM_4_CONFIRM - - //#define MAIN_MENU_ITEM_5_DESC "Home & Info" - //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503" - //#define MAIN_MENU_ITEM_5_CONFIRM -#endif - -// Custom Menu: Configuration Menu -//#define CUSTOM_MENU_CONFIG -#if ENABLED(CUSTOM_MENU_CONFIG) - //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands" - #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done" - #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK - //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script - #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle - - #define CONFIG_MENU_ITEM_1_DESC "Wifi ON" - #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678" - //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action - - #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON" - #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678" - //#define CONFIG_MENU_ITEM_2_CONFIRM - - //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF" - //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678" - //#define CONFIG_MENU_ITEM_3_CONFIRM - - //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????" - //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????" - //#define CONFIG_MENU_ITEM_4_CONFIRM - - //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????" - //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????" - //#define CONFIG_MENU_ITEM_5_CONFIRM -#endif - -/** - * User-defined buttons to run custom G-code. - * Up to 25 may be defined. - */ -//#define CUSTOM_USER_BUTTONS -#if ENABLED(CUSTOM_USER_BUTTONS) - //#define BUTTON1_PIN -1 - #if PIN_EXISTS(BUTTON1) - #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH. - #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing? - #define BUTTON1_GCODE "G28" - #define BUTTON1_DESC "Homing" // Optional string to set the LCD status - #endif - - //#define BUTTON2_PIN -1 - #if PIN_EXISTS(BUTTON2) - #define BUTTON2_HIT_STATE LOW - #define BUTTON2_WHEN_PRINTING false - #define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND) - #define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL - #endif - - //#define BUTTON3_PIN -1 - #if PIN_EXISTS(BUTTON3) - #define BUTTON3_HIT_STATE LOW - #define BUTTON3_WHEN_PRINTING false - #define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND) - #define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL - #endif -#endif - -/** - * Host Action Commands - * - * Define host streamer action commands in compliance with the standard. - * - * See https://reprap.org/wiki/G-code#Action_commands - * Common commands ........ poweroff, pause, paused, resume, resumed, cancel - * G29_RETRY_AND_RECOVER .. probe_rewipe, probe_failed - * - * Some features add reason codes to extend these commands. - * - * Host Prompt Support enables Marlin to use the host for user prompts so - * filament runout and other processes can be managed from the host side. - */ -//#define HOST_ACTION_COMMANDS -#if ENABLED(HOST_ACTION_COMMANDS) - //#define HOST_PAUSE_M76 // Tell the host to pause in response to M76 - //#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback - #if ENABLED(HOST_PROMPT_SUPPORT) - //#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications - #endif - //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start - //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down -#endif - -/** - * Cancel Objects - * - * Implement M486 to allow Marlin to skip objects - */ -//#define CANCEL_OBJECTS -#if ENABLED(CANCEL_OBJECTS) - #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message -#endif - -/** - * I2C position encoders for closed loop control. - * Developed by Chris Barr at Aus3D. - * - * Wiki: https://wiki.aus3d.com.au/Magnetic_Encoder - * Github: https://github.com/Aus3D/MagneticEncoder - * - * Supplier: https://aus3d.com.au/magnetic-encoder-module - * Alternative Supplier: https://reliabuild3d.com/ - * - * Reliabuild 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_MICROSTEP // 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_MICROSTEP - #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 behavior. - - #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 4 // (ms) Minimum time between encoder checks. - - // Use a rolling average to identify persistent errors that indicate skips, as opposed to vibration and noise. - #define I2CPE_ERR_ROLLING_AVERAGE - -#endif // I2C_POSITION_ENCODERS - -/** - * Analog Joystick(s) - */ -//#define JOYSTICK -#if ENABLED(JOYSTICK) - #define JOY_X_PIN 5 // RAMPS: Suggested pin A5 on AUX2 - #define JOY_Y_PIN 10 // RAMPS: Suggested pin A10 on AUX2 - #define JOY_Z_PIN 12 // RAMPS: Suggested pin A12 on AUX2 - #define JOY_EN_PIN 44 // RAMPS: Suggested pin D44 on AUX2 - - //#define INVERT_JOY_X // Enable if X direction is reversed - //#define INVERT_JOY_Y // Enable if Y direction is reversed - //#define INVERT_JOY_Z // Enable if Z direction is reversed - - // Use M119 with JOYSTICK_DEBUG to find reasonable values after connecting: - #define JOY_X_LIMITS { 5600, 8190-100, 8190+100, 10800 } // min, deadzone start, deadzone end, max - #define JOY_Y_LIMITS { 5600, 8250-100, 8250+100, 11000 } - #define JOY_Z_LIMITS { 4800, 8080-100, 8080+100, 11550 } - //#define JOYSTICK_DEBUG -#endif - -/** - * Mechanical Gantry Calibration - * Modern replacement for the Prusa TMC_Z_CALIBRATION. - * Adds capability to work with any adjustable current drivers. - * Implemented as G34 because M915 is deprecated. - */ -//#define MECHANICAL_GANTRY_CALIBRATION -#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) - #define GANTRY_CALIBRATION_CURRENT 600 // Default calibration current in ma - #define GANTRY_CALIBRATION_EXTRA_HEIGHT 15 // Extra distance in mm past Z_###_POS to move - #define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move - //#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction - - //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle - //#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM - //#define GANTRY_CALIBRATION_COMMANDS_PRE "" - #define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position -#endif - -/** - * Instant freeze / unfreeze functionality - * Potentially useful for emergency stop that allows being resumed. - */ -//#define FREEZE_FEATURE -#if ENABLED(FREEZE_FEATURE) - //#define FREEZE_PIN 41 // Override the default (KILL) pin here - #define FREEZE_STATE LOW // State of pin indicating freeze -#endif - -/** - * MAX7219 Debug Matrix - * - * Add support for a low-cost 8x8 LED Matrix based on the Max7219 chip as a realtime status display. - * Requires 3 signal wires. Some useful debug options are included to demonstrate its usage. - */ -//#define MAX7219_DEBUG -#if ENABLED(MAX7219_DEBUG) - #define MAX7219_CLK_PIN 64 - #define MAX7219_DIN_PIN 57 - #define MAX7219_LOAD_PIN 44 - - //#define MAX7219_GCODE // Add the M7219 G-code to control the LED matrix - #define MAX7219_INIT_TEST 2 // Test pattern at startup: 0=none, 1=sweep, 2=spiral - #define MAX7219_NUMBER_UNITS 1 // Number of Max7219 units in chain. - #define MAX7219_ROTATE 0 // Rotate the display clockwise (in multiples of +/- 90°) - // connector at: right=0 bottom=-90 top=90 left=180 - //#define MAX7219_REVERSE_ORDER // The individual LED matrix units may be in reversed order - //#define MAX7219_SIDE_BY_SIDE // Big chip+matrix boards can be chained side-by-side - - /** - * 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_PLANNER_HEAD 3 // Show the planner queue head position on this and the next LED matrix row - #define MAX7219_DEBUG_PLANNER_TAIL 5 // Show the planner queue tail position on this and the next LED matrix row - - #define MAX7219_DEBUG_PLANNER_QUEUE 0 // Show the current planner 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 - -/** - * NanoDLP Sync support - * - * Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will - * output a "Z_move_comp" string to enable synchronization with DLP projector exposure. - * This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands. - */ -//#define NANODLP_Z_SYNC -#if ENABLED(NANODLP_Z_SYNC) - //#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z). -#endif - -/** - * Ethernet. Use M552 to enable and set the IP address. - */ -#if HAS_ETHERNET - #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network -#endif - -/** - * WiFi Support (Espressif ESP32 WiFi) - */ -//#define WIFISUPPORT // Marlin embedded WiFi managenent -//#define ESP3D_WIFISUPPORT // ESP3D Library WiFi management (https://github.com/luc-github/ESP3DLib) - -#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT) - //#define WEBSUPPORT // Start a webserver (which may include auto-discovery) - //#define OTASUPPORT // Support over-the-air firmware updates - //#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host - - /** - * To set a default WiFi SSID / Password, create a file called Configuration_Secure.h with - * the following defines, customized for your network. This specific file is excluded via - * .gitignore to prevent it from accidentally leaking to the public. - * - * #define WIFI_SSID "WiFi SSID" - * #define WIFI_PWD "WiFi Password" - */ - //#include "Configuration_Secure.h" // External file with WiFi SSID / Password -#endif - -/** - * Průša Multi-Material Unit (MMU) - * Enable in Configuration.h - * - * These devices allow a single stepper driver on the board to drive - * multi-material feeders with any number of stepper motors. - */ -#if HAS_PRUSA_MMU1 - /** - * This option only allows the multiplexer to switch on tool-change. - * Additional options to configure custom E moves are pending. - * - * 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 inputs - //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs -#elif HAS_PRUSA_MMU2 - // Serial port used for communication with MMU2. - #define MMU2_SERIAL_PORT 2 - - // Use hardware reset for MMU if a pin is defined for it - //#define MMU2_RST_PIN 23 - - // Enable if the MMU2 has 12V stepper motors (MMU2 Firmware 1.0.2 and up) - //#define MMU2_MODE_12V - - // G-code to execute when MMU2 F.I.N.D.A. probe detects filament runout - #define MMU2_FILAMENT_RUNOUT_SCRIPT "M600" - - // Add an LCD menu for MMU2 - //#define MMU2_MENUS - #if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S) - // Settings for filament load / unload from the LCD menu. - // This is for Průša MK3-style extruders. Customize for your hardware. - #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 - #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \ - { 7.2, 1145 }, \ - { 14.4, 871 }, \ - { 36.0, 1393 }, \ - { 14.4, 871 }, \ - { 50.0, 198 } - - #define MMU2_RAMMING_SEQUENCE \ - { 1.0, 1000 }, \ - { 1.0, 1500 }, \ - { 2.0, 2000 }, \ - { 1.5, 3000 }, \ - { 2.5, 4000 }, \ - { -15.0, 5000 }, \ - { -14.0, 1200 }, \ - { -6.0, 600 }, \ - { 10.0, 700 }, \ - { -10.0, 400 }, \ - { -50.0, 2000 } - #endif - - /** - * Using a sensor like the MMU2S - * This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S. - * See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11 - */ - #if HAS_PRUSA_MMU2S - #define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries) - - #define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min) - #define MMU2_CAN_LOAD_SEQUENCE \ - { 0.1, MMU2_CAN_LOAD_FEEDRATE }, \ - { 60.0, MMU2_CAN_LOAD_FEEDRATE }, \ - { -52.0, MMU2_CAN_LOAD_FEEDRATE } - - #define MMU2_CAN_LOAD_RETRACT 6.0 // (mm) Keep under the distance between Load Sequence values - #define MMU2_CAN_LOAD_DEVIATION 0.8 // (mm) Acceptable deviation - - #define MMU2_CAN_LOAD_INCREMENT 0.2 // (mm) To reuse within MMU2 module - #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \ - { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE } - - #else - - /** - * MMU1 Extruder Sensor - * - * Support for a Průša (or other) IR Sensor to detect filament near the extruder - * and make loading more reliable. Suitable for an extruder equipped with a filament - * sensor less than 38mm from the gears. - * - * During loading the extruder will stop when the sensor is triggered, then do a last - * move up to the gears. If no filament is detected, the MMU2 can make some more attempts. - * If all attempts fail, a filament runout will be triggered. - */ - //#define MMU_EXTRUDER_SENSOR - #if ENABLED(MMU_EXTRUDER_SENSOR) - #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail - #endif - - #endif - - //#define MMU2_DEBUG // Write debug info to serial output - -#endif // HAS_PRUSA_MMU2 - -/** - * Advanced Print Counter settings - */ -#if ENABLED(PRINTCOUNTER) - #define SERVICE_WARNING_BUZZES 3 - // Activate up to 3 service interval watchdogs - //#define SERVICE_NAME_1 "Service S" - //#define SERVICE_INTERVAL_1 100 // print hours - //#define SERVICE_NAME_2 "Service L" - //#define SERVICE_INTERVAL_2 200 // print hours - //#define SERVICE_NAME_3 "Service 3" - //#define SERVICE_INTERVAL_3 1 // print hours -#endif - -// @section develop - -// -// M100 Free Memory Watcher to debug memory usage -// -//#define M100_FREE_MEMORY_WATCHER - -// -// M42 - Set pin states -// -//#define DIRECT_PIN_CONTROL - -// -// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe -// -//#define PINS_DEBUGGING - -// Enable Marlin dev mode which adds some special commands -//#define MARLIN_DEV_MODE - -#if ENABLED(MARLIN_DEV_MODE) - /** - * D576 - Buffer Monitoring - * To help diagnose print quality issues stemming from empty command buffers. - */ - //#define BUFFER_MONITORING -#endif - -/** - * Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial. - * When running in the debugger it will break for debugging. This is useful to help understand - * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash. - */ -//#define POSTMORTEM_DEBUGGING - -/** - * Software Reset options - */ -//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller -//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL - -// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR. -//#define OPTIBOOT_RESET_REASON diff --git a/Marlin/Marlin.ino b/Marlin/Marlin.ino deleted file mode 100644 index 57c8254..0000000 --- a/Marlin/Marlin.ino +++ /dev/null @@ -1,57 +0,0 @@ -/*============================================================================== - - Marlin Firmware - - (c) 2011-2020 MarlinFirmware - Portions of Marlin are (c) by their respective authors. - All code complies with GPLv2 and/or GPLv3 - -================================================================================ - -Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware. - -To configure Marlin you must edit Configuration.h and Configuration_adv.h -located in the root 'Marlin' folder. Check our Configurations repository to -see if there's a more suitable starting-point for your specific hardware. - -Before diving in, we recommend the following essential links: - -Marlin Firmware Official Website - - - https://marlinfw.org/ - The official Marlin Firmware website contains the most up-to-date - documentation. Contributions are always welcome! - -Configuration - - - https://github.com/MarlinFirmware/Configurations - Example configurations for several printer models. - - - https://www.youtube.com/watch?v=3gwWVFtdg-4 - A good 20-minute overview of Marlin configuration by Tom Sanladerer. - (Applies to Marlin 1.0.x, so Jerk and Acceleration should be halved.) - Also... https://www.google.com/search?tbs=vid%3A1&q=configure+marlin - - - https://marlinfw.org/docs/configuration/configuration.html - Marlin's configuration options are explained in more detail here. - -Getting Help - - - https://reprap.org/forum/list.php?415 - The Marlin Discussion Forum is a great place to get help from other Marlin - users who may have experienced similar issues to your own. - - - https://github.com/MarlinFirmware/Marlin/issues - With a free GitHub account you can provide us with feedback, bug reports, - and feature requests via the Marlin Issue Queue. - -Contributing - - - https://marlinfw.org/docs/development/contributing.html - If you'd like to contribute to Marlin, read this first! - - - https://marlinfw.org/docs/development/coding_standards.html - Before submitting code get to know the Coding Standards. - - -------------------------------------------------------------------------------*/ diff --git a/Marlin/Version.h b/Marlin/Version.h deleted file mode 100644 index d9634a6..0000000 --- a/Marlin/Version.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -//////////////////////////// -// VENDOR VERSION EXAMPLE // -//////////////////////////// - -/** - * Marlin release version identifier - */ -//#define SHORT_BUILD_VERSION "2.0.9.5" - -/** - * 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 - -/** - * 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 "2022-07-29" - -/** - * 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 "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 "marlinfw.org" - -/** - * Set the vendor info the serial USB interface, if changable - * Currently only supported by DUE platform - */ -//#define USB_DEVICE_VENDOR_ID 0x0000 -//#define USB_DEVICE_PRODUCT_ID 0x0000 -//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL diff --git a/Version.h b/Version.h deleted file mode 100644 index d9634a6..0000000 --- a/Version.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -//////////////////////////// -// VENDOR VERSION EXAMPLE // -//////////////////////////// - -/** - * Marlin release version identifier - */ -//#define SHORT_BUILD_VERSION "2.0.9.5" - -/** - * 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 - -/** - * 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 "2022-07-29" - -/** - * 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 "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 "marlinfw.org" - -/** - * Set the vendor info the serial USB interface, if changable - * Currently only supported by DUE platform - */ -//#define USB_DEVICE_VENDOR_ID 0x0000 -//#define USB_DEVICE_PRODUCT_ID 0x0000 -//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL diff --git a/lib/readme.txt b/lib/readme.txt deleted file mode 100644 index 52c2ac8..0000000 --- a/lib/readme.txt +++ /dev/null @@ -1,36 +0,0 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| |--Foo -| | |- Foo.c -| | |- Foo.h -| |- readme.txt --> THIS FILE -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/src/HAL/AVR/HAL.cpp b/src/HAL/AVR/HAL.cpp deleted file mode 100644 index 5382eb3..0000000 --- a/src/HAL/AVR/HAL.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __AVR__ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" -#include - -#ifdef USBCON - DefaultSerial1 MSerial0(false, Serial); - #ifdef BLUETOOTH - BTSerial btSerial(false, bluetoothSerial); - #endif -#endif - -// ------------------------ -// Public Variables -// ------------------------ - -// Don't initialize/override variable (which would happen in .init4) -uint8_t MarlinHAL::reset_reason __attribute__((section(".noinit"))); - -// ------------------------ -// Public functions -// ------------------------ - -__attribute__((naked)) // Don't output function pro- and epilogue -__attribute__((used)) // Output the function, even if "not used" -__attribute__((section(".init3"))) // Put in an early user definable section -void save_reset_reason() { - #if ENABLED(OPTIBOOT_RESET_REASON) - __asm__ __volatile__( - A("STS %0, r2") - : "=m"(hal.reset_reason) - ); - #else - hal.reset_reason = MCUSR; - #endif - - // Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop - hal.clear_reset_source(); - wdt_disable(); -} - -void MarlinHAL::init() { - // Init Servo Pins - #define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW) - #if HAS_SERVO_0 - INIT_SERVO(0); - #endif - #if HAS_SERVO_1 - INIT_SERVO(1); - #endif - #if HAS_SERVO_2 - INIT_SERVO(2); - #endif - #if HAS_SERVO_3 - INIT_SERVO(3); - #endif - - init_pwm_timers(); // Init user timers to default frequency - 1000HZ -} - -void MarlinHAL::reboot() { - #if ENABLED(USE_WATCHDOG) - while (1) { /* run out the watchdog */ } - #else - void (*resetFunc)() = 0; // Declare resetFunc() at address 0 - resetFunc(); // Jump to address 0 - #endif -} - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #include - #include "../../MarlinCore.h" - - // Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s. - void MarlinHAL::watchdog_init() { - #if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S) - #define WDTO_NS WDTO_8S - #else - #define WDTO_NS WDTO_4S - #endif - #if ENABLED(WATCHDOG_RESET_MANUAL) - // 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(); - cli(); - _WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE); - _WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5 - // So worked for up to WDTO_2S - sei(); - wdt_reset(); - #else - wdt_enable(WDTO_NS); // The function handles the upper bit correct. - #endif - //delay(10000); // test it! - } - - //=========================================================================== - //=================================== ISR =================================== - //=========================================================================== - - // Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled. - #if ENABLED(WATCHDOG_RESET_MANUAL) - ISR(WDT_vect) { - sei(); // With the interrupt driven serial we need to allow interrupts. - SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED); - minkill(); // interrupt-safe final kill and infinite loop - } - #endif - - // Reset watchdog. MUST be called at least every 4 seconds after the - // first watchdog_init or AVR will go into emergency procedures. - void MarlinHAL::watchdog_refresh() { wdt_reset(); } - -#endif // USE_WATCHDOG - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#if ENABLED(SDSUPPORT) - - #include "../../sd/SdFatUtil.h" - int freeMemory() { return SdFatUtil::FreeRam(); } - -#else // !SDSUPPORT - - 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 - -#endif // __AVR__ diff --git a/src/HAL/AVR/HAL.h b/src/HAL/AVR/HAL.h deleted file mode 100644 index 1491867..0000000 --- a/src/HAL/AVR/HAL.h +++ /dev/null @@ -1,277 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Arduino AVR - */ - -#include "../shared/Marduino.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "math.h" - -#ifdef USBCON - #include -#else - #include "MarlinSerial.h" -#endif - -#include -#include -#include -#include -#include -#include - -// -// Default graphical display delays -// -#if F_CPU >= 20000000 - #define CPU_ST7920_DELAY_1 150 - #define CPU_ST7920_DELAY_2 0 - #define CPU_ST7920_DELAY_3 150 -#elif F_CPU == 16000000 - #define CPU_ST7920_DELAY_1 125 - #define CPU_ST7920_DELAY_2 0 - #define CPU_ST7920_DELAY_3 188 -#endif - -#ifndef pgm_read_ptr - // Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for - // Windows Subsystem for Linux on Windows 10 as of 10/18/2019 - #define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long)) - #define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short)) - #define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short) -#endif - -// ------------------------ -// Defines -// ------------------------ - -// AVR PROGMEM extension for sprintf_P -#define S_FMT "%S" - -// AVR PROGMEM extension for string define -#define PGMSTR(NAM,STR) const char NAM[] PROGMEM = STR - -#ifndef CRITICAL_SECTION_START - #define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli() - #define CRITICAL_SECTION_END() SREG = _sreg -#endif - -#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment -#define PWM_FREQUENCY 1000 // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency() - -// ------------------------ -// Types -// ------------------------ - -typedef int8_t pin_t; - -#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp - -class Servo; -typedef Servo hal_servo_t; - -// ------------------------ -// Serial ports -// ------------------------ - -#ifdef USBCON - #include "../../core/serial_hook.h" - typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1; - extern DefaultSerial1 MSerial0; - #ifdef BLUETOOTH - typedef ForwardSerial1Class< decltype(bluetoothSerial) > BTSerial; - extern BTSerial btSerial; - #endif - - #define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0) -#else - #if !WITHIN(SERIAL_PORT, -1, 3) - #error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." - #endif - #define MYSERIAL1 customizedSerial1 - - #ifdef SERIAL_PORT_2 - #if !WITHIN(SERIAL_PORT_2, -1, 3) - #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." - #endif - #define MYSERIAL2 customizedSerial2 - #endif - - #ifdef SERIAL_PORT_3 - #if !WITHIN(SERIAL_PORT_3, -1, 3) - #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." - #endif - #define MYSERIAL3 customizedSerial3 - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if !WITHIN(MMU2_SERIAL_PORT, -1, 3) - #error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." - #endif - #define MMU2_SERIAL mmuSerial -#endif - -#ifdef LCD_SERIAL_PORT - #if !WITHIN(LCD_SERIAL_PORT, -1, 3) - #error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." - #endif - #define LCD_SERIAL lcdSerial - #if HAS_DGUS_LCD - #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free() - #endif -#endif - -// -// ADC -// -#define HAL_ADC_VREF 5.0 -#define HAL_ADC_RESOLUTION 10 - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -#define HAL_SENSITIVE_PINS 0, 1, - -#ifdef __AVR_AT90USB1286__ - #define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0) -#endif - -// AVR compatibility -#define strtof strtod - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -extern "C" int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init(); // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return TEST(SREG, SREG_I); } - static void isr_on() { sei(); } - static void isr_off() { cli(); } - - static void delay_ms(const int ms) { _delay_ms(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static uint8_t reset_reason; - static uint8_t get_reset_source() { return reset_reason; } - static void clear_reset_source() { MCUSR = 0; } - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - // Called by Temperature::init once at startup - static void adc_init() { - ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07; - DIDR0 = 0; - #ifdef DIDR2 - DIDR2 = 0; - #endif - } - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const uint8_t ch) { - #ifdef DIDR2 - if (ch > 7) { SBI(DIDR2, ch & 0x07); return; } - #endif - SBI(DIDR0, ch); - } - - // Begin ADC sampling on the given channel. Called from Temperature::isr! - static void adc_start(const uint8_t ch) { - #ifdef MUX5 - ADCSRB = ch > 7 ? _BV(MUX5) : 0; - #else - ADCSRB = 0; - #endif - ADMUX = _BV(REFS0) | (ch & 0x07); - SBI(ADCSRA, ADSC); - } - - // Is the ADC ready for reading? - static bool adc_ready() { return !TEST(ADCSRA, ADSC); } - - // The current value of the ADC register - static __typeof__(ADC) adc_value() { return ADC; } - - /** - * init_pwm_timers - * Set the default frequency for timers 2-5 to 1000HZ - */ - static void init_pwm_timers(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * Optionally invert the duty cycle [default = false] - * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); - - /** - * Set the frequency of the timer for the given pin as close as - * possible to the provided desired frequency. Internally calculate - * the required waveform generation mode, prescaler, and resolution - * values and set timer registers accordingly. - * NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B) - * NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST_PWM_FAN Settings) - */ - static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); -}; diff --git a/src/HAL/AVR/HAL_SPI.cpp b/src/HAL/AVR/HAL_SPI.cpp deleted file mode 100644 index dc98f2f..0000000 --- a/src/HAL/AVR/HAL_SPI.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Adapted from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - */ - -/** - * HAL for AVR - SPI functions - */ - -#ifdef __AVR__ - -#include "../../inc/MarlinConfig.h" - -void spiBegin() { - #if PIN_EXISTS(SD_SS) - // Do not init HIGH for boards with pin 4 used as Fans or Heaters or otherwise, not likely to have multiple SPI devices anyway. - #if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) - // SS must be in output mode even it is not chip select - SET_OUTPUT(SD_SS_PIN); - #else - // set SS high - may be chip select for another SPI device - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - #endif - SET_OUTPUT(SD_SCK_PIN); - SET_INPUT(SD_MISO_PIN); - SET_OUTPUT(SD_MOSI_PIN); - - IF_DISABLED(SOFTWARE_SPI, spiInit(SPI_HALF_SPEED)); -} - -#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI) - - // ------------------------ - // 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] - */ - void spiInit(uint8_t spiRate) { - // See avr processor documentation - CBI( - #ifdef PRR - PRR - #elif defined(PRR0) - PRR0 - #endif - , PRSPI - ); - - SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1); - SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X); - } - - /** SPI receive a byte */ - uint8_t spiRec() { - SPDR = 0xFF; - while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - return SPDR; - } - - /** SPI read data */ - 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 */ - void spiSend(uint8_t b) { - SPDR = b; - while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - } - - /** SPI send block */ - 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 */ } - } - - - /** begin spi transaction */ - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - // Based on Arduino SPI library - // Clock settings are defined as follows. Note that this shows SPI2X - // inverted, so the bits form increasing numbers. Also note that - // fosc/64 appears twice - // SPR1 SPR0 ~SPI2X Freq - // 0 0 0 fosc/2 - // 0 0 1 fosc/4 - // 0 1 0 fosc/8 - // 0 1 1 fosc/16 - // 1 0 0 fosc/32 - // 1 0 1 fosc/64 - // 1 1 0 fosc/64 - // 1 1 1 fosc/128 - - // We find the fastest clock that is less than or equal to the - // given clock rate. The clock divider that results in clock_setting - // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the - // slowest (128 == 2 ^^ 7, so clock_div = 6). - uint8_t clockDiv; - - // When the clock is known at compiletime, use this if-then-else - // cascade, which the compiler knows how to completely optimize - // away. When clock is not known, use a loop instead, which generates - // shorter code. - if (__builtin_constant_p(spiClock)) { - if (spiClock >= F_CPU / 2) clockDiv = 0; - else if (spiClock >= F_CPU / 4) clockDiv = 1; - else if (spiClock >= F_CPU / 8) clockDiv = 2; - else if (spiClock >= F_CPU / 16) clockDiv = 3; - else if (spiClock >= F_CPU / 32) clockDiv = 4; - else if (spiClock >= F_CPU / 64) clockDiv = 5; - else clockDiv = 6; - } - else { - uint32_t clockSetting = F_CPU / 2; - clockDiv = 0; - while (clockDiv < 6 && spiClock < clockSetting) { - clockSetting /= 2; - clockDiv++; - } - } - - // Compensate for the duplicate fosc/64 - if (clockDiv == 6) clockDiv = 7; - - // Invert the SPI2X bit - clockDiv ^= 0x1; - - SPCR = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) | - (dataMode << CPHA) | ((clockDiv >> 1) << SPR0); - SPSR = clockDiv | 0x01; - } - - -#else // SOFTWARE_SPI || FORCE_SOFT_SPI - - // ------------------------ - // Software SPI - // ------------------------ - - // nop to tune soft SPI timing - #define nop asm volatile ("\tnop\n") - - void spiInit(uint8_t) { /* do nothing */ } - - // Begin SPI transaction, set clock, bit order, data mode - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { /* do nothing */ } - - // Soft SPI receive byte - uint8_t spiRec() { - uint8_t data = 0; - // no interrupts during byte receive - about 8µs - cli(); - // output pin high - like sending 0xFF - WRITE(SD_MOSI_PIN, HIGH); - - LOOP_L_N(i, 8) { - WRITE(SD_SCK_PIN, HIGH); - - nop; // adjust so SCK is nice - nop; - - data <<= 1; - - if (READ(SD_MISO_PIN)) data |= 1; - - WRITE(SD_SCK_PIN, LOW); - } - - sei(); - return data; - } - - // Soft SPI read data - void spiRead(uint8_t *buf, uint16_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) - buf[i] = spiRec(); - } - - // Soft SPI send byte - void spiSend(uint8_t data) { - // no interrupts during byte send - about 8µs - cli(); - LOOP_L_N(i, 8) { - WRITE(SD_SCK_PIN, LOW); - WRITE(SD_MOSI_PIN, data & 0x80); - data <<= 1; - WRITE(SD_SCK_PIN, HIGH); - } - - nop; // hold SCK high for a few ns - nop; - nop; - nop; - - WRITE(SD_SCK_PIN, LOW); - - 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 || FORCE_SOFT_SPI - -#endif // __AVR__ diff --git a/src/HAL/AVR/MarlinSPI.h b/src/HAL/AVR/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/AVR/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/AVR/MarlinSerial.cpp b/src/HAL/AVR/MarlinSerial.cpp deleted file mode 100644 index 9864624..0000000 --- a/src/HAL/AVR/MarlinSerial.cpp +++ /dev/null @@ -1,652 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * MarlinSerial.cpp - Hardware serial library for Wiring - * Copyright (c) 2006 Nicholas Zambetti. All right reserved. - * - * Modified 23 November 2006 by David A. Mellis - * Modified 28 September 2010 by Mark Sproul - * Modified 14 February 2016 by Andreas Hardtung (added tx buffer) - * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF) - * Modified 10 June 2018 by Eduardo José Tagle (See #10991) - * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances - */ - -#ifdef __AVR__ - -// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.) - -#include "../../inc/MarlinConfig.h" - -#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)) - -#include "MarlinSerial.h" -#include "../../MarlinCore.h" - -#if ENABLED(DIRECT_STEPPING) - #include "../../feature/direct_stepping.h" -#endif - -template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } }; -template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 }; -template bool MarlinSerial::_written = false; -template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR; -template uint8_t MarlinSerial::rx_dropped_bytes = 0; -template uint8_t MarlinSerial::rx_buffer_overruns = 0; -template uint8_t MarlinSerial::rx_framing_errors = 0; -template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0; - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() asm volatile("": : :"memory"); - -#include "../../feature/e_parser.h" - -// "Atomically" read the RX head index value without disabling interrupts: -// This MUST be called with RX interrupts enabled, and CAN'T be called -// from the RX ISR itself! -template -FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_head() { - if (Cfg::RX_SIZE > 256) { - // Keep reading until 2 consecutive reads return the same value, - // meaning there was no update in-between caused by an interrupt. - // This works because serial RX interrupts happen at a slower rate - // than successive reads of a variable, so 2 consecutive reads with - // the same value means no interrupt updated it. - ring_buffer_pos_t vold, vnew = rx_buffer.head; - sw_barrier(); - do { - vold = vnew; - vnew = rx_buffer.head; - sw_barrier(); - } while (vold != vnew); - return vnew; - } - else { - // With an 8bit index, reads are always atomic. No need for special handling - return rx_buffer.head; - } -} - -template -volatile bool MarlinSerial::rx_tail_value_not_stable = false; -template -volatile uint16_t MarlinSerial::rx_tail_value_backup = 0; - -// Set RX tail index, taking into account the RX ISR could interrupt -// the write to this variable in the middle - So a backup strategy -// is used to ensure reads of the correct values. -// -Must NOT be called from the RX ISR - -template -FORCE_INLINE void MarlinSerial::atomic_set_rx_tail(typename MarlinSerial::ring_buffer_pos_t value) { - if (Cfg::RX_SIZE > 256) { - // Store the new value in the backup - rx_tail_value_backup = value; - sw_barrier(); - // Flag we are about to change the true value - rx_tail_value_not_stable = true; - sw_barrier(); - // Store the new value - rx_buffer.tail = value; - sw_barrier(); - // Signal the new value is completely stored into the value - rx_tail_value_not_stable = false; - sw_barrier(); - } - else - rx_buffer.tail = value; -} - -// Get the RX tail index, taking into account the read could be -// interrupting in the middle of the update of that index value -// -Called from the RX ISR - -template -FORCE_INLINE typename MarlinSerial::ring_buffer_pos_t MarlinSerial::atomic_read_rx_tail() { - if (Cfg::RX_SIZE > 256) { - // If the true index is being modified, return the backup value - if (rx_tail_value_not_stable) return rx_tail_value_backup; - } - // The true index is stable, return it - return rx_buffer.tail; -} - -// (called with RX interrupts disabled) -template -FORCE_INLINE void MarlinSerial::store_rxd_char() { - - static EmergencyParser::State emergency_state; // = EP_RESET - - // This must read the R_UCSRA register before reading the received byte to detect error causes - if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes; - if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns; - if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors; - - // Read the character from the USART - uint8_t c = R_UDR; - - #if ENABLED(DIRECT_STEPPING) - if (page_manager.maybe_store_rxd_char(c)) return; - #endif - - // Get the tail - Nothing can alter its value while this ISR is executing, but there's - // a chance that this ISR interrupted the main process while it was updating the index. - // The backup mechanism ensures the correct value is always returned. - const ring_buffer_pos_t t = atomic_read_rx_tail(); - - // Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here - ring_buffer_pos_t h = rx_buffer.head; - - // Get the next element - ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the RX FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - - if (Cfg::MAX_RX_QUEUED) { - // Calculate count of bytes stored into the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Keep track of the maximum count of enqueued bytes - NOLESS(rx_max_enqueued, rx_count); - } - - if (Cfg::XONOFF) { - // If the last char that was sent was an XON - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) { - - // Bytes stored into the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // If over 12.5% of RX buffer capacity, send XOFF before running out of - // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react - // and stop sending bytes. This translates to 13mS propagation time. - if (rx_count >= (Cfg::RX_SIZE) / 8) { - - // At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted. - // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens - // to be in the middle of trying to disable the RX interrupt in the main program, eventually the - // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure - // the sending of the XOFF char is to send it HERE AND NOW. - - // About to send the XOFF char - xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; - - // Wait until the TX register becomes empty and send it - Here there could be a problem - // - While waiting for the TX register to empty, the RX register could receive a new - // character. This must also handle that situation! - while (!B_UDRE) { - - if (B_RXC) { - // A char arrived while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = R_UDR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - R_UDR = XOFF_CHAR; - - // Clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - - // At this point there could be a race condition between the write() function - // and this sending of the XOFF char. This interrupt could happen between the - // wait to be empty TX buffer loop and the actual write of the character. Since - // the TX buffer is full because it's sending the XOFF char, the only way to be - // sure the write() function will succeed is to wait for the XOFF char to be - // completely sent. Since an extra character could be received during the wait - // it must also be handled! - while (!B_UDRE) { - - if (B_RXC) { - // A char arrived while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = R_UDR; - - if (Cfg::EMERGENCYPARSER) - emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - // At this point everything is ready. The write() function won't - // have any issues writing to the UART TX register if it needs to! - } - } - } - - // Store the new head value - The main loop will retry until the value is stable - rx_buffer.head = h; -} - -// (called with TX irqs disabled) -template -FORCE_INLINE void MarlinSerial::_tx_udr_empty_irq() { - if (Cfg::TX_SIZE > 0) { - // Read positions - uint8_t t = tx_buffer.tail; - const uint8_t h = tx_buffer.head; - - if (Cfg::XONOFF) { - // If an XON char is pending to be sent, do it now - if (xon_xoff_state == XON_CHAR) { - - // Send the character - R_UDR = XON_CHAR; - - // clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - - // Remember we sent it. - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - - // If nothing else to transmit, just disable TX interrupts. - if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - - return; - } - } - - // If nothing to transmit, just disable TX interrupts. This could - // happen as the result of the non atomicity of the disabling of RX - // interrupts that could end reenabling TX interrupts as a side effect. - if (h == t) { - B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - return; - } - - // There is something to TX, Send the next byte - const uint8_t c = tx_buffer.buffer[t]; - t = (t + 1) & (Cfg::TX_SIZE - 1); - R_UDR = c; - tx_buffer.tail = t; - - // Clear the TXC bit (by writing a one to its bit location). - // Ensures flush() won't return until the bytes are actually written/ - B_TXC = 1; - - // Disable interrupts if there is nothing to transmit following this byte - if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed) - } -} - -// Public Methods -template -void MarlinSerial::begin(const long baud) { - uint16_t baud_setting; - bool useU2X = true; - - #if F_CPU == 16000000UL && SERIAL_PORT == 0 - // Hard-coded exception for compatibility with the bootloader shipped - // with the Duemilanove and previous boards, and the firmware on the - // 8U2 on the Uno and Mega 2560. - if (baud == 57600) useU2X = false; - #endif - - R_UCSRA = 0; - if (useU2X) { - B_U2X = 1; - baud_setting = (F_CPU / 4 / baud - 1) / 2; - } - else - baud_setting = (F_CPU / 8 / baud - 1) / 2; - - // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) - R_UBRRH = baud_setting >> 8; - R_UBRRL = baud_setting; - - B_RXEN = 1; - B_TXEN = 1; - B_RXCIE = 1; - if (Cfg::TX_SIZE > 0) B_UDRIE = 0; - _written = false; -} - -template -void MarlinSerial::end() { - B_RXEN = 0; - B_TXEN = 0; - B_RXCIE = 0; - B_UDRIE = 0; -} - -template -int MarlinSerial::peek() { - const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; - return h == t ? -1 : rx_buffer.buffer[t]; -} - -template -int MarlinSerial::read() { - const ring_buffer_pos_t h = atomic_read_rx_head(); - - // Read the tail. Main thread owns it, so it is safe to directly read it - ring_buffer_pos_t t = rx_buffer.tail; - - // If nothing to read, return now - if (h == t) return -1; - - // Get the next char - const int v = rx_buffer.buffer[t]; - t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1); - - // Advance tail - Making sure the RX ISR will always get an stable value, even - // if it interrupts the writing of the value of that variable in the middle. - atomic_set_rx_tail(t); - - if (Cfg::XONOFF) { - // If the XOFF char was sent, or about to be sent... - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - // Get count of bytes in the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - if (rx_count < (Cfg::RX_SIZE) / 10) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX ISR. Non atomic, but it will eventually enable them - B_UDRIE = 1; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!B_UDRE) sw_barrier(); - R_UDR = XON_CHAR; - } - } - } - } - - return v; -} - -template -typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() { - const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail; - return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1); -} - -template -void MarlinSerial::flush() { - - // Set the tail to the head: - // - Read the RX head index in a safe way. (See atomic_read_rx_head.) - // - Set the tail, making sure the RX ISR will always get a stable value, even - // if it interrupts the writing of the value of that variable in the middle. - atomic_set_rx_tail(atomic_read_rx_head()); - - if (Cfg::XONOFF) { - // If the XOFF char was sent, or about to be sent... - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX ISR. Non atomic, but it will eventually enable it. - B_UDRIE = 1; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!B_UDRE) sw_barrier(); - R_UDR = XON_CHAR; - } - } - } -} - -template -void MarlinSerial::write(const uint8_t c) { - if (Cfg::TX_SIZE == 0) { - - _written = true; - while (!B_UDRE) sw_barrier(); - R_UDR = c; - - } - else { - - _written = true; - - // If the TX interrupts are disabled and the data register - // is empty, just write the byte to the data register and - // be done. This shortcut helps significantly improve the - // effective datarate at high (>500kbit/s) bitrates, where - // interrupt overhead becomes a slowdown. - // Yes, there is a race condition between the sending of the - // XOFF char at the RX ISR, but it is properly handled there - if (!B_UDRIE && B_UDRE) { - R_UDR = c; - - // clear the TXC bit -- "can be cleared by writing a one to its bit - // location". This makes sure flush() won't return until the bytes - // actually got written - B_TXC = 1; - return; - } - - const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1); - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!hal.isr_state()) { - - // Make room by polling if it is possible to transmit, and do so! - while (i == tx_buffer.tail) { - - // If we can transmit another byte, do it. - if (B_UDRE) _tx_udr_empty_irq(); - - // Make sure compiler rereads tx_buffer.tail - sw_barrier(); - } - } - else { - // Interrupts are enabled, just wait until there is space - while (i == tx_buffer.tail) sw_barrier(); - } - - // Store new char. head is always safe to move - tx_buffer.buffer[tx_buffer.head] = c; - tx_buffer.head = i; - - // Enable TX ISR - Non atomic, but it will eventually enable TX ISR - B_UDRIE = 1; - } -} - -template -void MarlinSerial::flushTX() { - - if (Cfg::TX_SIZE == 0) { - // No bytes written, no need to flush. This special case is needed since there's - // no way to force the TXC (transmit complete) bit to 1 during initialization. - if (!_written) return; - - // Wait until everything was transmitted - while (!B_TXC) sw_barrier(); - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - - } - else { - - // No bytes written, no need to flush. This special case is needed since there's - // no way to force the TXC (transmit complete) bit to 1 during initialization. - if (!_written) return; - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!hal.isr_state()) { - - // Wait until everything was transmitted - We must do polling, as interrupts are disabled - while (tx_buffer.head != tx_buffer.tail || !B_TXC) { - - // If there is more space, send an extra character - if (B_UDRE) _tx_udr_empty_irq(); - - sw_barrier(); - } - - } - else { - // Wait until everything was transmitted - while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier(); - } - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - } -} - -// Hookup ISR handlers -ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) { - MarlinSerial>::store_rxd_char(); -} - -ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); -} - -// Because of the template definition above, it's required to instantiate the template to have all methods generated -template class MarlinSerial< MarlinSerialCfg >; -MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser); - -#ifdef SERIAL_PORT_2 - - // Hookup ISR handlers - ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - template class MarlinSerial< MarlinSerialCfg >; - MSerialT2 customizedSerial2(MSerialT2::HasEmergencyParser); - -#endif // SERIAL_PORT_2 - -#ifdef SERIAL_PORT_3 - - // Hookup ISR handlers - ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - template class MarlinSerial< MarlinSerialCfg >; - MSerialT3 customizedSerial3(MSerialT3::HasEmergencyParser); - -#endif // SERIAL_PORT_3 - -#ifdef MMU2_SERIAL_PORT - - ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - template class MarlinSerial< MMU2SerialCfg >; - MSerialMMU2 mmuSerial(MSerialMMU2::HasEmergencyParser); - -#endif // MMU2_SERIAL_PORT - -#ifdef LCD_SERIAL_PORT - - ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _RX_vect)) { - MarlinSerial>::store_rxd_char(); - } - - ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _UDRE_vect)) { - MarlinSerial>::_tx_udr_empty_irq(); - } - - template class MarlinSerial< LCDSerialCfg >; - MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser); - - #if HAS_DGUS_LCD - template - typename MarlinSerial::ring_buffer_pos_t MarlinSerial::get_tx_buffer_free() { - const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send. - h = tx_buffer.head; // next pos for queue. - int ret = t - h - 1; - if (ret < 0) ret += Cfg::TX_SIZE + 1; - return ret; - } - #endif - -#endif // LCD_SERIAL_PORT - -#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H) - -// For AT90USB targets use the UART for BT interfacing -#if defined(USBCON) && ENABLED(BLUETOOTH) - MSerialBT bluetoothSerial(false); -#endif - -#endif // __AVR__ diff --git a/src/HAL/AVR/MarlinSerial.h b/src/HAL/AVR/MarlinSerial.h deleted file mode 100644 index 7eb7600..0000000 --- a/src/HAL/AVR/MarlinSerial.h +++ /dev/null @@ -1,297 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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) - * Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF) - * Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances - */ - -#include - -#include "../../inc/MarlinConfigPre.h" -#include "../../core/serial_hook.h" - -#ifndef SERIAL_PORT - #define SERIAL_PORT 0 -#endif - -#ifndef USBCON - - // 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(registerbase,number,suffix) - #if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary - #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##suffix - #else - #define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##number##suffix - #endif - - // Registers used by MarlinSerial class (expanded depending on selected serial port) - - // Templated 8bit register (generic) - #define UART_REGISTER_DECL_BASE(registerbase, suffix) \ - template struct R_##registerbase##x##suffix {} - - // Templated 8bit register (specialization for each port) - #define UART_REGISTER_DECL(port, registerbase, suffix) \ - template<> struct R_##registerbase##x##suffix { \ - constexpr R_##registerbase##x##suffix(int) {} \ - FORCE_INLINE void operator=(uint8_t newVal) const { SERIAL_REGNAME(registerbase,port,suffix) = newVal; } \ - FORCE_INLINE operator uint8_t() const { return SERIAL_REGNAME(registerbase,port,suffix); } \ - } - - // Templated 1bit register (generic) - #define UART_BIT_DECL_BASE(registerbase, suffix, bit) \ - templatestruct B_##bit##x {} - - // Templated 1bit register (specialization for each port) - #define UART_BIT_DECL(port, registerbase, suffix, bit) \ - template<> struct B_##bit##x { \ - constexpr B_##bit##x(int) {} \ - FORCE_INLINE void operator=(int newVal) const { \ - if (newVal) \ - SBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \ - else \ - CBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \ - } \ - FORCE_INLINE operator bool() const { return TEST(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); } \ - } - - #define UART_DECL_BASE() \ - UART_REGISTER_DECL_BASE(UCSR,A);\ - UART_REGISTER_DECL_BASE(UDR,);\ - UART_REGISTER_DECL_BASE(UBRR,H);\ - UART_REGISTER_DECL_BASE(UBRR,L);\ - UART_BIT_DECL_BASE(UCSR,B,RXEN);\ - UART_BIT_DECL_BASE(UCSR,B,TXEN);\ - UART_BIT_DECL_BASE(UCSR,A,TXC);\ - UART_BIT_DECL_BASE(UCSR,B,RXCIE);\ - UART_BIT_DECL_BASE(UCSR,A,UDRE);\ - UART_BIT_DECL_BASE(UCSR,A,FE);\ - UART_BIT_DECL_BASE(UCSR,A,DOR);\ - UART_BIT_DECL_BASE(UCSR,B,UDRIE);\ - UART_BIT_DECL_BASE(UCSR,A,RXC);\ - UART_BIT_DECL_BASE(UCSR,A,U2X) - - #define UART_DECL(port) \ - UART_REGISTER_DECL(port,UCSR,A);\ - UART_REGISTER_DECL(port,UDR,);\ - UART_REGISTER_DECL(port,UBRR,H);\ - UART_REGISTER_DECL(port,UBRR,L);\ - UART_BIT_DECL(port,UCSR,B,RXEN);\ - UART_BIT_DECL(port,UCSR,B,TXEN);\ - UART_BIT_DECL(port,UCSR,A,TXC);\ - UART_BIT_DECL(port,UCSR,B,RXCIE);\ - UART_BIT_DECL(port,UCSR,A,UDRE);\ - UART_BIT_DECL(port,UCSR,A,FE);\ - UART_BIT_DECL(port,UCSR,A,DOR);\ - UART_BIT_DECL(port,UCSR,B,UDRIE);\ - UART_BIT_DECL(port,UCSR,A,RXC);\ - UART_BIT_DECL(port,UCSR,A,U2X) - - // Declare empty templates - UART_DECL_BASE(); - - // And all the specializations for each possible serial port - #if UART_PRESENT(0) - UART_DECL(0); - #endif - #if UART_PRESENT(1) - UART_DECL(1); - #endif - #if UART_PRESENT(2) - UART_DECL(2); - #endif - #if UART_PRESENT(3) - UART_DECL(3); - #endif - - #define BYTE 0 - - // Templated type selector - template struct TypeSelector { typedef T type;} ; - template struct TypeSelector { typedef F type; }; - - template - class MarlinSerial { - protected: - // Registers - static constexpr R_UCSRxA R_UCSRA = 0; - static constexpr R_UDRx R_UDR = 0; - static constexpr R_UBRRxH R_UBRRH = 0; - static constexpr R_UBRRxL R_UBRRL = 0; - - // Bits - static constexpr B_RXENx B_RXEN = 0; - static constexpr B_TXENx B_TXEN = 0; - static constexpr B_TXCx B_TXC = 0; - static constexpr B_RXCIEx B_RXCIE = 0; - static constexpr B_UDREx B_UDRE = 0; - static constexpr B_FEx B_FE = 0; - static constexpr B_DORx B_DOR = 0; - static constexpr B_UDRIEx B_UDRIE = 0; - static constexpr B_RXCx B_RXC = 0; - static constexpr B_U2Xx B_U2X = 0; - - // Base size of type on buffer size - typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t; - - struct ring_buffer_r { - volatile ring_buffer_pos_t head, tail; - unsigned char buffer[Cfg::RX_SIZE]; - }; - - struct ring_buffer_t { - volatile uint8_t head, tail; - unsigned char buffer[Cfg::TX_SIZE]; - }; - - static ring_buffer_r rx_buffer; - static ring_buffer_t tx_buffer; - static bool _written; - - static constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80, // XON / XOFF Character was sent - XON_XOFF_CHAR_MASK = 0x1F; // XON / XOFF character to send - - // XON / XOFF character definitions - static constexpr uint8_t XON_CHAR = 17, XOFF_CHAR = 19; - static uint8_t xon_xoff_state, - rx_dropped_bytes, - rx_buffer_overruns, - rx_framing_errors; - static ring_buffer_pos_t rx_max_enqueued; - - FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_head(); - - static volatile bool rx_tail_value_not_stable; - static volatile uint16_t rx_tail_value_backup; - - FORCE_INLINE static void atomic_set_rx_tail(ring_buffer_pos_t value); - FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_tail(); - - public: - FORCE_INLINE static void store_rxd_char(); - FORCE_INLINE static void _tx_udr_empty_irq(); - - public: - static void begin(const long); - static void end(); - static int peek(); - static int read(); - static void flush(); - static ring_buffer_pos_t available(); - static void write(const uint8_t c); - static void flushTX(); - #if HAS_DGUS_LCD - static ring_buffer_pos_t get_tx_buffer_free(); - #endif - - enum { HasEmergencyParser = Cfg::EMERGENCYPARSER }; - static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; } - - FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; } - FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; } - FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; } - FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; } - }; - - template - struct MarlinSerialCfg { - static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE; - static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE; - static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF); - static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); - static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX); - static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS); - static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS); - static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED); - }; - - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1; - extern MSerialT1 customizedSerial1; - - #ifdef SERIAL_PORT_2 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2; - extern MSerialT2 customizedSerial2; - #endif - - #ifdef SERIAL_PORT_3 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3; - extern MSerialT3 customizedSerial3; - #endif - -#endif // !USBCON - -#ifdef MMU2_SERIAL_PORT - template - struct MMU2SerialCfg { - static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = 32; - static constexpr unsigned int TX_SIZE = 32; - static constexpr bool XONOFF = false; - static constexpr bool EMERGENCYPARSER = false; - static constexpr bool DROPPED_RX = false; - static constexpr bool RX_FRAMING_ERRORS = false; - static constexpr bool MAX_RX_QUEUED = false; - static constexpr bool RX_OVERRUNS = false; - }; - - typedef Serial1Class< MarlinSerial< MMU2SerialCfg > > MSerialMMU2; - extern MSerialMMU2 mmuSerial; -#endif - -#ifdef LCD_SERIAL_PORT - - template - struct LCDSerialCfg { - static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = TERN(HAS_DGUS_LCD, DGUS_RX_BUFFER_SIZE, 64); - static constexpr unsigned int TX_SIZE = TERN(HAS_DGUS_LCD, DGUS_TX_BUFFER_SIZE, 128); - static constexpr bool XONOFF = false; - static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); - static constexpr bool DROPPED_RX = false; - static constexpr bool RX_FRAMING_ERRORS = false; - static constexpr bool MAX_RX_QUEUED = false; - static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS); - }; - - typedef Serial1Class< MarlinSerial< LCDSerialCfg > > MSerialLCD; - extern MSerialLCD lcdSerial; -#endif - -// Use the UART for Bluetooth in AT90USB configurations -#if defined(USBCON) && ENABLED(BLUETOOTH) - typedef Serial1Class MSerialBT; - extern MSerialBT bluetoothSerial; -#endif diff --git a/src/HAL/AVR/Servo.cpp b/src/HAL/AVR/Servo.cpp deleted file mode 100644 index 0a1ef53..0000000 --- a/src/HAL/AVR/Servo.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * 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), safe_delay(servo_delay[servoIndex]). - * With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after servo_delay[servoIndex]. - * 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. - */ - -#ifdef __AVR__ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include - -#include "../shared/servo.h" -#include "../shared/servo_private.h" - -static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) - - -/************ static functions common to all instances ***********************/ - -static inline void handle_interrupts(const timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) { - int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first - if (cho < 0) // Channel -1 indicates the refresh interval completed... - *TCNTn = 0; // ...so reset the timer - else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled? - extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW - - Channel[timer] = ++cho; // Handle the next channel (or 0) - if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) { - *OCRnA = *TCNTn + SERVO(timer, cho).ticks; // set compare to current ticks plus duration - if (SERVO(timer, cho).Pin.isActive) // activated? - extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH - } - else { - // finished all channels so wait for the refresh period to expire before starting over - const unsigned int cval = ((unsigned)*TCNTn) + 32 / (SERVO_TIMER_PRESCALER), // allow 32 cycles to ensure the next OCR1A not missed - ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed - *OCRnA = max(cval, ival); - - Channel[timer] = -1; // reset the timer counter to 0 on the next call - } -} - -#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform - - // Interrupt handlers for Arduino - #ifdef _useTimer1 - SIGNAL(TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); } - #endif - - #ifdef _useTimer3 - SIGNAL(TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); } - #endif - - #ifdef _useTimer4 - SIGNAL(TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); } - #endif - - #ifdef _useTimer5 - SIGNAL(TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); } - #endif - -#else // WIRING - - // Interrupt handlers for Wiring - #ifdef _useTimer1 - void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); } - #endif - #ifdef _useTimer3 - void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); } - #endif - -#endif // WIRING - -/****************** end of static functions ******************************/ - -void initISR(const timer16_Sequence_t timer_index) { - switch (timer_index) { - default: break; - - #ifdef _useTimer1 - case _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 - break; - #endif - - #ifdef _useTimer3 - case _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 - break; - #endif - - #ifdef _useTimer4 - case _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 - break; - #endif - - #ifdef _useTimer5 - case _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 - break; - #endif - } -} - -void finISR(const timer16_Sequence_t timer_index) { - // Disable use of the given timer - #ifdef WIRING - switch (timer_index) { - default: break; - - case _timer1: - CBI( - #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) - TIMSK1 - #else - TIMSK - #endif - , OCIE1A // disable timer 1 output compare interrupt - ); - timerDetach(TIMER1OUTCOMPAREA_INT); - break; - - case _timer3: - CBI( - #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) - TIMSK3 - #else - ETIMSK - #endif - , OCIE3A // disable the timer3 output compare A interrupt - ); - timerDetach(TIMER3OUTCOMPAREA_INT); - break; - } - #else // !WIRING - // For arduino - in future: call here to a currently undefined function to reset the timer - UNUSED(timer_index); - #endif -} - -#endif // HAS_SERVOS - -#endif // __AVR__ diff --git a/src/HAL/AVR/ServoTimers.h b/src/HAL/AVR/ServoTimers.h deleted file mode 100644 index 436b281..0000000 --- a/src/HAL/AVR/ServoTimers.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * ServoTimers.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 - */ - -/** - * 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. - */ - -/** - * AVR Only definitions - * -------------------- - */ - -#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays -#define SERVO_TIMER_PRESCALER 8 // timer prescaler - -// Say which 16 bit timers can be used and in what order -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - //#define _useTimer1 - #define _useTimer4 - #if NUM_SERVOS > SERVOS_PER_TIMER - #define _useTimer3 - #if !HAS_MOTOR_CURRENT_PWM && SERVOS > 2 * SERVOS_PER_TIMER - #define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos. - #endif - #endif -#elif defined(__AVR_ATmega32U4__) - #define _useTimer3 -#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 { - #ifdef _useTimer1 - _timer1, - #endif - #ifdef _useTimer3 - _timer3, - #endif - #ifdef _useTimer4 - _timer4, - #endif - #ifdef _useTimer5 - _timer5, - #endif - _Nbr_16timers -} timer16_Sequence_t; diff --git a/src/HAL/AVR/eeprom.cpp b/src/HAL/AVR/eeprom.cpp deleted file mode 100644 index 8d084de..0000000 --- a/src/HAL/AVR/eeprom.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __AVR__ - -#include "../../inc/MarlinConfig.h" - -#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - -/** - * PersistentStore for Arduino-style EEPROM interface - * with implementations supplied by the framework. - */ - -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; // always assume success for AVR's -} - -#endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE -#endif // __AVR__ diff --git a/src/HAL/AVR/endstop_interrupts.h b/src/HAL/AVR/endstop_interrupts.h deleted file mode 100644 index 0ce8574..0000000 --- a/src/HAL/AVR/endstop_interrupts.h +++ /dev/null @@ -1,306 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate 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) - */ - -#include "../../module/endstops.h" - -#include - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -/** - * 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 (D14, D15). - * 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) - - #define digitalPinHasPCICR(p) (WITHIN(p, 10, 15) || WITHIN(p, 50, 53) || WITHIN(p, 62, 69)) - - #undef digitalPinToPCICR - #define digitalPinToPCICR(p) (digitalPinHasPCICR(p) ? (&PCICR) : nullptr) - - #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) : \ - nullptr) - - #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) - -#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324A__) || \ - defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega324PB__) || \ - defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284__) || \ - defined(__AVR_ATmega1284P__) - - #define digitalPinHasPCICR(p) WITHIN(p, 0, NUM_DIGITAL_PINS) - -#else - - #error "Unsupported AVR variant!" - -#endif - - -// Install Pin change interrupt for a pin. Can be called multiple times. -void pciSetup(const int8_t pin) { - if (digitalPinHasPCICR(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 - } -} - -// Handlers for pin change interrupts -#ifdef PCINT0_vect - ISR(PCINT0_vect) { endstop_ISR(); } -#endif - -#ifdef PCINT1_vect - ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -#ifdef PCINT2_vect - ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -#ifdef PCINT3_vect - ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect)); -#endif - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #if HAS_X_MAX - #if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(X_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(X_MAX_PIN); - #endif - #endif - #if HAS_X_MIN - #if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(X_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(X_MIN_PIN); - #endif - #endif - #if HAS_Y_MAX - #if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Y_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Y_MAX_PIN); - #endif - #endif - #if HAS_Y_MIN - #if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Y_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Y_MIN_PIN); - #endif - #endif - #if HAS_Z_MAX - #if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z_MAX_PIN); - #endif - #endif - #if HAS_Z_MIN - #if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z_MIN_PIN); - #endif - #endif - #if HAS_I_MAX - #if (digitalPinToInterrupt(I_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(I_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(I_MAX_PIN), "I_MAX_PIN is not interrupt-capable"); - pciSetup(I_MAX_PIN); - #endif - #elif HAS_I_MIN - #if (digitalPinToInterrupt(I_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(I_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(I_MIN_PIN), "I_MIN_PIN is not interrupt-capable"); - pciSetup(I_MIN_PIN); - #endif - #endif - #if HAS_J_MAX - #if (digitalPinToInterrupt(J_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(J_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(J_MAX_PIN), "J_MAX_PIN is not interrupt-capable"); - pciSetup(J_MAX_PIN); - #endif - #elif HAS_J_MIN - #if (digitalPinToInterrupt(J_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(J_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(J_MIN_PIN), "J_MIN_PIN is not interrupt-capable"); - pciSetup(J_MIN_PIN); - #endif - #endif - #if HAS_K_MAX - #if (digitalPinToInterrupt(K_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(K_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(K_MAX_PIN), "K_MAX_PIN is not interrupt-capable"); - pciSetup(K_MAX_PIN); - #endif - #elif HAS_K_MIN - #if (digitalPinToInterrupt(K_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(K_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(K_MIN_PIN), "K_MIN_PIN is not interrupt-capable"); - pciSetup(K_MIN_PIN); - #endif - #endif - #if HAS_X2_MAX - #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(X2_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(X2_MAX_PIN); - #endif - #endif - #if HAS_X2_MIN - #if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(X2_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(X2_MIN_PIN); - #endif - #endif - #if HAS_Y2_MAX - #if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Y2_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Y2_MAX_PIN); - #endif - #endif - #if HAS_Y2_MIN - #if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Y2_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Y2_MIN_PIN); - #endif - #endif - #if HAS_Z2_MAX - #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z2_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z2_MAX_PIN); - #endif - #endif - #if HAS_Z2_MIN - #if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z2_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z2_MIN_PIN); - #endif - #endif - #if HAS_Z3_MAX - #if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z3_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z3_MAX_PIN); - #endif - #endif - #if HAS_Z3_MIN - #if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z3_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z3_MIN_PIN); - #endif - #endif - #if HAS_Z4_MAX - #if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z4_MAX_PIN); - #else - static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z4_MAX_PIN); - #endif - #endif - #if HAS_Z4_MIN - #if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z4_MIN_PIN); - #else - static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - pciSetup(Z4_MIN_PIN); - #endif - #endif - #if HAS_Z_MIN_PROBE_PIN - #if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT) - _ATTACH(Z_MIN_PROBE_PIN); - #else - static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."); - 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. -} diff --git a/src/HAL/AVR/fast_pwm.cpp b/src/HAL/AVR/fast_pwm.cpp deleted file mode 100644 index 0a38417..0000000 --- a/src/HAL/AVR/fast_pwm.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __AVR__ - -#include "../../inc/MarlinConfig.h" - -struct Timer { - volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer - volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer - volatile uint16_t* ICRn; // max 1 ICR register per timer - uint8_t n; // the timer number [0->5] - uint8_t q; // the timer output [0->2] (A->C) - bool isPWM; // True if pin is a "hardware timer" - bool isProtected; // True if timer is protected -}; - -// Macros for the Timer structure -#define _SET_WGMnQ(T, V) do{ \ - *(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \ - *(T.TCCRnQ)[1] = (*(T.TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \ - }while(0) - -// Set TCCR CS bits -#define _SET_CSn(T, V) (*(T.TCCRnQ)[1] = (*(T.TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)) - -// Set TCCR COM bits -#define _SET_COMnQ(T, Q, V) (*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))) - -// Set OCRnQ register -#define _SET_OCRnQ(T, Q, V) (*(T.OCRnQ)[Q] = int(V) & 0xFFFF) - -// Set ICRn register (one per timer) -#define _SET_ICRn(T, V) (*(T.ICRn) = int(V) & 0xFFFF) - -/** - * Return a Timer struct describing a pin's timer. - */ -const Timer get_pwm_timer(const pin_t pin) { - - uint8_t q = 0; - - switch (digitalPinToTimer(pin)) { - #ifdef TCCR0A - IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:) - #endif - #ifdef TCCR1A - case TIMER1A: case TIMER1B: - #endif - - break; // Protect reserved timers (TIMER0 & TIMER1) - - #ifdef TCCR0A - case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only - return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0A, (uint16_t*)&OCR0B, nullptr }, nullptr, 0, 1, true, true }); - #endif - - #if HAS_TCCR2 - case TIMER2: - return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false }); - #elif ENABLED(USE_OCR2A_AS_TOP) - case TIMER2A: break; // Protect TIMER2A since its OCR is used by TIMER2B - case TIMER2B: - return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false }); - #elif defined(TCCR2A) - case TIMER2B: ++q; case TIMER2A: - return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false }); - #endif - - #ifdef OCR3C - case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A: - return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false }); - #elif defined(OCR3B) - case TIMER3B: ++q; case TIMER3A: - return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false }); - #endif - - #ifdef TCCR4A - case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A: - return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false }); - #endif - - #ifdef TCCR5A - case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A: - return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false }); - #endif - } - - return Timer(); -} - -void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { - const Timer timer = get_pwm_timer(pin); - if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized - - const bool is_timer2 = timer.n == 2; - const uint16_t maxtop = is_timer2 ? 0xFF : 0xFFFF; - - uint16_t res = 0xFF; // resolution (TOP value) - uint8_t j = CS_NONE; // prescaler index - uint8_t wgm = WGM_PWM_PC_8; // waveform generation mode - - // Calculating the prescaler and resolution to use to achieve closest frequency - if (f_desired != 0) { - constexpr uint16_t prescaler[] = { 1, 8, (32), 64, (128), 256, 1024 }; // (*) are Timer 2 only - uint16_t f = (F_CPU) / (2 * 1024 * maxtop) + 1; // Start with the lowest non-zero frequency achievable (1 or 31) - - LOOP_L_N(i, COUNT(prescaler)) { // Loop through all prescaler values - const uint16_t p = prescaler[i]; - uint16_t res_fast_temp, res_pc_temp; - if (is_timer2) { - #if ENABLED(USE_OCR2A_AS_TOP) // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP - const uint16_t rft = (F_CPU) / (p * f_desired); - res_fast_temp = rft - 1; - res_pc_temp = rft / 2; - #else - res_fast_temp = res_pc_temp = maxtop; - #endif - } - else { - if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2 - const uint16_t rft = (F_CPU) / (p * f_desired); - res_fast_temp = rft - 1; - res_pc_temp = rft / 2; - } - - LIMIT(res_fast_temp, 1U, maxtop); - LIMIT(res_pc_temp, 1U, maxtop); - - // Calculate frequencies of test prescaler and resolution values - const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired), - f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)), - f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired), - f_pc_temp = (F_CPU) / (2 * p * res_pc_temp), - f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired); - - if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f - // Set the Wave Generation Mode to FAST PWM - wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn); - // Remember this combination - f = f_fast_temp; res = res_fast_temp; j = i + 1; - } - else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f - // Set the Wave Generation Mode to PWM PHASE CORRECT - wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn); - f = f_pc_temp; res = res_pc_temp; j = i + 1; - } - } - } - - _SET_WGMnQ(timer, wgm); - _SET_CSn(timer, j); - - if (is_timer2) { - TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer, 0, res)); // Set OCR2A value (TOP) = res - } - else - _SET_ICRn(timer, res); // Set ICRn value (TOP) = res -} - -void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { - // If v is 0 or v_size (max), digitalWrite to LOW or HIGH. - // Note that digitalWrite also disables PWM output for us (sets COM bit to 0) - if (v == 0) - digitalWrite(pin, invert); - else if (v == v_size) - digitalWrite(pin, !invert); - else { - const Timer timer = get_pwm_timer(pin); - if (timer.isPWM) { - if (timer.n == 0) { - _SET_COMnQ(timer, timer.q, COM_CLEAR_SET); // Only allow a TIMER0B select... - _SET_OCRnQ(timer, timer.q, v); // ...and OCR0B duty update. For output pin D4 no frequency changes are permitted. - } - else if (!timer.isProtected) { - const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn; - _SET_COMnQ(timer, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2 - _SET_OCRnQ(timer, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value - } - } - else - digitalWrite(pin, v < v_size / 2 ? LOW : HIGH); - } -} - -void MarlinHAL::init_pwm_timers() { - // Init some timer frequencies to a default 1KHz - const pin_t pwm_pin[] = { - #ifdef __AVR_ATmega2560__ - 10, 5, 6, 46 - #elif defined(__AVR_ATmega1280__) - 12, 31 - #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__) - 15, 6 - #elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128) - 16, 24 - #endif - }; - - LOOP_L_N(i, COUNT(pwm_pin)) - set_pwm_frequency(pwm_pin[i], 1000); -} - -#endif // __AVR__ diff --git a/src/HAL/AVR/fastio.cpp b/src/HAL/AVR/fastio.cpp deleted file mode 100644 index 5c6ef18..0000000 --- a/src/HAL/AVR/fastio.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Fast I/O for extended pins - */ - -#ifdef __AVR__ - -#include "fastio.h" - -#ifdef FASTIO_EXT_START - -#include "../shared/Marduino.h" - -#define _IS_EXT(P) WITHIN(P, FASTIO_EXT_START, FASTIO_EXT_END) - -void extDigitalWrite(const int8_t pin, const uint8_t state) { - #define _WCASE(N) case N: WRITE(N, state); break - switch (pin) { - default: digitalWrite(pin, state); - #if _IS_EXT(70) - _WCASE(70); - #endif - #if _IS_EXT(71) - _WCASE(71); - #endif - #if _IS_EXT(72) - _WCASE(72); - #endif - #if _IS_EXT(73) - _WCASE(73); - #endif - #if _IS_EXT(74) - _WCASE(74); - #endif - #if _IS_EXT(75) - _WCASE(75); - #endif - #if _IS_EXT(76) - _WCASE(76); - #endif - #if _IS_EXT(77) - _WCASE(77); - #endif - #if _IS_EXT(78) - _WCASE(78); - #endif - #if _IS_EXT(79) - _WCASE(79); - #endif - #if _IS_EXT(80) - _WCASE(80); - #endif - #if _IS_EXT(81) - _WCASE(81); - #endif - #if _IS_EXT(82) - _WCASE(82); - #endif - #if _IS_EXT(83) - _WCASE(83); - #endif - #if _IS_EXT(84) - _WCASE(84); - #endif - #if _IS_EXT(85) - _WCASE(85); - #endif - #if _IS_EXT(86) - _WCASE(86); - #endif - #if _IS_EXT(87) - _WCASE(87); - #endif - #if _IS_EXT(88) - _WCASE(88); - #endif - #if _IS_EXT(89) - _WCASE(89); - #endif - #if _IS_EXT(90) - _WCASE(90); - #endif - #if _IS_EXT(91) - _WCASE(91); - #endif - #if _IS_EXT(92) - _WCASE(92); - #endif - #if _IS_EXT(93) - _WCASE(93); - #endif - #if _IS_EXT(94) - _WCASE(94); - #endif - #if _IS_EXT(95) - _WCASE(95); - #endif - #if _IS_EXT(96) - _WCASE(96); - #endif - #if _IS_EXT(97) - _WCASE(97); - #endif - #if _IS_EXT(98) - _WCASE(98); - #endif - #if _IS_EXT(99) - _WCASE(99); - #endif - #if _IS_EXT(100) - _WCASE(100); - #endif - } -} - -uint8_t extDigitalRead(const int8_t pin) { - #define _RCASE(N) case N: return READ(N) - switch (pin) { - default: return digitalRead(pin); - #if _IS_EXT(70) - _RCASE(70); - #endif - #if _IS_EXT(71) - _RCASE(71); - #endif - #if _IS_EXT(72) - _RCASE(72); - #endif - #if _IS_EXT(73) - _RCASE(73); - #endif - #if _IS_EXT(74) - _RCASE(74); - #endif - #if _IS_EXT(75) - _RCASE(75); - #endif - #if _IS_EXT(76) - _RCASE(76); - #endif - #if _IS_EXT(77) - _RCASE(77); - #endif - #if _IS_EXT(78) - _RCASE(78); - #endif - #if _IS_EXT(79) - _RCASE(79); - #endif - #if _IS_EXT(80) - _RCASE(80); - #endif - #if _IS_EXT(81) - _RCASE(81); - #endif - #if _IS_EXT(82) - _RCASE(82); - #endif - #if _IS_EXT(83) - _RCASE(83); - #endif - #if _IS_EXT(84) - _RCASE(84); - #endif - #if _IS_EXT(85) - _RCASE(85); - #endif - #if _IS_EXT(86) - _RCASE(86); - #endif - #if _IS_EXT(87) - _RCASE(87); - #endif - #if _IS_EXT(88) - _RCASE(88); - #endif - #if _IS_EXT(89) - _RCASE(89); - #endif - #if _IS_EXT(90) - _RCASE(90); - #endif - #if _IS_EXT(91) - _RCASE(91); - #endif - #if _IS_EXT(92) - _RCASE(92); - #endif - #if _IS_EXT(93) - _RCASE(93); - #endif - #if _IS_EXT(94) - _RCASE(94); - #endif - #if _IS_EXT(95) - _RCASE(95); - #endif - #if _IS_EXT(96) - _RCASE(96); - #endif - #if _IS_EXT(97) - _RCASE(97); - #endif - #if _IS_EXT(98) - _RCASE(98); - #endif - #if _IS_EXT(99) - _RCASE(99); - #endif - #if _IS_EXT(100) - _RCASE(100); - #endif - } -} - -#if 0 -/** - * Set Timer 5 PWM frequency in Hz, from 3.8Hz up to ~16MHz - * with a minimum resolution of 100 steps. - * - * DC values -1.0 to 1.0. Negative duty cycle inverts the pulse. - */ -uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb, const float dcc) { - float count = 0; - if (hz > 0 && (dca || dcb || dcc)) { - count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq. - uint16_t prescaler; // Range of 30.5Hz (65535) 64.5kHz (>31) - - if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); } - else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); } - else if (count >= 255. * 8.) { prescaler = 64; SET_CS(5, PRESCALER_64); } - else if (count >= 255.) { prescaler = 8; SET_CS(5, PRESCALER_8); } - else { prescaler = 1; SET_CS(5, PRESCALER_1); } - - count /= float(prescaler); - const float pwm_top = round(count); // Get the rounded count - - ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP - OCR5A = pwm_top * ABS(dca); // Update and scale DCs - OCR5B = pwm_top * ABS(dcb); - OCR5C = pwm_top * ABS(dcc); - _SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes - _SET_COM(5, B, dcb ? (dcb < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); - _SET_COM(5, C, dcc ? (dcc < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); - - SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP - - //SERIAL_ECHOLNPGM("Timer 5 Settings:"); - //SERIAL_ECHOLNPGM(" Prescaler=", prescaler); - //SERIAL_ECHOLNPGM(" TOP=", ICR5); - //SERIAL_ECHOLNPGM(" OCR5A=", OCR5A); - //SERIAL_ECHOLNPGM(" OCR5B=", OCR5B); - //SERIAL_ECHOLNPGM(" OCR5C=", OCR5C); - } - else { - // Restore the default for Timer 5 - SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct) - SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing - SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250kHz - OCR5A = OCR5B = OCR5C = 0; - } - return round(count); -} -#endif - -#endif // FASTIO_EXT_START -#endif // __AVR__ diff --git a/src/HAL/AVR/fastio.h b/src/HAL/AVR/fastio.h deleted file mode 100644 index 51d3b31..0000000 --- a/src/HAL/AVR/fastio.h +++ /dev/null @@ -1,350 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for AVR - * Use direct port manipulation to save scads of processor time. - * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. - */ - -#include - -#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__) - #define AVR_AT90USB1286_FAMILY 1 -#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) - #define AVR_ATmega1284_FAMILY 1 -#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - #define AVR_ATmega2560_FAMILY 1 -#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) - #define AVR_ATmega2561_FAMILY 1 -#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) - #define AVR_ATmega328_FAMILY 1 -#endif - -/** - * Include Ports and Functions - */ -#if AVR_ATmega328_FAMILY - #include "fastio/fastio_168.h" -#elif AVR_ATmega1284_FAMILY - #include "fastio/fastio_644.h" -#elif AVR_ATmega2560_FAMILY - #include "fastio/fastio_1280.h" -#elif AVR_AT90USB1286_FAMILY - #include "fastio/fastio_AT90USB.h" -#elif AVR_ATmega2561_FAMILY - #include "fastio/fastio_1281.h" -#else - #error "No FastIO definition for the selected AVR Board." -#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 https://gcc.gnu.org/onlinedocs/cpp/Stringification.html - */ - -#define _READ(IO) TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN) - -#define _WRITE_NC(IO,V) do{ \ - if (V) SBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \ - else CBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \ -}while(0) - -#define _WRITE_C(IO,V) do{ \ - uint8_t port_bits = DIO ## IO ## _WPORT; /* Get a mask from the current port bits */ \ - if (V) port_bits = ~port_bits; /* For setting bits, invert the mask */ \ - DIO ## IO ## _RPORT = port_bits & _BV(DIO ## IO ## _PIN); /* Atomically toggle the output port bits */ \ -}while(0) - -#define _WRITE(IO,V) do{ if (&(DIO ## IO ## _RPORT) < (uint8_t*)0x100) _WRITE_NC(IO,V); else _WRITE_C(IO,V); }while(0) - -#define _TOGGLE(IO) (DIO ## IO ## _RPORT = _BV(DIO ## IO ## _PIN)) - -#define _SET_INPUT(IO) CBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN) -#define _SET_OUTPUT(IO) SBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN) - -#define _IS_INPUT(IO) !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN) -#define _IS_OUTPUT(IO) TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN) - -// digitalRead/Write wrappers -#ifdef FASTIO_EXT_START - void extDigitalWrite(const int8_t pin, const uint8_t state); - uint8_t extDigitalRead(const int8_t pin); -#else - #define extDigitalWrite(IO,V) digitalWrite(IO,V) - #define extDigitalRead(IO) digitalRead(IO) -#endif - -#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_INPUT_PULLDOWN SET_INPUT -#define SET_OUTPUT(IO) _SET_OUTPUT(IO) -#define SET_PWM SET_OUTPUT - -#define IS_INPUT(IO) _IS_INPUT(IO) -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -/** - * Timer and Interrupt Control - */ - -// Waveform Generation Modes -enum WaveGenMode : uint8_t { - 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 -}; - -// Wavefore Generation Modes (Timer 2 only) -enum WaveGenMode2 : uint8_t { - WGM2_NORMAL, // 0 - WGM2_PWM_PC, // 1 - WGM2_CTC_OCR2A, // 2 - WGM2_FAST_PWM, // 3 - WGM2_reserved_1, // 4 - WGM2_PWM_PC_OCR2A, // 5 - WGM2_reserved_2, // 6 - WGM2_FAST_PWM_OCR2A, // 7 -}; - -// Compare Modes -enum CompareMode : uint8_t { - 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 -}; - -// Clock Sources -enum ClockSource : uint8_t { - 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 -}; - -// Clock Sources (Timer 2 only) -enum ClockSource2 : uint8_t { - 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 -}; - -// Get interrupt bits in an orderly way -// Ex: cs = GET_CS(0); coma1 = GET_COM(A,1); -#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 -// Ex: SET_WGM(5,CTC_ICRn); -#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 -// Ex: SET_CS3(PRESCALER_64); -#ifdef TCCR2 - #define HAS_TCCR2 1 -#endif -#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) -#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) - -#if HAS_TCCR2 - #define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20)) - #define SET_CS2(V) _SET_CS2(CS2_##V) -#else - #define _SET_CS2(V) _SET_CS(2,V) - #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 -// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET); -#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 -// Ex: SET_ICNC(2,1) -#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 -// Ex: SET_ICES(5,0) -#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 -// Ex: SET_FOC(3,A,1) -#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) - -#if 0 - -/** - * PWM availability macros - */ - -// Determine which hardware PWMs are already in use -#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 || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN) -#if PIN_EXISTS(CONTROLLER_FAN) - #define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN) -#else - #define PWM_CHK_FAN_B(P) _PWM_CHK_FAN_B(P) -#endif - -#if ANY_PIN(FAN, FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FAN7) - #if PIN_EXISTS(FAN7) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN || P == FAN6_PIN || P == FAN7_PIN) - #elif PIN_EXISTS(FAN6) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN || P == FAN6_PIN) - #elif PIN_EXISTS(FAN5) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN) - #elif PIN_EXISTS(FAN4) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN) - #elif PIN_EXISTS(FAN3) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN) - #elif PIN_EXISTS(FAN2) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN) - #elif PIN_EXISTS(FAN1) - #define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN) - #else - #define PWM_CHK_FAN_A(P) (P == FAN0_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 - -#ifdef 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)) - -#endif // PWM_CHK is not used in Marlin - -// 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_PIN(P) ((P >= 2 && P <= 10) || P == 13 || P == 44 || P == 45 || P == 46) -#elif AVR_ATmega2561_FAMILY - #define PWM_PIN(P) ((P >= 2 && P <= 6) || P == 9) -#elif AVR_ATmega1284_FAMILY - #define PWM_PIN(P) (P == 3 || P == 4 || P == 14 || P == 15) -#elif AVR_AT90USB1286_FAMILY - #define PWM_PIN(P) (P == 0 || P == 1 || P == 14 || P == 15 || P == 16 || P == 24) -#elif AVR_ATmega328_FAMILY - #define PWM_PIN(P) (P == 3 || P == 5 || P == 6 || P == 11) -#else - #error "unknown CPU" -#endif diff --git a/src/HAL/AVR/fastio/fastio_1280.h b/src/HAL/AVR/fastio/fastio_1280.h deleted file mode 100644 index f482f82..0000000 --- a/src/HAL/AVR/fastio/fastio_1280.h +++ /dev/null @@ -1,1114 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin mapping for the 1280 and 2560 - * - * Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 | 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100 - * Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx - * Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 73 75 76 77 74 xx xx xx xx xx - */ - -#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 nullptr - -#define DIO1_PIN PINE1 -#define DIO1_RPORT PINE -#define DIO1_WPORT PORTE -#define DIO1_DDR DDRE -#define DIO1_PWM nullptr - -#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 nullptr - -#define DIO12_PIN PINB6 -#define DIO12_RPORT PINB -#define DIO12_WPORT PORTB -#define DIO12_DDR DDRB -#define DIO12_PWM nullptr - -#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 nullptr - -#define DIO15_PIN PINJ0 -#define DIO15_RPORT PINJ -#define DIO15_WPORT PORTJ -#define DIO15_DDR DDRJ -#define DIO15_PWM nullptr - -#define DIO16_PIN PINH1 -#define DIO16_RPORT PINH -#define DIO16_WPORT PORTH -#define DIO16_DDR DDRH -#define DIO16_PWM nullptr - -#define DIO17_PIN PINH0 -#define DIO17_RPORT PINH -#define DIO17_WPORT PORTH -#define DIO17_DDR DDRH -#define DIO17_PWM nullptr - -#define DIO18_PIN PIND3 -#define DIO18_RPORT PIND -#define DIO18_WPORT PORTD -#define DIO18_DDR DDRD -#define DIO18_PWM nullptr - -#define DIO19_PIN PIND2 -#define DIO19_RPORT PIND -#define DIO19_WPORT PORTD -#define DIO19_DDR DDRD -#define DIO19_PWM nullptr - -#define DIO20_PIN PIND1 -#define DIO20_RPORT PIND -#define DIO20_WPORT PORTD -#define DIO20_DDR DDRD -#define DIO20_PWM nullptr - -#define DIO21_PIN PIND0 -#define DIO21_RPORT PIND -#define DIO21_WPORT PORTD -#define DIO21_DDR DDRD -#define DIO21_PWM nullptr - -#define DIO22_PIN PINA0 -#define DIO22_RPORT PINA -#define DIO22_WPORT PORTA -#define DIO22_DDR DDRA -#define DIO22_PWM nullptr - -#define DIO23_PIN PINA1 -#define DIO23_RPORT PINA -#define DIO23_WPORT PORTA -#define DIO23_DDR DDRA -#define DIO23_PWM nullptr - -#define DIO24_PIN PINA2 -#define DIO24_RPORT PINA -#define DIO24_WPORT PORTA -#define DIO24_DDR DDRA -#define DIO24_PWM nullptr - -#define DIO25_PIN PINA3 -#define DIO25_RPORT PINA -#define DIO25_WPORT PORTA -#define DIO25_DDR DDRA -#define DIO25_PWM nullptr - -#define DIO26_PIN PINA4 -#define DIO26_RPORT PINA -#define DIO26_WPORT PORTA -#define DIO26_DDR DDRA -#define DIO26_PWM nullptr - -#define DIO27_PIN PINA5 -#define DIO27_RPORT PINA -#define DIO27_WPORT PORTA -#define DIO27_DDR DDRA -#define DIO27_PWM nullptr - -#define DIO28_PIN PINA6 -#define DIO28_RPORT PINA -#define DIO28_WPORT PORTA -#define DIO28_DDR DDRA -#define DIO28_PWM nullptr - -#define DIO29_PIN PINA7 -#define DIO29_RPORT PINA -#define DIO29_WPORT PORTA -#define DIO29_DDR DDRA -#define DIO29_PWM nullptr - -#define DIO30_PIN PINC7 -#define DIO30_RPORT PINC -#define DIO30_WPORT PORTC -#define DIO30_DDR DDRC -#define DIO30_PWM nullptr - -#define DIO31_PIN PINC6 -#define DIO31_RPORT PINC -#define DIO31_WPORT PORTC -#define DIO31_DDR DDRC -#define DIO31_PWM nullptr - -#define DIO32_PIN PINC5 -#define DIO32_RPORT PINC -#define DIO32_WPORT PORTC -#define DIO32_DDR DDRC -#define DIO32_PWM nullptr - -#define DIO33_PIN PINC4 -#define DIO33_RPORT PINC -#define DIO33_WPORT PORTC -#define DIO33_DDR DDRC -#define DIO33_PWM nullptr - -#define DIO34_PIN PINC3 -#define DIO34_RPORT PINC -#define DIO34_WPORT PORTC -#define DIO34_DDR DDRC -#define DIO34_PWM nullptr - -#define DIO35_PIN PINC2 -#define DIO35_RPORT PINC -#define DIO35_WPORT PORTC -#define DIO35_DDR DDRC -#define DIO35_PWM nullptr - -#define DIO36_PIN PINC1 -#define DIO36_RPORT PINC -#define DIO36_WPORT PORTC -#define DIO36_DDR DDRC -#define DIO36_PWM nullptr - -#define DIO37_PIN PINC0 -#define DIO37_RPORT PINC -#define DIO37_WPORT PORTC -#define DIO37_DDR DDRC -#define DIO37_PWM nullptr - -#define DIO38_PIN PIND7 -#define DIO38_RPORT PIND -#define DIO38_WPORT PORTD -#define DIO38_DDR DDRD -#define DIO38_PWM nullptr - -#define DIO39_PIN PING2 -#define DIO39_RPORT PING -#define DIO39_WPORT PORTG -#define DIO39_DDR DDRG -#define DIO39_PWM nullptr - -#define DIO40_PIN PING1 -#define DIO40_RPORT PING -#define DIO40_WPORT PORTG -#define DIO40_DDR DDRG -#define DIO40_PWM nullptr - -#define DIO41_PIN PING0 -#define DIO41_RPORT PING -#define DIO41_WPORT PORTG -#define DIO41_DDR DDRG -#define DIO41_PWM nullptr - -#define DIO42_PIN PINL7 -#define DIO42_RPORT PINL -#define DIO42_WPORT PORTL -#define DIO42_DDR DDRL -#define DIO42_PWM nullptr - -#define DIO43_PIN PINL6 -#define DIO43_RPORT PINL -#define DIO43_WPORT PORTL -#define DIO43_DDR DDRL -#define DIO43_PWM nullptr - -#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 nullptr - -#define DIO48_PIN PINL1 -#define DIO48_RPORT PINL -#define DIO48_WPORT PORTL -#define DIO48_DDR DDRL -#define DIO48_PWM nullptr - -#define DIO49_PIN PINL0 -#define DIO49_RPORT PINL -#define DIO49_WPORT PORTL -#define DIO49_DDR DDRL -#define DIO49_PWM nullptr - -#define DIO50_PIN PINB3 -#define DIO50_RPORT PINB -#define DIO50_WPORT PORTB -#define DIO50_DDR DDRB -#define DIO50_PWM nullptr - -#define DIO51_PIN PINB2 -#define DIO51_RPORT PINB -#define DIO51_WPORT PORTB -#define DIO51_DDR DDRB -#define DIO51_PWM nullptr - -#define DIO52_PIN PINB1 -#define DIO52_RPORT PINB -#define DIO52_WPORT PORTB -#define DIO52_DDR DDRB -#define DIO52_PWM nullptr - -#define DIO53_PIN PINB0 -#define DIO53_RPORT PINB -#define DIO53_WPORT PORTB -#define DIO53_DDR DDRB -#define DIO53_PWM nullptr - -#define DIO54_PIN PINF0 -#define DIO54_RPORT PINF -#define DIO54_WPORT PORTF -#define DIO54_DDR DDRF -#define DIO54_PWM nullptr - -#define DIO55_PIN PINF1 -#define DIO55_RPORT PINF -#define DIO55_WPORT PORTF -#define DIO55_DDR DDRF -#define DIO55_PWM nullptr - -#define DIO56_PIN PINF2 -#define DIO56_RPORT PINF -#define DIO56_WPORT PORTF -#define DIO56_DDR DDRF -#define DIO56_PWM nullptr - -#define DIO57_PIN PINF3 -#define DIO57_RPORT PINF -#define DIO57_WPORT PORTF -#define DIO57_DDR DDRF -#define DIO57_PWM nullptr - -#define DIO58_PIN PINF4 -#define DIO58_RPORT PINF -#define DIO58_WPORT PORTF -#define DIO58_DDR DDRF -#define DIO58_PWM nullptr - -#define DIO59_PIN PINF5 -#define DIO59_RPORT PINF -#define DIO59_WPORT PORTF -#define DIO59_DDR DDRF -#define DIO59_PWM nullptr - -#define DIO60_PIN PINF6 -#define DIO60_RPORT PINF -#define DIO60_WPORT PORTF -#define DIO60_DDR DDRF -#define DIO60_PWM nullptr - -#define DIO61_PIN PINF7 -#define DIO61_RPORT PINF -#define DIO61_WPORT PORTF -#define DIO61_DDR DDRF -#define DIO61_PWM nullptr - -#define DIO62_PIN PINK0 -#define DIO62_RPORT PINK -#define DIO62_WPORT PORTK -#define DIO62_DDR DDRK -#define DIO62_PWM nullptr - -#define DIO63_PIN PINK1 -#define DIO63_RPORT PINK -#define DIO63_WPORT PORTK -#define DIO63_DDR DDRK -#define DIO63_PWM nullptr - -#define DIO64_PIN PINK2 -#define DIO64_RPORT PINK -#define DIO64_WPORT PORTK -#define DIO64_DDR DDRK -#define DIO64_PWM nullptr - -#define DIO65_PIN PINK3 -#define DIO65_RPORT PINK -#define DIO65_WPORT PORTK -#define DIO65_DDR DDRK -#define DIO65_PWM nullptr - -#define DIO66_PIN PINK4 -#define DIO66_RPORT PINK -#define DIO66_WPORT PORTK -#define DIO66_DDR DDRK -#define DIO66_PWM nullptr - -#define DIO67_PIN PINK5 -#define DIO67_RPORT PINK -#define DIO67_WPORT PORTK -#define DIO67_DDR DDRK -#define DIO67_PWM nullptr - -#define DIO68_PIN PINK6 -#define DIO68_RPORT PINK -#define DIO68_WPORT PORTK -#define DIO68_DDR DDRK -#define DIO68_PWM nullptr - -#define DIO69_PIN PINK7 -#define DIO69_RPORT PINK -#define DIO69_WPORT PORTK -#define DIO69_DDR DDRK -#define DIO69_PWM nullptr - -//#define FASTIO_EXT_START 70 -//#define FASTIO_EXT_END 85 - -#define DIO70_PIN PING4 -#define DIO70_RPORT PING -#define DIO70_WPORT PORTG -#define DIO70_DDR DDRG -#define DIO70_PWM nullptr - -#define DIO71_PIN PING3 -#define DIO71_RPORT PING -#define DIO71_WPORT PORTG -#define DIO71_DDR DDRG -#define DIO71_PWM nullptr - -#define DIO72_PIN PINJ2 -#define DIO72_RPORT PINJ -#define DIO72_WPORT PORTJ -#define DIO72_DDR DDRJ -#define DIO72_PWM nullptr - -#define DIO73_PIN PINJ3 -#define DIO73_RPORT PINJ -#define DIO73_WPORT PORTJ -#define DIO73_DDR DDRJ -#define DIO73_PWM nullptr - -#define DIO74_PIN PINJ7 -#define DIO74_RPORT PINJ -#define DIO74_WPORT PORTJ -#define DIO74_DDR DDRJ -#define DIO74_PWM nullptr - -#define DIO75_PIN PINJ4 -#define DIO75_RPORT PINJ -#define DIO75_WPORT PORTJ -#define DIO75_DDR DDRJ -#define DIO75_PWM nullptr - -#define DIO76_PIN PINJ5 -#define DIO76_RPORT PINJ -#define DIO76_WPORT PORTJ -#define DIO76_DDR DDRJ -#define DIO76_PWM nullptr - -#define DIO77_PIN PINJ6 -#define DIO77_RPORT PINJ -#define DIO77_WPORT PORTJ -#define DIO77_DDR DDRJ -#define DIO77_PWM nullptr - -#define DIO78_PIN PINE2 -#define DIO78_RPORT PINE -#define DIO78_WPORT PORTE -#define DIO78_DDR DDRE -#define DIO78_PWM nullptr - -#define DIO79_PIN PINE6 -#define DIO79_RPORT PINE -#define DIO79_WPORT PORTE -#define DIO79_DDR DDRE -#define DIO79_PWM nullptr - -#define DIO80_PIN PINE7 -#define DIO80_RPORT PINE -#define DIO80_WPORT PORTE -#define DIO80_DDR DDRE -#define DIO80_PWM nullptr - -#define DIO81_PIN PIND4 -#define DIO81_RPORT PIND -#define DIO81_WPORT PORTD -#define DIO81_DDR DDRD -#define DIO81_PWM nullptr - -#define DIO82_PIN PIND5 -#define DIO82_RPORT PIND -#define DIO82_WPORT PORTD -#define DIO82_DDR DDRD -#define DIO82_PWM nullptr - -#define DIO83_PIN PIND6 -#define DIO83_RPORT PIND -#define DIO83_WPORT PORTD -#define DIO83_DDR DDRD -#define DIO83_PWM nullptr - -#define DIO84_PIN PINH2 -#define DIO84_RPORT PINH -#define DIO84_WPORT PORTH -#define DIO84_DDR DDRH -#define DIO84_PWM nullptr - -#define DIO85_PIN PINH7 -#define DIO85_RPORT PINH -#define DIO85_WPORT PORTH -#define DIO85_DDR DDRH -#define DIO85_PWM nullptr - -#undef PA0 -#define PA0_PIN PINA0 -#define PA0_RPORT PINA -#define PA0_WPORT PORTA -#define PA0_DDR DDRA -#define PA0_PWM nullptr -#undef PA1 -#define PA1_PIN PINA1 -#define PA1_RPORT PINA -#define PA1_WPORT PORTA -#define PA1_DDR DDRA -#define PA1_PWM nullptr -#undef PA2 -#define PA2_PIN PINA2 -#define PA2_RPORT PINA -#define PA2_WPORT PORTA -#define PA2_DDR DDRA -#define PA2_PWM nullptr -#undef PA3 -#define PA3_PIN PINA3 -#define PA3_RPORT PINA -#define PA3_WPORT PORTA -#define PA3_DDR DDRA -#define PA3_PWM nullptr -#undef PA4 -#define PA4_PIN PINA4 -#define PA4_RPORT PINA -#define PA4_WPORT PORTA -#define PA4_DDR DDRA -#define PA4_PWM nullptr -#undef PA5 -#define PA5_PIN PINA5 -#define PA5_RPORT PINA -#define PA5_WPORT PORTA -#define PA5_DDR DDRA -#define PA5_PWM nullptr -#undef PA6 -#define PA6_PIN PINA6 -#define PA6_RPORT PINA -#define PA6_WPORT PORTA -#define PA6_DDR DDRA -#define PA6_PWM nullptr -#undef PA7 -#define PA7_PIN PINA7 -#define PA7_RPORT PINA -#define PA7_WPORT PORTA -#define PA7_DDR DDRA -#define PA7_PWM nullptr - -#undef PB0 -#define PB0_PIN PINB0 -#define PB0_RPORT PINB -#define PB0_WPORT PORTB -#define PB0_DDR DDRB -#define PB0_PWM nullptr -#undef PB1 -#define PB1_PIN PINB1 -#define PB1_RPORT PINB -#define PB1_WPORT PORTB -#define PB1_DDR DDRB -#define PB1_PWM nullptr -#undef PB2 -#define PB2_PIN PINB2 -#define PB2_RPORT PINB -#define PB2_WPORT PORTB -#define PB2_DDR DDRB -#define PB2_PWM nullptr -#undef PB3 -#define PB3_PIN PINB3 -#define PB3_RPORT PINB -#define PB3_WPORT PORTB -#define PB3_DDR DDRB -#define PB3_PWM nullptr -#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 nullptr -#undef PB6 -#define PB6_PIN PINB6 -#define PB6_RPORT PINB -#define PB6_WPORT PORTB -#define PB6_DDR DDRB -#define PB6_PWM nullptr -#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 nullptr -#undef PC1 -#define PC1_PIN PINC1 -#define PC1_RPORT PINC -#define PC1_WPORT PORTC -#define PC1_DDR DDRC -#define PC1_PWM nullptr -#undef PC2 -#define PC2_PIN PINC2 -#define PC2_RPORT PINC -#define PC2_WPORT PORTC -#define PC2_DDR DDRC -#define PC2_PWM nullptr -#undef PC3 -#define PC3_PIN PINC3 -#define PC3_RPORT PINC -#define PC3_WPORT PORTC -#define PC3_DDR DDRC -#define PC3_PWM nullptr -#undef PC4 -#define PC4_PIN PINC4 -#define PC4_RPORT PINC -#define PC4_WPORT PORTC -#define PC4_DDR DDRC -#define PC4_PWM nullptr -#undef PC5 -#define PC5_PIN PINC5 -#define PC5_RPORT PINC -#define PC5_WPORT PORTC -#define PC5_DDR DDRC -#define PC5_PWM nullptr -#undef PC6 -#define PC6_PIN PINC6 -#define PC6_RPORT PINC -#define PC6_WPORT PORTC -#define PC6_DDR DDRC -#define PC6_PWM nullptr -#undef PC7 -#define PC7_PIN PINC7 -#define PC7_RPORT PINC -#define PC7_WPORT PORTC -#define PC7_DDR DDRC -#define PC7_PWM nullptr - -#undef PD0 -#define PD0_PIN PIND0 -#define PD0_RPORT PIND -#define PD0_WPORT PORTD -#define PD0_DDR DDRD -#define PD0_PWM nullptr -#undef PD1 -#define PD1_PIN PIND1 -#define PD1_RPORT PIND -#define PD1_WPORT PORTD -#define PD1_DDR DDRD -#define PD1_PWM nullptr -#undef PD2 -#define PD2_PIN PIND2 -#define PD2_RPORT PIND -#define PD2_WPORT PORTD -#define PD2_DDR DDRD -#define PD2_PWM nullptr -#undef PD3 -#define PD3_PIN PIND3 -#define PD3_RPORT PIND -#define PD3_WPORT PORTD -#define PD3_DDR DDRD -#define PD3_PWM nullptr -#undef PD4 -#define PD4_PIN PIND4 -#define PD4_RPORT PIND -#define PD4_WPORT PORTD -#define PD4_DDR DDRD -#define PD4_PWM nullptr -#undef PD5 -#define PD5_PIN PIND5 -#define PD5_RPORT PIND -#define PD5_WPORT PORTD -#define PD5_DDR DDRD -#define PD5_PWM nullptr -#undef PD6 -#define PD6_PIN PIND6 -#define PD6_RPORT PIND -#define PD6_WPORT PORTD -#define PD6_DDR DDRD -#define PD6_PWM nullptr -#undef PD7 -#define PD7_PIN PIND7 -#define PD7_RPORT PIND -#define PD7_WPORT PORTD -#define PD7_DDR DDRD -#define PD7_PWM nullptr - -#undef PE0 -#define PE0_PIN PINE0 -#define PE0_RPORT PINE -#define PE0_WPORT PORTE -#define PE0_DDR DDRE -#define PE0_PWM nullptr -#undef PE1 -#define PE1_PIN PINE1 -#define PE1_RPORT PINE -#define PE1_WPORT PORTE -#define PE1_DDR DDRE -#define PE1_PWM nullptr -#undef PE2 -#define PE2_PIN PINE2 -#define PE2_RPORT PINE -#define PE2_WPORT PORTE -#define PE2_DDR DDRE -#define PE2_PWM nullptr -#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 nullptr -#undef PE7 -#define PE7_PIN PINE7 -#define PE7_RPORT PINE -#define PE7_WPORT PORTE -#define PE7_DDR DDRE -#define PE7_PWM nullptr - -#undef PF0 -#define PF0_PIN PINF0 -#define PF0_RPORT PINF -#define PF0_WPORT PORTF -#define PF0_DDR DDRF -#define PF0_PWM nullptr -#undef PF1 -#define PF1_PIN PINF1 -#define PF1_RPORT PINF -#define PF1_WPORT PORTF -#define PF1_DDR DDRF -#define PF1_PWM nullptr -#undef PF2 -#define PF2_PIN PINF2 -#define PF2_RPORT PINF -#define PF2_WPORT PORTF -#define PF2_DDR DDRF -#define PF2_PWM nullptr -#undef PF3 -#define PF3_PIN PINF3 -#define PF3_RPORT PINF -#define PF3_WPORT PORTF -#define PF3_DDR DDRF -#define PF3_PWM nullptr -#undef PF4 -#define PF4_PIN PINF4 -#define PF4_RPORT PINF -#define PF4_WPORT PORTF -#define PF4_DDR DDRF -#define PF4_PWM nullptr -#undef PF5 -#define PF5_PIN PINF5 -#define PF5_RPORT PINF -#define PF5_WPORT PORTF -#define PF5_DDR DDRF -#define PF5_PWM nullptr -#undef PF6 -#define PF6_PIN PINF6 -#define PF6_RPORT PINF -#define PF6_WPORT PORTF -#define PF6_DDR DDRF -#define PF6_PWM nullptr -#undef PF7 -#define PF7_PIN PINF7 -#define PF7_RPORT PINF -#define PF7_WPORT PORTF -#define PF7_DDR DDRF -#define PF7_PWM nullptr - -#undef PG0 -#define PG0_PIN PING0 -#define PG0_RPORT PING -#define PG0_WPORT PORTG -#define PG0_DDR DDRG -#define PG0_PWM nullptr -#undef PG1 -#define PG1_PIN PING1 -#define PG1_RPORT PING -#define PG1_WPORT PORTG -#define PG1_DDR DDRG -#define PG1_PWM nullptr -#undef PG2 -#define PG2_PIN PING2 -#define PG2_RPORT PING -#define PG2_WPORT PORTG -#define PG2_DDR DDRG -#define PG2_PWM nullptr -#undef PG3 -#define PG3_PIN PING3 -#define PG3_RPORT PING -#define PG3_WPORT PORTG -#define PG3_DDR DDRG -#define PG3_PWM nullptr -#undef PG4 -#define PG4_PIN PING4 -#define PG4_RPORT PING -#define PG4_WPORT PORTG -#define PG4_DDR DDRG -#define PG4_PWM nullptr -#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 nullptr -#undef PH1 -#define PH1_PIN PINH1 -#define PH1_RPORT PINH -#define PH1_WPORT PORTH -#define PH1_DDR DDRH -#define PH1_PWM nullptr -#undef PH2 -#define PH2_PIN PINH2 -#define PH2_RPORT PINH -#define PH2_WPORT PORTH -#define PH2_DDR DDRH -#define PH2_PWM nullptr -#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 nullptr - -#undef PJ0 -#define PJ0_PIN PINJ0 -#define PJ0_RPORT PINJ -#define PJ0_WPORT PORTJ -#define PJ0_DDR DDRJ -#define PJ0_PWM nullptr -#undef PJ1 -#define PJ1_PIN PINJ1 -#define PJ1_RPORT PINJ -#define PJ1_WPORT PORTJ -#define PJ1_DDR DDRJ -#define PJ1_PWM nullptr -#undef PJ2 -#define PJ2_PIN PINJ2 -#define PJ2_RPORT PINJ -#define PJ2_WPORT PORTJ -#define PJ2_DDR DDRJ -#define PJ2_PWM nullptr -#undef PJ3 -#define PJ3_PIN PINJ3 -#define PJ3_RPORT PINJ -#define PJ3_WPORT PORTJ -#define PJ3_DDR DDRJ -#define PJ3_PWM nullptr -#undef PJ4 -#define PJ4_PIN PINJ4 -#define PJ4_RPORT PINJ -#define PJ4_WPORT PORTJ -#define PJ4_DDR DDRJ -#define PJ4_PWM nullptr -#undef PJ5 -#define PJ5_PIN PINJ5 -#define PJ5_RPORT PINJ -#define PJ5_WPORT PORTJ -#define PJ5_DDR DDRJ -#define PJ5_PWM nullptr -#undef PJ6 -#define PJ6_PIN PINJ6 -#define PJ6_RPORT PINJ -#define PJ6_WPORT PORTJ -#define PJ6_DDR DDRJ -#define PJ6_PWM nullptr -#undef PJ7 -#define PJ7_PIN PINJ7 -#define PJ7_RPORT PINJ -#define PJ7_WPORT PORTJ -#define PJ7_DDR DDRJ -#define PJ7_PWM nullptr - -#undef PK0 -#define PK0_PIN PINK0 -#define PK0_RPORT PINK -#define PK0_WPORT PORTK -#define PK0_DDR DDRK -#define PK0_PWM nullptr -#undef PK1 -#define PK1_PIN PINK1 -#define PK1_RPORT PINK -#define PK1_WPORT PORTK -#define PK1_DDR DDRK -#define PK1_PWM nullptr -#undef PK2 -#define PK2_PIN PINK2 -#define PK2_RPORT PINK -#define PK2_WPORT PORTK -#define PK2_DDR DDRK -#define PK2_PWM nullptr -#undef PK3 -#define PK3_PIN PINK3 -#define PK3_RPORT PINK -#define PK3_WPORT PORTK -#define PK3_DDR DDRK -#define PK3_PWM nullptr -#undef PK4 -#define PK4_PIN PINK4 -#define PK4_RPORT PINK -#define PK4_WPORT PORTK -#define PK4_DDR DDRK -#define PK4_PWM nullptr -#undef PK5 -#define PK5_PIN PINK5 -#define PK5_RPORT PINK -#define PK5_WPORT PORTK -#define PK5_DDR DDRK -#define PK5_PWM nullptr -#undef PK6 -#define PK6_PIN PINK6 -#define PK6_RPORT PINK -#define PK6_WPORT PORTK -#define PK6_DDR DDRK -#define PK6_PWM nullptr -#undef PK7 -#define PK7_PIN PINK7 -#define PK7_RPORT PINK -#define PK7_WPORT PORTK -#define PK7_DDR DDRK -#define PK7_PWM nullptr - -#undef PL0 -#define PL0_PIN PINL0 -#define PL0_RPORT PINL -#define PL0_WPORT PORTL -#define PL0_DDR DDRL -#define PL0_PWM nullptr -#undef PL1 -#define PL1_PIN PINL1 -#define PL1_RPORT PINL -#define PL1_WPORT PORTL -#define PL1_DDR DDRL -#define PL1_PWM nullptr -#undef PL2 -#define PL2_PIN PINL2 -#define PL2_RPORT PINL -#define PL2_WPORT PORTL -#define PL2_DDR DDRL -#define PL2_PWM nullptr -#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 nullptr -#undef PL7 -#define PL7_PIN PINL7 -#define PL7_RPORT PINL -#define PL7_WPORT PORTL -#define PL7_DDR DDRL -#define PL7_PWM nullptr diff --git a/src/HAL/AVR/fastio/fastio_1281.h b/src/HAL/AVR/fastio/fastio_1281.h deleted file mode 100644 index e0bc5e2..0000000 --- a/src/HAL/AVR/fastio/fastio_1281.h +++ /dev/null @@ -1,715 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin mapping for the 1281 and 2561 - * - * Logical Pin: 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 - */ - -#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 nullptr - -#define DIO1_PIN PINE1 -#define DIO1_RPORT PINE -#define DIO1_WPORT PORTE -#define DIO1_DDR DDRE -#define DIO1_PWM nullptr - -#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 nullptr - -#define DIO11_PIN PINB2 -#define DIO11_RPORT PINB -#define DIO11_WPORT PORTB -#define DIO11_DDR DDRB -#define DIO11_PWM nullptr - -#define DIO12_PIN PINB3 -#define DIO12_RPORT PINB -#define DIO12_WPORT PORTB -#define DIO12_DDR DDRB -#define DIO12_PWM nullptr - -#define DIO13_PIN PINE2 -#define DIO13_RPORT PINE -#define DIO13_WPORT PORTE -#define DIO13_DDR DDRE -#define DIO13_PWM nullptr - -#define DIO14_PIN PINE6 -#define DIO14_RPORT PINE -#define DIO14_WPORT PORTE -#define DIO14_DDR DDRE -#define DIO14_PWM nullptr - -#define DIO15_PIN PINE7 -#define DIO15_RPORT PINE -#define DIO15_WPORT PORTE -#define DIO15_DDR DDRE -#define DIO15_PWM nullptr - -#define DIO16_PIN PINB0 -#define DIO16_RPORT PINB -#define DIO16_WPORT PORTB -#define DIO16_DDR DDRB -#define DIO16_PWM nullptr - -#define DIO17_PIN PIND0 -#define DIO17_RPORT PIND -#define DIO17_WPORT PORTD -#define DIO17_DDR DDRD -#define DIO17_PWM nullptr - -#define DIO18_PIN PIND1 -#define DIO18_RPORT PIND -#define DIO18_WPORT PORTD -#define DIO18_DDR DDRD -#define DIO18_PWM nullptr - -#define DIO19_PIN PIND2 -#define DIO19_RPORT PIND -#define DIO19_WPORT PORTD -#define DIO19_DDR DDRD -#define DIO19_PWM nullptr - -#define DIO20_PIN PIND3 -#define DIO20_RPORT PIND -#define DIO20_WPORT PORTD -#define DIO20_DDR DDRD -#define DIO20_PWM nullptr - -#define DIO21_PIN PIND4 -#define DIO21_RPORT PIND -#define DIO21_WPORT PORTD -#define DIO21_DDR DDRD -#define DIO21_PWM nullptr - -#define DIO22_PIN PIND5 -#define DIO22_RPORT PIND -#define DIO22_WPORT PORTD -#define DIO22_DDR DDRD -#define DIO22_PWM nullptr - -#define DIO23_PIN PIND6 -#define DIO23_RPORT PIND -#define DIO23_WPORT PORTD -#define DIO23_DDR DDRD -#define DIO23_PWM nullptr - -#define DIO24_PIN PIND7 -#define DIO24_RPORT PIND -#define DIO24_WPORT PORTD -#define DIO24_DDR DDRD -#define DIO24_PWM nullptr - -#define DIO25_PIN PING0 -#define DIO25_RPORT PING -#define DIO25_WPORT PORTG -#define DIO25_DDR DDRG -#define DIO25_PWM nullptr - -#define DIO26_PIN PING1 -#define DIO26_RPORT PING -#define DIO26_WPORT PORTG -#define DIO26_DDR DDRG -#define DIO26_PWM nullptr - -#define DIO27_PIN PING2 -#define DIO27_RPORT PING -#define DIO27_WPORT PORTG -#define DIO27_DDR DDRG -#define DIO27_PWM nullptr - -#define DIO28_PIN PING3 -#define DIO28_RPORT PING -#define DIO28_WPORT PORTG -#define DIO28_DDR DDRG -#define DIO28_PWM nullptr - -#define DIO29_PIN PING4 -#define DIO29_RPORT PING -#define DIO29_WPORT PORTG -#define DIO29_DDR DDRG -#define DIO29_PWM nullptr - -#define DIO30_PIN PINC0 -#define DIO30_RPORT PINC -#define DIO30_WPORT PORTC -#define DIO30_DDR DDRC -#define DIO30_PWM nullptr - -#define DIO31_PIN PINC1 -#define DIO31_RPORT PINC -#define DIO31_WPORT PORTC -#define DIO31_DDR DDRC -#define DIO31_PWM nullptr - -#define DIO32_PIN PINC2 -#define DIO32_RPORT PINC -#define DIO32_WPORT PORTC -#define DIO32_DDR DDRC -#define DIO32_PWM nullptr - -#define DIO33_PIN PINC3 -#define DIO33_RPORT PINC -#define DIO33_WPORT PORTC -#define DIO33_DDR DDRC -#define DIO33_PWM nullptr - -#define DIO34_PIN PINC4 -#define DIO34_RPORT PINC -#define DIO34_WPORT PORTC -#define DIO34_DDR DDRC -#define DIO34_PWM nullptr - -#define DIO35_PIN PINC5 -#define DIO35_RPORT PINC -#define DIO35_WPORT PORTC -#define DIO35_DDR DDRC -#define DIO35_PWM nullptr - -#define DIO36_PIN PINC6 -#define DIO36_RPORT PINC -#define DIO36_WPORT PORTC -#define DIO36_DDR DDRC -#define DIO36_PWM nullptr - -#define DIO37_PIN PINC7 -#define DIO37_RPORT PINC -#define DIO37_WPORT PORTC -#define DIO37_DDR DDRC -#define DIO37_PWM nullptr - -#define DIO38_PIN PINA0 -#define DIO38_RPORT PINA -#define DIO38_WPORT PORTA -#define DIO38_DDR DDRA -#define DIO38_PWM nullptr - -#define DIO39_PIN PINA1 -#define DIO39_RPORT PINA -#define DIO39_WPORT PORTA -#define DIO39_DDR DDRA -#define DIO39_PWM nullptr - -#define DIO40_PIN PINA2 -#define DIO40_RPORT PINA -#define DIO40_WPORT PORTA -#define DIO40_DDR DDRA -#define DIO40_PWM nullptr - -#define DIO41_PIN PINA3 -#define DIO41_RPORT PINA -#define DIO41_WPORT PORTA -#define DIO41_DDR DDRA -#define DIO41_PWM nullptr - -#define DIO42_PIN PINA4 -#define DIO42_RPORT PINA -#define DIO42_WPORT PORTA -#define DIO42_DDR DDRA -#define DIO42_PWM nullptr - -#define DIO43_PIN PINA5 -#define DIO43_RPORT PINA -#define DIO43_WPORT PORTA -#define DIO43_DDR DDRA -#define DIO43_PWM nullptr - -#define DIO44_PIN PINA6 -#define DIO44_RPORT PINA -#define DIO44_WPORT PORTA -#define DIO44_DDR DDRA -#define DIO44_PWM nullptr - -#define DIO45_PIN PINA7 -#define DIO45_RPORT PINA -#define DIO45_WPORT PORTA -#define DIO45_DDR DDRA -#define DIO45_PWM nullptr - -#define DIO46_PIN PINF0 -#define DIO46_RPORT PINF -#define DIO46_WPORT PORTF -#define DIO46_DDR DDRF -#define DIO46_PWM nullptr - -#define DIO47_PIN PINF1 -#define DIO47_RPORT PINF -#define DIO47_WPORT PORTF -#define DIO47_DDR DDRF -#define DIO47_PWM nullptr - -#define DIO48_PIN PINF2 -#define DIO48_RPORT PINF -#define DIO48_WPORT PORTF -#define DIO48_DDR DDRF -#define DIO48_PWM nullptr - -#define DIO49_PIN PINF3 -#define DIO49_RPORT PINF -#define DIO49_WPORT PORTF -#define DIO49_DDR DDRF -#define DIO49_PWM nullptr - -#define DIO50_PIN PINF4 -#define DIO50_RPORT PINF -#define DIO50_WPORT PORTF -#define DIO50_DDR DDRF -#define DIO50_PWM nullptr - -#define DIO51_PIN PINF5 -#define DIO51_RPORT PINF -#define DIO51_WPORT PORTF -#define DIO51_DDR DDRF -#define DIO51_PWM nullptr - -#define DIO52_PIN PINF6 -#define DIO52_RPORT PINF -#define DIO52_WPORT PORTF -#define DIO52_DDR DDRF -#define DIO52_PWM nullptr - -#define DIO53_PIN PINF7 -#define DIO53_RPORT PINF -#define DIO53_WPORT PORTF -#define DIO53_DDR DDRF -#define DIO53_PWM nullptr - -#undef PA0 -#define PA0_PIN PINA0 -#define PA0_RPORT PINA -#define PA0_WPORT PORTA -#define PA0_DDR DDRA -#define PA0_PWM nullptr -#undef PA1 -#define PA1_PIN PINA1 -#define PA1_RPORT PINA -#define PA1_WPORT PORTA -#define PA1_DDR DDRA -#define PA1_PWM nullptr -#undef PA2 -#define PA2_PIN PINA2 -#define PA2_RPORT PINA -#define PA2_WPORT PORTA -#define PA2_DDR DDRA -#define PA2_PWM nullptr -#undef PA3 -#define PA3_PIN PINA3 -#define PA3_RPORT PINA -#define PA3_WPORT PORTA -#define PA3_DDR DDRA -#define PA3_PWM nullptr -#undef PA4 -#define PA4_PIN PINA4 -#define PA4_RPORT PINA -#define PA4_WPORT PORTA -#define PA4_DDR DDRA -#define PA4_PWM nullptr -#undef PA5 -#define PA5_PIN PINA5 -#define PA5_RPORT PINA -#define PA5_WPORT PORTA -#define PA5_DDR DDRA -#define PA5_PWM nullptr -#undef PA6 -#define PA6_PIN PINA6 -#define PA6_RPORT PINA -#define PA6_WPORT PORTA -#define PA6_DDR DDRA -#define PA6_PWM nullptr -#undef PA7 -#define PA7_PIN PINA7 -#define PA7_RPORT PINA -#define PA7_WPORT PORTA -#define PA7_DDR DDRA -#define PA7_PWM nullptr - -#undef PB0 -#define PB0_PIN PINB0 -#define PB0_RPORT PINB -#define PB0_WPORT PORTB -#define PB0_DDR DDRB -#define PB0_PWM nullptr -#undef PB1 -#define PB1_PIN PINB1 -#define PB1_RPORT PINB -#define PB1_WPORT PORTB -#define PB1_DDR DDRB -#define PB1_PWM nullptr -#undef PB2 -#define PB2_PIN PINB2 -#define PB2_RPORT PINB -#define PB2_WPORT PORTB -#define PB2_DDR DDRB -#define PB2_PWM nullptr -#undef PB3 -#define PB3_PIN PINB3 -#define PB3_RPORT PINB -#define PB3_WPORT PORTB -#define PB3_DDR DDRB -#define PB3_PWM nullptr -#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 nullptr -#undef PB6 -#define PB6_PIN PINB6 -#define PB6_RPORT PINB -#define PB6_WPORT PORTB -#define PB6_DDR DDRB -#define PB6_PWM nullptr -#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 nullptr -#undef PC1 -#define PC1_PIN PINC1 -#define PC1_RPORT PINC -#define PC1_WPORT PORTC -#define PC1_DDR DDRC -#define PC1_PWM nullptr -#undef PC2 -#define PC2_PIN PINC2 -#define PC2_RPORT PINC -#define PC2_WPORT PORTC -#define PC2_DDR DDRC -#define PC2_PWM nullptr -#undef PC3 -#define PC3_PIN PINC3 -#define PC3_RPORT PINC -#define PC3_WPORT PORTC -#define PC3_DDR DDRC -#define PC3_PWM nullptr -#undef PC4 -#define PC4_PIN PINC4 -#define PC4_RPORT PINC -#define PC4_WPORT PORTC -#define PC4_DDR DDRC -#define PC4_PWM nullptr -#undef PC5 -#define PC5_PIN PINC5 -#define PC5_RPORT PINC -#define PC5_WPORT PORTC -#define PC5_DDR DDRC -#define PC5_PWM nullptr -#undef PC6 -#define PC6_PIN PINC6 -#define PC6_RPORT PINC -#define PC6_WPORT PORTC -#define PC6_DDR DDRC -#define PC6_PWM nullptr -#undef PC7 -#define PC7_PIN PINC7 -#define PC7_RPORT PINC -#define PC7_WPORT PORTC -#define PC7_DDR DDRC -#define PC7_PWM nullptr - -#undef PD0 -#define PD0_PIN PIND0 -#define PD0_RPORT PIND -#define PD0_WPORT PORTD -#define PD0_DDR DDRD -#define PD0_PWM nullptr -#undef PD1 -#define PD1_PIN PIND1 -#define PD1_RPORT PIND -#define PD1_WPORT PORTD -#define PD1_DDR DDRD -#define PD1_PWM nullptr -#undef PD2 -#define PD2_PIN PIND2 -#define PD2_RPORT PIND -#define PD2_WPORT PORTD -#define PD2_DDR DDRD -#define PD2_PWM nullptr -#undef PD3 -#define PD3_PIN PIND3 -#define PD3_RPORT PIND -#define PD3_WPORT PORTD -#define PD3_DDR DDRD -#define PD3_PWM nullptr -#undef PD4 -#define PD4_PIN PIND4 -#define PD4_RPORT PIND -#define PD4_WPORT PORTD -#define PD4_DDR DDRD -#define PD4_PWM nullptr -#undef PD5 -#define PD5_PIN PIND5 -#define PD5_RPORT PIND -#define PD5_WPORT PORTD -#define PD5_DDR DDRD -#define PD5_PWM nullptr -#undef PD6 -#define PD6_PIN PIND6 -#define PD6_RPORT PIND -#define PD6_WPORT PORTD -#define PD6_DDR DDRD -#define PD6_PWM nullptr -#undef PD7 -#define PD7_PIN PIND7 -#define PD7_RPORT PIND -#define PD7_WPORT PORTD -#define PD7_DDR DDRD -#define PD7_PWM nullptr - -#undef PE0 -#define PE0_PIN PINE0 -#define PE0_RPORT PINE -#define PE0_WPORT PORTE -#define PE0_DDR DDRE -#define PE0_PWM nullptr -#undef PE1 -#define PE1_PIN PINE1 -#define PE1_RPORT PINE -#define PE1_WPORT PORTE -#define PE1_DDR DDRE -#define PE1_PWM nullptr -#undef PE2 -#define PE2_PIN PINE2 -#define PE2_RPORT PINE -#define PE2_WPORT PORTE -#define PE2_DDR DDRE -#define PE2_PWM nullptr -#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 nullptr -#undef PE7 -#define PE7_PIN PINE7 -#define PE7_RPORT PINE -#define PE7_WPORT PORTE -#define PE7_DDR DDRE -#define PE7_PWM nullptr - -#undef PF0 -#define PF0_PIN PINF0 -#define PF0_RPORT PINF -#define PF0_WPORT PORTF -#define PF0_DDR DDRF -#define PF0_PWM nullptr -#undef PF1 -#define PF1_PIN PINF1 -#define PF1_RPORT PINF -#define PF1_WPORT PORTF -#define PF1_DDR DDRF -#define PF1_PWM nullptr -#undef PF2 -#define PF2_PIN PINF2 -#define PF2_RPORT PINF -#define PF2_WPORT PORTF -#define PF2_DDR DDRF -#define PF2_PWM nullptr -#undef PF3 -#define PF3_PIN PINF3 -#define PF3_RPORT PINF -#define PF3_WPORT PORTF -#define PF3_DDR DDRF -#define PF3_PWM nullptr -#undef PF4 -#define PF4_PIN PINF4 -#define PF4_RPORT PINF -#define PF4_WPORT PORTF -#define PF4_DDR DDRF -#define PF4_PWM nullptr -#undef PF5 -#define PF5_PIN PINF5 -#define PF5_RPORT PINF -#define PF5_WPORT PORTF -#define PF5_DDR DDRF -#define PF5_PWM nullptr -#undef PF6 -#define PF6_PIN PINF6 -#define PF6_RPORT PINF -#define PF6_WPORT PORTF -#define PF6_DDR DDRF -#define PF6_PWM nullptr -#undef PF7 -#define PF7_PIN PINF7 -#define PF7_RPORT PINF -#define PF7_WPORT PORTF -#define PF7_DDR DDRF -#define PF7_PWM nullptr - -#undef PG0 -#define PG0_PIN PING0 -#define PG0_RPORT PING -#define PG0_WPORT PORTG -#define PG0_DDR DDRG -#define PG0_PWM nullptr -#undef PG1 -#define PG1_PIN PING1 -#define PG1_RPORT PING -#define PG1_WPORT PORTG -#define PG1_DDR DDRG -#define PG1_PWM nullptr -#undef PG2 -#define PG2_PIN PING2 -#define PG2_RPORT PING -#define PG2_WPORT PORTG -#define PG2_DDR DDRG -#define PG2_PWM nullptr -#undef PG3 -#define PG3_PIN PING3 -#define PG3_RPORT PING -#define PG3_WPORT PORTG -#define PG3_DDR DDRG -#define PG3_PWM nullptr -#undef PG4 -#define PG4_PIN PING4 -#define PG4_RPORT PING -#define PG4_WPORT PORTG -#define PG4_DDR DDRG -#define PG4_PWM nullptr -#undef PG5 -#define PG5_PIN PING5 -#define PG5_RPORT PING -#define PG5_WPORT PORTG -#define PG5_DDR DDRG -#define PG5_PWM &OCR0B diff --git a/src/HAL/AVR/fastio/fastio_168.h b/src/HAL/AVR/fastio/fastio_168.h deleted file mode 100644 index 8cfdd1e..0000000 --- a/src/HAL/AVR/fastio/fastio_168.h +++ /dev/null @@ -1,357 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin mapping for the 168, 328, and 328P - * - * Logical Pin: 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 - */ - -#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 nullptr - -#define DIO1_PIN PIND1 -#define DIO1_RPORT PIND -#define DIO1_WPORT PORTD -#define DIO1_DDR DDRD -#define DIO1_PWM nullptr - -#define DIO2_PIN PIND2 -#define DIO2_RPORT PIND -#define DIO2_WPORT PORTD -#define DIO2_DDR DDRD -#define DIO2_PWM nullptr - -#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 nullptr - -#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 nullptr - -#define DIO8_PIN PINB0 -#define DIO8_RPORT PINB -#define DIO8_WPORT PORTB -#define DIO8_DDR DDRB -#define DIO8_PWM nullptr - -#define DIO9_PIN PINB1 -#define DIO9_RPORT PINB -#define DIO9_WPORT PORTB -#define DIO9_DDR DDRB -#define DIO9_PWM nullptr - -#define DIO10_PIN PINB2 -#define DIO10_RPORT PINB -#define DIO10_WPORT PORTB -#define DIO10_DDR DDRB -#define DIO10_PWM nullptr - -#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 nullptr - -#define DIO13_PIN PINB5 -#define DIO13_RPORT PINB -#define DIO13_WPORT PORTB -#define DIO13_DDR DDRB -#define DIO13_PWM nullptr - -#define DIO14_PIN PINC0 -#define DIO14_RPORT PINC -#define DIO14_WPORT PORTC -#define DIO14_DDR DDRC -#define DIO14_PWM nullptr - -#define DIO15_PIN PINC1 -#define DIO15_RPORT PINC -#define DIO15_WPORT PORTC -#define DIO15_DDR DDRC -#define DIO15_PWM nullptr - -#define DIO16_PIN PINC2 -#define DIO16_RPORT PINC -#define DIO16_WPORT PORTC -#define DIO16_DDR DDRC -#define DIO16_PWM nullptr - -#define DIO17_PIN PINC3 -#define DIO17_RPORT PINC -#define DIO17_WPORT PORTC -#define DIO17_DDR DDRC -#define DIO17_PWM nullptr - -#define DIO18_PIN PINC4 -#define DIO18_RPORT PINC -#define DIO18_WPORT PORTC -#define DIO18_DDR DDRC -#define DIO18_PWM nullptr - -#define DIO19_PIN PINC5 -#define DIO19_RPORT PINC -#define DIO19_WPORT PORTC -#define DIO19_DDR DDRC -#define DIO19_PWM nullptr - -#define DIO20_PIN PINC6 -#define DIO20_RPORT PINC -#define DIO20_WPORT PORTC -#define DIO20_DDR DDRC -#define DIO20_PWM nullptr - -#define DIO21_PIN PINC7 -#define DIO21_RPORT PINC -#define DIO21_WPORT PORTC -#define DIO21_DDR DDRC -#define DIO21_PWM nullptr - -#undef PB0 -#define PB0_PIN PINB0 -#define PB0_RPORT PINB -#define PB0_WPORT PORTB -#define PB0_DDR DDRB -#define PB0_PWM nullptr - -#undef PB1 -#define PB1_PIN PINB1 -#define PB1_RPORT PINB -#define PB1_WPORT PORTB -#define PB1_DDR DDRB -#define PB1_PWM nullptr - -#undef PB2 -#define PB2_PIN PINB2 -#define PB2_RPORT PINB -#define PB2_WPORT PORTB -#define PB2_DDR DDRB -#define PB2_PWM nullptr - -#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 nullptr - -#undef PB5 -#define PB5_PIN PINB5 -#define PB5_RPORT PINB -#define PB5_WPORT PORTB -#define PB5_DDR DDRB -#define PB5_PWM nullptr - -#undef PB6 -#define PB6_PIN PINB6 -#define PB6_RPORT PINB -#define PB6_WPORT PORTB -#define PB6_DDR DDRB -#define PB6_PWM nullptr - -#undef PB7 -#define PB7_PIN PINB7 -#define PB7_RPORT PINB -#define PB7_WPORT PORTB -#define PB7_DDR DDRB -#define PB7_PWM nullptr - -#undef PC0 -#define PC0_PIN PINC0 -#define PC0_RPORT PINC -#define PC0_WPORT PORTC -#define PC0_DDR DDRC -#define PC0_PWM nullptr - -#undef PC1 -#define PC1_PIN PINC1 -#define PC1_RPORT PINC -#define PC1_WPORT PORTC -#define PC1_DDR DDRC -#define PC1_PWM nullptr - -#undef PC2 -#define PC2_PIN PINC2 -#define PC2_RPORT PINC -#define PC2_WPORT PORTC -#define PC2_DDR DDRC -#define PC2_PWM nullptr - -#undef PC3 -#define PC3_PIN PINC3 -#define PC3_RPORT PINC -#define PC3_WPORT PORTC -#define PC3_DDR DDRC -#define PC3_PWM nullptr - -#undef PC4 -#define PC4_PIN PINC4 -#define PC4_RPORT PINC -#define PC4_WPORT PORTC -#define PC4_DDR DDRC -#define PC4_PWM nullptr - -#undef PC5 -#define PC5_PIN PINC5 -#define PC5_RPORT PINC -#define PC5_WPORT PORTC -#define PC5_DDR DDRC -#define PC5_PWM nullptr - -#undef PC6 -#define PC6_PIN PINC6 -#define PC6_RPORT PINC -#define PC6_WPORT PORTC -#define PC6_DDR DDRC -#define PC6_PWM nullptr - -#undef PC7 -#define PC7_PIN PINC7 -#define PC7_RPORT PINC -#define PC7_WPORT PORTC -#define PC7_DDR DDRC -#define PC7_PWM nullptr - -#undef PD0 -#define PD0_PIN PIND0 -#define PD0_RPORT PIND -#define PD0_WPORT PORTD -#define PD0_DDR DDRD -#define PD0_PWM nullptr - -#undef PD1 -#define PD1_PIN PIND1 -#define PD1_RPORT PIND -#define PD1_WPORT PORTD -#define PD1_DDR DDRD -#define PD1_PWM nullptr - -#undef PD2 -#define PD2_PIN PIND2 -#define PD2_RPORT PIND -#define PD2_WPORT PORTD -#define PD2_DDR DDRD -#define PD2_PWM nullptr - -#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 nullptr - -#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 nullptr diff --git a/src/HAL/AVR/fastio/fastio_644.h b/src/HAL/AVR/fastio/fastio_644.h deleted file mode 100644 index f4a9427..0000000 --- a/src/HAL/AVR/fastio/fastio_644.h +++ /dev/null @@ -1,552 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin mapping for the 644, 644p, 644pa, and 1284p - * - * Logical Pin: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - * Port: B0 B1 B2 B3 B4 B5 B6 B7 D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 C2 C3 C4 C5 C6 C7 A7 A6 A5 A4 A3 A2 A1 A0 - */ - -/** 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 - * +--------+ - */ - -#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 nullptr - -#define DIO1_PIN PINB1 -#define DIO1_RPORT PINB -#define DIO1_WPORT PORTB -#define DIO1_DDR DDRB -#define DIO1_PWM nullptr - -#define DIO2_PIN PINB2 -#define DIO2_RPORT PINB -#define DIO2_WPORT PORTB -#define DIO2_DDR DDRB -#define DIO2_PWM nullptr - -#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 nullptr - -#define DIO6_PIN PINB6 -#define DIO6_RPORT PINB -#define DIO6_WPORT PORTB -#define DIO6_DDR DDRB -#define DIO6_PWM nullptr - -#define DIO7_PIN PINB7 -#define DIO7_RPORT PINB -#define DIO7_WPORT PORTB -#define DIO7_DDR DDRB -#define DIO7_PWM nullptr - -#define DIO8_PIN PIND0 -#define DIO8_RPORT PIND -#define DIO8_WPORT PORTD -#define DIO8_DDR DDRD -#define DIO8_PWM nullptr - -#define DIO9_PIN PIND1 -#define DIO9_RPORT PIND -#define DIO9_WPORT PORTD -#define DIO9_DDR DDRD -#define DIO9_PWM nullptr - -#define DIO10_PIN PIND2 -#define DIO10_RPORT PIND -#define DIO10_WPORT PORTD -#define DIO10_DDR DDRD -#define DIO10_PWM nullptr - -#define DIO11_PIN PIND3 -#define DIO11_RPORT PIND -#define DIO11_WPORT PORTD -#define DIO11_DDR DDRD -#define DIO11_PWM nullptr - -#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 nullptr - -#define DIO17_PIN PINC1 -#define DIO17_RPORT PINC -#define DIO17_WPORT PORTC -#define DIO17_DDR DDRC -#define DIO17_PWM nullptr - -#define DIO18_PIN PINC2 -#define DIO18_RPORT PINC -#define DIO18_WPORT PORTC -#define DIO18_DDR DDRC -#define DIO18_PWM nullptr - -#define DIO19_PIN PINC3 -#define DIO19_RPORT PINC -#define DIO19_WPORT PORTC -#define DIO19_DDR DDRC -#define DIO19_PWM nullptr - -#define DIO20_PIN PINC4 -#define DIO20_RPORT PINC -#define DIO20_WPORT PORTC -#define DIO20_DDR DDRC -#define DIO20_PWM nullptr - -#define DIO21_PIN PINC5 -#define DIO21_RPORT PINC -#define DIO21_WPORT PORTC -#define DIO21_DDR DDRC -#define DIO21_PWM nullptr - -#define DIO22_PIN PINC6 -#define DIO22_RPORT PINC -#define DIO22_WPORT PORTC -#define DIO22_DDR DDRC -#define DIO22_PWM nullptr - -#define DIO23_PIN PINC7 -#define DIO23_RPORT PINC -#define DIO23_WPORT PORTC -#define DIO23_DDR DDRC -#define DIO23_PWM nullptr - -#define DIO24_PIN PINA7 -#define DIO24_RPORT PINA -#define DIO24_WPORT PORTA -#define DIO24_DDR DDRA -#define DIO24_PWM nullptr - -#define DIO25_PIN PINA6 -#define DIO25_RPORT PINA -#define DIO25_WPORT PORTA -#define DIO25_DDR DDRA -#define DIO25_PWM nullptr - -#define DIO26_PIN PINA5 -#define DIO26_RPORT PINA -#define DIO26_WPORT PORTA -#define DIO26_DDR DDRA -#define DIO26_PWM nullptr - -#define DIO27_PIN PINA4 -#define DIO27_RPORT PINA -#define DIO27_WPORT PORTA -#define DIO27_DDR DDRA -#define DIO27_PWM nullptr - -#define DIO28_PIN PINA3 -#define DIO28_RPORT PINA -#define DIO28_WPORT PORTA -#define DIO28_DDR DDRA -#define DIO28_PWM nullptr - -#define DIO29_PIN PINA2 -#define DIO29_RPORT PINA -#define DIO29_WPORT PORTA -#define DIO29_DDR DDRA -#define DIO29_PWM nullptr - -#define DIO30_PIN PINA1 -#define DIO30_RPORT PINA -#define DIO30_WPORT PORTA -#define DIO30_DDR DDRA -#define DIO30_PWM nullptr - -#define DIO31_PIN PINA0 -#define DIO31_RPORT PINA -#define DIO31_WPORT PORTA -#define DIO31_DDR DDRA -#define DIO31_PWM nullptr - -#define AIO0_PIN PINA0 -#define AIO0_RPORT PINA -#define AIO0_WPORT PORTA -#define AIO0_DDR DDRA -#define AIO0_PWM nullptr - -#define AIO1_PIN PINA1 -#define AIO1_RPORT PINA -#define AIO1_WPORT PORTA -#define AIO1_DDR DDRA -#define AIO1_PWM nullptr - -#define AIO2_PIN PINA2 -#define AIO2_RPORT PINA -#define AIO2_WPORT PORTA -#define AIO2_DDR DDRA -#define AIO2_PWM nullptr - -#define AIO3_PIN PINA3 -#define AIO3_RPORT PINA -#define AIO3_WPORT PORTA -#define AIO3_DDR DDRA -#define AIO3_PWM nullptr - -#define AIO4_PIN PINA4 -#define AIO4_RPORT PINA -#define AIO4_WPORT PORTA -#define AIO4_DDR DDRA -#define AIO4_PWM nullptr - -#define AIO5_PIN PINA5 -#define AIO5_RPORT PINA -#define AIO5_WPORT PORTA -#define AIO5_DDR DDRA -#define AIO5_PWM nullptr - -#define AIO6_PIN PINA6 -#define AIO6_RPORT PINA -#define AIO6_WPORT PORTA -#define AIO6_DDR DDRA -#define AIO6_PWM nullptr - -#define AIO7_PIN PINA7 -#define AIO7_RPORT PINA -#define AIO7_WPORT PORTA -#define AIO7_DDR DDRA -#define AIO7_PWM nullptr - -#undef PA0 -#define PA0_PIN PINA0 -#define PA0_RPORT PINA -#define PA0_WPORT PORTA -#define PA0_DDR DDRA -#define PA0_PWM nullptr - -#undef PA1 -#define PA1_PIN PINA1 -#define PA1_RPORT PINA -#define PA1_WPORT PORTA -#define PA1_DDR DDRA -#define PA1_PWM nullptr - -#undef PA2 -#define PA2_PIN PINA2 -#define PA2_RPORT PINA -#define PA2_WPORT PORTA -#define PA2_DDR DDRA -#define PA2_PWM nullptr - -#undef PA3 -#define PA3_PIN PINA3 -#define PA3_RPORT PINA -#define PA3_WPORT PORTA -#define PA3_DDR DDRA -#define PA3_PWM nullptr - -#undef PA4 -#define PA4_PIN PINA4 -#define PA4_RPORT PINA -#define PA4_WPORT PORTA -#define PA4_DDR DDRA -#define PA4_PWM nullptr - -#undef PA5 -#define PA5_PIN PINA5 -#define PA5_RPORT PINA -#define PA5_WPORT PORTA -#define PA5_DDR DDRA -#define PA5_PWM nullptr - -#undef PA6 -#define PA6_PIN PINA6 -#define PA6_RPORT PINA -#define PA6_WPORT PORTA -#define PA6_DDR DDRA -#define PA6_PWM nullptr - -#undef PA7 -#define PA7_PIN PINA7 -#define PA7_RPORT PINA -#define PA7_WPORT PORTA -#define PA7_DDR DDRA -#define PA7_PWM nullptr - -#undef PB0 -#define PB0_PIN PINB0 -#define PB0_RPORT PINB -#define PB0_WPORT PORTB -#define PB0_DDR DDRB -#define PB0_PWM nullptr - -#undef PB1 -#define PB1_PIN PINB1 -#define PB1_RPORT PINB -#define PB1_WPORT PORTB -#define PB1_DDR DDRB -#define PB1_PWM nullptr - -#undef PB2 -#define PB2_PIN PINB2 -#define PB2_RPORT PINB -#define PB2_WPORT PORTB -#define PB2_DDR DDRB -#define PB2_PWM nullptr - -#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 nullptr - -#undef PB6 -#define PB6_PIN PINB6 -#define PB6_RPORT PINB -#define PB6_WPORT PORTB -#define PB6_DDR DDRB -#define PB6_PWM nullptr - -#undef PB7 -#define PB7_PIN PINB7 -#define PB7_RPORT PINB -#define PB7_WPORT PORTB -#define PB7_DDR DDRB -#define PB7_PWM nullptr - -#undef PC0 -#define PC0_PIN PINC0 -#define PC0_RPORT PINC -#define PC0_WPORT PORTC -#define PC0_DDR DDRC -#define PC0_PWM nullptr - -#undef PC1 -#define PC1_PIN PINC1 -#define PC1_RPORT PINC -#define PC1_WPORT PORTC -#define PC1_DDR DDRC -#define PC1_PWM nullptr - -#undef PC2 -#define PC2_PIN PINC2 -#define PC2_RPORT PINC -#define PC2_WPORT PORTC -#define PC2_DDR DDRC -#define PC2_PWM nullptr - -#undef PC3 -#define PC3_PIN PINC3 -#define PC3_RPORT PINC -#define PC3_WPORT PORTC -#define PC3_DDR DDRC -#define PC3_PWM nullptr - -#undef PC4 -#define PC4_PIN PINC4 -#define PC4_RPORT PINC -#define PC4_WPORT PORTC -#define PC4_DDR DDRC -#define PC4_PWM nullptr - -#undef PC5 -#define PC5_PIN PINC5 -#define PC5_RPORT PINC -#define PC5_WPORT PORTC -#define PC5_DDR DDRC -#define PC5_PWM nullptr - -#undef PC6 -#define PC6_PIN PINC6 -#define PC6_RPORT PINC -#define PC6_WPORT PORTC -#define PC6_DDR DDRC -#define PC6_PWM nullptr - -#undef PC7 -#define PC7_PIN PINC7 -#define PC7_RPORT PINC -#define PC7_WPORT PORTC -#define PC7_DDR DDRC -#define PC7_PWM nullptr - -#undef PD0 -#define PD0_PIN PIND0 -#define PD0_RPORT PIND -#define PD0_WPORT PORTD -#define PD0_DDR DDRD -#define PD0_PWM nullptr - -#undef PD1 -#define PD1_PIN PIND1 -#define PD1_RPORT PIND -#define PD1_WPORT PORTD -#define PD1_DDR DDRD -#define PD1_PWM nullptr - -#undef PD2 -#define PD2_PIN PIND2 -#define PD2_RPORT PIND -#define PD2_WPORT PORTD -#define PD2_DDR DDRD -#define PD2_PWM nullptr - -#undef PD3 -#define PD3_PIN PIND3 -#define PD3_RPORT PIND -#define PD3_WPORT PORTD -#define PD3_DDR DDRD -#define PD3_PWM nullptr - -#undef PD4 -#define PD4_PIN PIND4 -#define PD4_RPORT PIND -#define PD4_WPORT PORTD -#define PD4_DDR DDRD -#define PD4_PWM nullptr - -#undef PD5 -#define PD5_PIN PIND5 -#define PD5_RPORT PIND -#define PD5_WPORT PORTD -#define PD5_DDR DDRD -#define PD5_PWM nullptr - -#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 diff --git a/src/HAL/AVR/fastio/fastio_AT90USB.h b/src/HAL/AVR/fastio/fastio_AT90USB.h deleted file mode 100644 index 51d400b..0000000 --- a/src/HAL/AVR/fastio/fastio_AT90USB.h +++ /dev/null @@ -1,697 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Pin mapping (Teensy) for AT90USB646, 647, 1286, and 1287 - * - * Logical Pin: 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 logical pins 46 and 47 are not supported by Teensyduino, but are supported below as E2 and E3 - */ - -#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 0 -#define DIO0_DDR DDRD - -#define DIO1_PIN PIND1 -#define DIO1_RPORT PIND -#define DIO1_WPORT PORTD -#define DIO1_PWM 0 -#define DIO1_DDR DDRD - -#define DIO2_PIN PIND2 -#define DIO2_RPORT PIND -#define DIO2_WPORT PORTD -#define DIO2_PWM 0 -#define DIO2_DDR DDRD - -#define DIO3_PIN PIND3 -#define DIO3_RPORT PIND -#define DIO3_WPORT PORTD -#define DIO3_PWM 0 -#define DIO3_DDR DDRD - -#define DIO4_PIN PIND4 -#define DIO4_RPORT PIND -#define DIO4_WPORT PORTD -#define DIO4_PWM 0 -#define DIO4_DDR DDRD - -#define DIO5_PIN PIND5 -#define DIO5_RPORT PIND -#define DIO5_WPORT PORTD -#define DIO5_PWM 0 -#define DIO5_DDR DDRD - -#define DIO6_PIN PIND6 -#define DIO6_RPORT PIND -#define DIO6_WPORT PORTD -#define DIO6_PWM 0 -#define DIO6_DDR DDRD - -#define DIO7_PIN PIND7 -#define DIO7_RPORT PIND -#define DIO7_WPORT PORTD -#define DIO7_PWM 0 -#define DIO7_DDR DDRD - -#define DIO8_PIN PINE0 -#define DIO8_RPORT PINE -#define DIO8_WPORT PORTE -#define DIO8_PWM 0 -#define DIO8_DDR DDRE - -#define DIO9_PIN PINE1 -#define DIO9_RPORT PINE -#define DIO9_WPORT PORTE -#define DIO9_PWM 0 -#define DIO9_DDR DDRE - -#define DIO10_PIN PINC0 -#define DIO10_RPORT PINC -#define DIO10_WPORT PORTC -#define DIO10_PWM 0 -#define DIO10_DDR DDRC - -#define DIO11_PIN PINC1 -#define DIO11_RPORT PINC -#define DIO11_WPORT PORTC -#define DIO11_PWM 0 -#define DIO11_DDR DDRC - -#define DIO12_PIN PINC2 -#define DIO12_RPORT PINC -#define DIO12_WPORT PORTC -#define DIO12_PWM 0 -#define DIO12_DDR DDRC - -#define DIO13_PIN PINC3 -#define DIO13_RPORT PINC -#define DIO13_WPORT PORTC -#define DIO13_PWM 0 -#define DIO13_DDR DDRC - -#define DIO14_PIN PINC4 -#define DIO14_RPORT PINC -#define DIO14_WPORT PORTC -#define DIO14_PWM 0 // OC3C -#define DIO14_DDR DDRC - -#define DIO15_PIN PINC5 -#define DIO15_RPORT PINC -#define DIO15_WPORT PORTC -#define DIO15_PWM 0 // OC3B -#define DIO15_DDR DDRC - -#define DIO16_PIN PINC6 -#define DIO16_RPORT PINC -#define DIO16_WPORT PORTC -#define DIO16_PWM 0 // OC3A -#define DIO16_DDR DDRC - -#define DIO17_PIN PINC7 -#define DIO17_RPORT PINC -#define DIO17_WPORT PORTC -#define DIO17_PWM 0 -#define DIO17_DDR DDRC - -#define DIO18_PIN PINE6 -#define DIO18_RPORT PINE -#define DIO18_WPORT PORTE -#define DIO18_PWM 0 -#define DIO18_DDR DDRE - -#define DIO19_PIN PINE7 -#define DIO19_RPORT PINE -#define DIO19_WPORT PORTE -#define DIO19_PWM 0 -#define DIO19_DDR DDRE - -#define DIO20_PIN PINB0 -#define DIO20_RPORT PINB -#define DIO20_WPORT PORTB -#define DIO20_PWM 0 -#define DIO20_DDR DDRB - -#define DIO21_PIN PINB1 -#define DIO21_RPORT PINB -#define DIO21_WPORT PORTB -#define DIO21_PWM 0 -#define DIO21_DDR DDRB - -#define DIO22_PIN PINB2 -#define DIO22_RPORT PINB -#define DIO22_WPORT PORTB -#define DIO22_PWM 0 -#define DIO22_DDR DDRB - -#define DIO23_PIN PINB3 -#define DIO23_RPORT PINB -#define DIO23_WPORT PORTB -#define DIO23_PWM 0 -#define DIO23_DDR DDRB - -#define DIO24_PIN PINB4 -#define DIO24_RPORT PINB -#define DIO24_WPORT PORTB -#define DIO24_PWM 0 // OC2A -#define DIO24_DDR DDRB - -#define DIO25_PIN PINB5 -#define DIO25_RPORT PINB -#define DIO25_WPORT PORTB -#define DIO25_PWM 0 // OC1A -#define DIO25_DDR DDRB - -#define DIO26_PIN PINB6 -#define DIO26_RPORT PINB -#define DIO26_WPORT PORTB -#define DIO26_PWM 0 // OC1B -#define DIO26_DDR DDRB - -#define DIO27_PIN PINB7 -#define DIO27_RPORT PINB -#define DIO27_WPORT PORTB -#define DIO27_PWM 0 // OC1C -#define DIO27_DDR DDRB - -#define DIO28_PIN PINA0 -#define DIO28_RPORT PINA -#define DIO28_WPORT PORTA -#define DIO28_PWM 0 -#define DIO28_DDR DDRA - -#define DIO29_PIN PINA1 -#define DIO29_RPORT PINA -#define DIO29_WPORT PORTA -#define DIO29_PWM 0 -#define DIO29_DDR DDRA - -#define DIO30_PIN PINA2 -#define DIO30_RPORT PINA -#define DIO30_WPORT PORTA -#define DIO30_PWM 0 -#define DIO30_DDR DDRA - -#define DIO31_PIN PINA3 -#define DIO31_RPORT PINA -#define DIO31_WPORT PORTA -#define DIO31_PWM 0 -#define DIO31_DDR DDRA - -#define DIO32_PIN PINA4 -#define DIO32_RPORT PINA -#define DIO32_WPORT PORTA -#define DIO32_PWM 0 -#define DIO32_DDR DDRA - -#define DIO33_PIN PINA5 -#define DIO33_RPORT PINA -#define DIO33_WPORT PORTA -#define DIO33_PWM 0 -#define DIO33_DDR DDRA - -#define DIO34_PIN PINA6 -#define DIO34_RPORT PINA -#define DIO34_WPORT PORTA -#define DIO34_PWM 0 -#define DIO34_DDR DDRA - -#define DIO35_PIN PINA7 -#define DIO35_RPORT PINA -#define DIO35_WPORT PORTA -#define DIO35_PWM 0 -#define DIO35_DDR DDRA - -#define DIO36_PIN PINE4 -#define DIO36_RPORT PINE -#define DIO36_WPORT PORTE -#define DIO36_PWM 0 -#define DIO36_DDR DDRE - -#define DIO37_PIN PINE5 -#define DIO37_RPORT PINE -#define DIO37_WPORT PORTE -#define DIO37_PWM 0 -#define DIO37_DDR DDRE - -#define DIO38_PIN PINF0 -#define DIO38_RPORT PINF -#define DIO38_WPORT PORTF -#define DIO38_PWM 0 -#define DIO38_DDR DDRF - -#define DIO39_PIN PINF1 -#define DIO39_RPORT PINF -#define DIO39_WPORT PORTF -#define DIO39_PWM 0 -#define DIO39_DDR DDRF - -#define DIO40_PIN PINF2 -#define DIO40_RPORT PINF -#define DIO40_WPORT PORTF -#define DIO40_PWM 0 -#define DIO40_DDR DDRF - -#define DIO41_PIN PINF3 -#define DIO41_RPORT PINF -#define DIO41_WPORT PORTF -#define DIO41_PWM 0 -#define DIO41_DDR DDRF - -#define DIO42_PIN PINF4 -#define DIO42_RPORT PINF -#define DIO42_WPORT PORTF -#define DIO42_PWM 0 -#define DIO42_DDR DDRF - -#define DIO43_PIN PINF5 -#define DIO43_RPORT PINF -#define DIO43_WPORT PORTF -#define DIO43_PWM 0 -#define DIO43_DDR DDRF - -#define DIO44_PIN PINF6 -#define DIO44_RPORT PINF -#define DIO44_WPORT PORTF -#define DIO44_PWM 0 -#define DIO44_DDR DDRF - -#define DIO45_PIN PINF7 -#define DIO45_RPORT PINF -#define DIO45_WPORT PORTF -#define DIO45_PWM 0 -#define DIO45_DDR DDRF - -#define AIO0_PIN PINF0 -#define AIO0_RPORT PINF -#define AIO0_WPORT PORTF -#define AIO0_PWM 0 -#define AIO0_DDR DDRF - -#define AIO1_PIN PINF1 -#define AIO1_RPORT PINF -#define AIO1_WPORT PORTF -#define AIO1_PWM 0 -#define AIO1_DDR DDRF - -#define AIO2_PIN PINF2 -#define AIO2_RPORT PINF -#define AIO2_WPORT PORTF -#define AIO2_PWM 0 -#define AIO2_DDR DDRF - -#define AIO3_PIN PINF3 -#define AIO3_RPORT PINF -#define AIO3_WPORT PORTF -#define AIO3_PWM 0 -#define AIO3_DDR DDRF - -#define AIO4_PIN PINF4 -#define AIO4_RPORT PINF -#define AIO4_WPORT PORTF -#define AIO4_PWM 0 -#define AIO4_DDR DDRF - -#define AIO5_PIN PINF5 -#define AIO5_RPORT PINF -#define AIO5_WPORT PORTF -#define AIO5_PWM 0 -#define AIO5_DDR DDRF - -#define AIO6_PIN PINF6 -#define AIO6_RPORT PINF -#define AIO6_WPORT PORTF -#define AIO6_PWM 0 -#define AIO6_DDR DDRF - -#define AIO7_PIN PINF7 -#define AIO7_RPORT PINF -#define AIO7_WPORT PORTF -#define AIO7_PWM 0 -#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 0 -#define DIO46_DDR DDRE - -#define DIO47_PIN PINE3 -#define DIO47_RPORT PINE -#define DIO47_WPORT PORTE -#define DIO47_PWM 0 -#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 0 -#define PA0_DDR DDRA -#undef PA1 -#define PA1_PIN PINA1 -#define PA1_RPORT PINA -#define PA1_WPORT PORTA -#define PA1_PWM 0 -#define PA1_DDR DDRA -#undef PA2 -#define PA2_PIN PINA2 -#define PA2_RPORT PINA -#define PA2_WPORT PORTA -#define PA2_PWM 0 -#define PA2_DDR DDRA -#undef PA3 -#define PA3_PIN PINA3 -#define PA3_RPORT PINA -#define PA3_WPORT PORTA -#define PA3_PWM 0 -#define PA3_DDR DDRA -#undef PA4 -#define PA4_PIN PINA4 -#define PA4_RPORT PINA -#define PA4_WPORT PORTA -#define PA4_PWM 0 -#define PA4_DDR DDRA -#undef PA5 -#define PA5_PIN PINA5 -#define PA5_RPORT PINA -#define PA5_WPORT PORTA -#define PA5_PWM 0 -#define PA5_DDR DDRA -#undef PA6 -#define PA6_PIN PINA6 -#define PA6_RPORT PINA -#define PA6_WPORT PORTA -#define PA6_PWM 0 -#define PA6_DDR DDRA -#undef PA7 -#define PA7_PIN PINA7 -#define PA7_RPORT PINA -#define PA7_WPORT PORTA -#define PA7_PWM 0 -#define PA7_DDR DDRA - -#undef PB0 -#define PB0_PIN PINB0 -#define PB0_RPORT PINB -#define PB0_WPORT PORTB -#define PB0_PWM 0 -#define PB0_DDR DDRB -#undef PB1 -#define PB1_PIN PINB1 -#define PB1_RPORT PINB -#define PB1_WPORT PORTB -#define PB1_PWM 0 -#define PB1_DDR DDRB -#undef PB2 -#define PB2_PIN PINB2 -#define PB2_RPORT PINB -#define PB2_WPORT PORTB -#define PB2_PWM 0 -#define PB2_DDR DDRB -#undef PB3 -#define PB3_PIN PINB3 -#define PB3_RPORT PINB -#define PB3_WPORT PORTB -#define PB3_PWM 0 -#define PB3_DDR DDRB -#undef PB4 -#define PB4_PIN PINB4 -#define PB4_RPORT PINB -#define PB4_WPORT PORTB -#define PB4_PWM 0 -#define PB4_DDR DDRB -#undef PB5 -#define PB5_PIN PINB5 -#define PB5_RPORT PINB -#define PB5_WPORT PORTB -#define PB5_PWM 0 -#define PB5_DDR DDRB -#undef PB6 -#define PB6_PIN PINB6 -#define PB6_RPORT PINB -#define PB6_WPORT PORTB -#define PB6_PWM 0 -#define PB6_DDR DDRB -#undef PB7 -#define PB7_PIN PINB7 -#define PB7_RPORT PINB -#define PB7_WPORT PORTB -#define PB7_PWM 0 -#define PB7_DDR DDRB - -#undef PC0 -#define PC0_PIN PINC0 -#define PC0_RPORT PINC -#define PC0_WPORT PORTC -#define PC0_PWM 0 -#define PC0_DDR DDRC -#undef PC1 -#define PC1_PIN PINC1 -#define PC1_RPORT PINC -#define PC1_WPORT PORTC -#define PC1_PWM 0 -#define PC1_DDR DDRC -#undef PC2 -#define PC2_PIN PINC2 -#define PC2_RPORT PINC -#define PC2_WPORT PORTC -#define PC2_PWM 0 -#define PC2_DDR DDRC -#undef PC3 -#define PC3_PIN PINC3 -#define PC3_RPORT PINC -#define PC3_WPORT PORTC -#define PC3_PWM 0 -#define PC3_DDR DDRC -#undef PC4 -#define PC4_PIN PINC4 -#define PC4_RPORT PINC -#define PC4_WPORT PORTC -#define PC4_PWM 0 -#define PC4_DDR DDRC -#undef PC5 -#define PC5_PIN PINC5 -#define PC5_RPORT PINC -#define PC5_WPORT PORTC -#define PC5_PWM 0 -#define PC5_DDR DDRC -#undef PC6 -#define PC6_PIN PINC6 -#define PC6_RPORT PINC -#define PC6_WPORT PORTC -#define PC6_PWM 0 -#define PC6_DDR DDRC -#undef PC7 -#define PC7_PIN PINC7 -#define PC7_RPORT PINC -#define PC7_WPORT PORTC -#define PC7_PWM 0 -#define PC7_DDR DDRC - -#undef PD0 -#define PD0_PIN PIND0 -#define PD0_RPORT PIND -#define PD0_WPORT PORTD -#define PD0_PWM 0 // OC0B -#define PD0_DDR DDRD -#undef PD1 -#define PD1_PIN PIND1 -#define PD1_RPORT PIND -#define PD1_WPORT PORTD -#define PD1_PWM 0 // OC2B -#define PD1_DDR DDRD -#undef PD2 -#define PD2_PIN PIND2 -#define PD2_RPORT PIND -#define PD2_WPORT PORTD -#define PD2_PWM 0 -#define PD2_DDR DDRD -#undef PD3 -#define PD3_PIN PIND3 -#define PD3_RPORT PIND -#define PD3_WPORT PORTD -#define PD3_PWM 0 -#define PD3_DDR DDRD -#undef PD4 -#define PD4_PIN PIND4 -#define PD4_RPORT PIND -#define PD4_WPORT PORTD -#define PD4_PWM 0 -#define PD4_DDR DDRD -#undef PD5 -#define PD5_PIN PIND5 -#define PD5_RPORT PIND -#define PD5_WPORT PORTD -#define PD5_PWM 0 -#define PD5_DDR DDRD -#undef PD6 -#define PD6_PIN PIND6 -#define PD6_RPORT PIND -#define PD6_WPORT PORTD -#define PD6_PWM 0 -#define PD6_DDR DDRD -#undef PD7 -#define PD7_PIN PIND7 -#define PD7_RPORT PIND -#define PD7_WPORT PORTD -#define PD7_PWM 0 -#define PD7_DDR DDRD - -#undef PE0 -#define PE0_PIN PINE0 -#define PE0_RPORT PINE -#define PE0_WPORT PORTE -#define PE0_PWM 0 -#define PE0_DDR DDRE -#undef PE1 -#define PE1_PIN PINE1 -#define PE1_RPORT PINE -#define PE1_WPORT PORTE -#define PE1_PWM 0 -#define PE1_DDR DDRE -#undef PE2 -#define PE2_PIN PINE2 -#define PE2_RPORT PINE -#define PE2_WPORT PORTE -#define PE2_PWM 0 -#define PE2_DDR DDRE -#undef PE3 -#define PE3_PIN PINE3 -#define PE3_RPORT PINE -#define PE3_WPORT PORTE -#define PE3_PWM 0 -#define PE3_DDR DDRE -#undef PE4 -#define PE4_PIN PINE4 -#define PE4_RPORT PINE -#define PE4_WPORT PORTE -#define PE4_PWM 0 -#define PE4_DDR DDRE -#undef PE5 -#define PE5_PIN PINE5 -#define PE5_RPORT PINE -#define PE5_WPORT PORTE -#define PE5_PWM 0 -#define PE5_DDR DDRE -#undef PE6 -#define PE6_PIN PINE6 -#define PE6_RPORT PINE -#define PE6_WPORT PORTE -#define PE6_PWM 0 -#define PE6_DDR DDRE -#undef PE7 -#define PE7_PIN PINE7 -#define PE7_RPORT PINE -#define PE7_WPORT PORTE -#define PE7_PWM 0 -#define PE7_DDR DDRE - -#undef PF0 -#define PF0_PIN PINF0 -#define PF0_RPORT PINF -#define PF0_WPORT PORTF -#define PF0_PWM 0 -#define PF0_DDR DDRF -#undef PF1 -#define PF1_PIN PINF1 -#define PF1_RPORT PINF -#define PF1_WPORT PORTF -#define PF1_PWM 0 -#define PF1_DDR DDRF -#undef PF2 -#define PF2_PIN PINF2 -#define PF2_RPORT PINF -#define PF2_WPORT PORTF -#define PF2_PWM 0 -#define PF2_DDR DDRF -#undef PF3 -#define PF3_PIN PINF3 -#define PF3_RPORT PINF -#define PF3_WPORT PORTF -#define PF3_PWM 0 -#define PF3_DDR DDRF -#undef PF4 -#define PF4_PIN PINF4 -#define PF4_RPORT PINF -#define PF4_WPORT PORTF -#define PF4_PWM 0 -#define PF4_DDR DDRF -#undef PF5 -#define PF5_PIN PINF5 -#define PF5_RPORT PINF -#define PF5_WPORT PORTF -#define PF5_PWM 0 -#define PF5_DDR DDRF -#undef PF6 -#define PF6_PIN PINF6 -#define PF6_RPORT PINF -#define PF6_WPORT PORTF -#define PF6_PWM 0 -#define PF6_DDR DDRF -#undef PF7 -#define PF7_PIN PINF7 -#define PF7_RPORT PINF -#define PF7_WPORT PORTF -#define PF7_PWM 0 -#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 diff --git a/src/HAL/AVR/inc/Conditionals_LCD.h b/src/HAL/AVR/inc/Conditionals_LCD.h deleted file mode 100644 index a611ccd..0000000 --- a/src/HAL/AVR/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/AVR." -#endif diff --git a/src/HAL/AVR/inc/Conditionals_adv.h b/src/HAL/AVR/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/AVR/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/AVR/inc/Conditionals_post.h b/src/HAL/AVR/inc/Conditionals_post.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/AVR/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/AVR/inc/SanityCheck.h b/src/HAL/AVR/inc/SanityCheck.h deleted file mode 100644 index 1c1d8d4..0000000 --- a/src/HAL/AVR/inc/SanityCheck.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test AVR-specific configuration values for errors at compile-time. - */ - -/** - * Check for common serial pin conflicts - */ -#define CHECK_SERIAL_PIN(N) ( \ - X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \ - || X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \ - || X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \ - || X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \ - || X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \ - || X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \ -) -#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts. -#endif -#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)) - #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." -#endif -#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17)) - #error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board." -#endif -#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15)) - #error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board." -#endif -#undef CHECK_SERIAL_PIN - -/** - * Checks for FAST PWM - */ -#if ALL(FAST_PWM_FAN, USE_OCR2A_AS_TOP, HAS_TCCR2) - #error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2." -#endif - -/** - * Checks for SOFT PWM - */ -#if HAS_FAN0 && FAN_PIN == 9 && DISABLED(FAN_SOFT_PWM) && ENABLED(SPEAKER) - #error "FAN_PIN 9 Hardware PWM uses Timer 2 which conflicts with Arduino AVR Tone Timer (for SPEAKER)." - #error "Disable SPEAKER or enable FAN_SOFT_PWM." -#endif - -/** - * Sanity checks for Spindle / Laser PWM - */ -#if ENABLED(SPINDLE_LASER_USE_PWM) - #include "../ServoTimers.h" // Needed to check timer availability (_useTimer3) - #if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13) - #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt." - #elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5) - #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system." - #endif -#elif SPINDLE_LASER_FREQUENCY - #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM." -#endif - -/** - * The Trinamic library includes SoftwareSerial.h, leading to a compile error. - */ -#if BOTH(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE) - #error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." -#endif - -#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS) - #error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue." -#endif - -/** - * Postmortem debugging - */ -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not supported on AVR boards." -#endif - -#if USING_PULLDOWNS - #error "PULLDOWN pin mode is not available on AVR boards." -#endif diff --git a/src/HAL/AVR/math.h b/src/HAL/AVR/math.h deleted file mode 100644 index 7dd1018..0000000 --- a/src/HAL/AVR/math.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Optimized math functions for AVR - */ - -// intRes = longIn1 * longIn2 >> 24 -// uses: -// A[tmp] to store 0 -// B[tmp] 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. -// B A are bits 24-39 and are the returned value -// C B A is longIn1 -// D C B A is longIn2 -// -FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) { - uint8_t tmp1; - uint8_t tmp2; - uint16_t intRes; - __asm__ __volatile__( - A("clr %[tmp1]") - A("mul %A[longIn1], %B[longIn2]") - A("mov %[tmp2], r1") - A("mul %B[longIn1], %C[longIn2]") - A("movw %A[intRes], r0") - A("mul %C[longIn1], %C[longIn2]") - A("add %B[intRes], r0") - A("mul %C[longIn1], %B[longIn2]") - A("add %A[intRes], r0") - A("adc %B[intRes], r1") - A("mul %A[longIn1], %C[longIn2]") - A("add %[tmp2], r0") - A("adc %A[intRes], r1") - A("adc %B[intRes], %[tmp1]") - A("mul %B[longIn1], %B[longIn2]") - A("add %[tmp2], r0") - A("adc %A[intRes], r1") - A("adc %B[intRes], %[tmp1]") - A("mul %C[longIn1], %A[longIn2]") - A("add %[tmp2], r0") - A("adc %A[intRes], r1") - A("adc %B[intRes], %[tmp1]") - A("mul %B[longIn1], %A[longIn2]") - A("add %[tmp2], r1") - A("adc %A[intRes], %[tmp1]") - A("adc %B[intRes], %[tmp1]") - A("lsr %[tmp2]") - A("adc %A[intRes], %[tmp1]") - A("adc %B[intRes], %[tmp1]") - A("mul %D[longIn2], %A[longIn1]") - A("add %A[intRes], r0") - A("adc %B[intRes], r1") - A("mul %D[longIn2], %B[longIn1]") - A("add %B[intRes], r0") - A("clr r1") - : [intRes] "=&r" (intRes), - [tmp1] "=&r" (tmp1), - [tmp2] "=&r" (tmp2) - : [longIn1] "d" (longIn1), - [longIn2] "d" (longIn2) - : "cc" - ); - return intRes; -} - -// intRes = intIn1 * intIn2 >> 16 -// uses: -// r26 to store 0 -// r27 to store the byte 1 of the 24 bit result -FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) { - uint8_t tmp; - uint16_t intRes; - __asm__ __volatile__ ( - A("clr %[tmp]") - A("mul %[charIn1], %B[intIn2]") - A("movw %A[intRes], r0") - A("mul %[charIn1], %A[intIn2]") - A("add %A[intRes], r1") - A("adc %B[intRes], %[tmp]") - A("lsr r0") - A("adc %A[intRes], %[tmp]") - A("adc %B[intRes], %[tmp]") - A("clr r1") - : [intRes] "=&r" (intRes), - [tmp] "=&r" (tmp) - : [charIn1] "d" (charIn1), - [intIn2] "d" (intIn2) - : "cc" - ); - return intRes; -} diff --git a/src/HAL/AVR/pinsDebug.h b/src/HAL/AVR/pinsDebug.h deleted file mode 100644 index dab4e44..0000000 --- a/src/HAL/AVR/pinsDebug.h +++ /dev/null @@ -1,400 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * PWM print routines for Atmel 8 bit AVR CPUs - */ - -#include "../../inc/MarlinConfig.h" - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS - -#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) - #define AVR_ATmega2560_FAMILY_PLUS_70 1 -#endif - -#if AVR_AT90USB1286_FAMILY - - // 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(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); } - #define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin) - -#endif - -#define VALID_PIN(pin) (pin >= 0 && pin < NUM_DIGITAL_PINS ? 1 : 0) -#if AVR_ATmega1284_FAMILY - #define DIGITAL_PIN_TO_ANALOG_PIN(P) int(analogInputToDigitalPin(0) - (P)) - #define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(7) && (P) <= analogInputToDigitalPin(0)) -#else - #define DIGITAL_PIN_TO_ANALOG_PIN(P) int((P) - analogInputToDigitalPin(0)) - #define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && ((P) <= analogInputToDigitalPin(15) || (P) <= analogInputToDigitalPin(7))) -#endif -#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin) -#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin - -void PRINT_ARRAY_NAME(uint8_t x) { - PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name); - LOOP_L_N(y, MAX_NAME_LENGTH) { - char temp_char = pgm_read_byte(name_mem_pointer + y); - if (temp_char != 0) - SERIAL_CHAR(temp_char); - else { - LOOP_L_N(i, MAX_NAME_LENGTH - y) SERIAL_CHAR(' '); - break; - } - } -} - -#define GET_ARRAY_IS_DIGITAL(x) pgm_read_byte(&pin_array[x].is_digital) - - -#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 - -#define ABTEST(N) defined(TCCR##N##A) && defined(COM##N##A1) - -/** - * 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 ABTEST(0) - #ifdef TIMER0A - #if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs - PWM_CASE(0, A); - #endif - #endif - PWM_CASE(0, B); - #endif - - #if ABTEST(1) - PWM_CASE(1, A); - PWM_CASE(1, B); - #if defined(COM1C1) && defined(TIMER1C) - PWM_CASE(1, C); - #endif - #endif - - #if ABTEST(2) - PWM_CASE(2, A); - PWM_CASE(2, B); - #endif - - #if ABTEST(3) - 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 ABTEST(5) - PWM_CASE(5, A); - PWM_CASE(5, B); - PWM_CASE(5, C); - #endif - - case NOT_ON_TIMER: - default: - return false; - } - SERIAL_ECHO_SP(2); -} // pwm_status - - -const volatile uint8_t* const PWM_other[][3] PROGMEM = { - { &TCCR0A, &TCCR0B, &TIMSK0 }, - { &TCCR1A, &TCCR1B, &TIMSK1 }, - #if ABTEST(2) - { &TCCR2A, &TCCR2B, &TIMSK2 }, - #endif - #if ABTEST(3) - { &TCCR3A, &TCCR3B, &TIMSK3 }, - #endif - #ifdef TCCR4A - { &TCCR4A, &TCCR4B, &TIMSK4 }, - #endif - #if ABTEST(5) - { &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 ABTEST(2) - { &OCR2A, &OCR2B, 0 }, - #endif - - #if ABTEST(3) - #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 ABTEST(5) - { (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_ECHOPGM(" non-standard PWM mode"); } -static void err_is_interrupt() { SERIAL_ECHOPGM(" compare interrupt enabled"); } -static void err_prob_interrupt() { SERIAL_ECHOPGM(" overflow interrupt enabled"); } -static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin"); SERIAL_ECHO_SP(14); } - -inline void com_print(const uint8_t N, const uint8_t Z) { - const uint8_t *TCCRA = (uint8_t*)TCCR_A(N); - SERIAL_ECHOPGM(" COM", AS_DIGIT(N)); - SERIAL_CHAR(Z); - SERIAL_ECHOPGM(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03)); -} - -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_ECHOPGM(" TIMER", AS_DIGIT(T)); - SERIAL_CHAR(L); - SERIAL_ECHO_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_ECHOPGM(" WGM: ", WGM); - com_print(T,L); - SERIAL_ECHOPGM(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) )); - SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "A: ", *TCCRA); - SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "B: ", *TCCRB); - - const uint8_t *TMSK = (uint8_t*)TIMSK(T); - SERIAL_ECHOPGM(" TIMSK", AS_DIGIT(T), ": ", *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 ABTEST(0) - #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 ABTEST(1) - 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 ABTEST(2) - case TIMER2A: timer_prefix(2, 'A', 3); break; - case TIMER2B: timer_prefix(2, 'B', 3); break; - #endif - - #if ABTEST(3) - 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 ABTEST(5) - 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_ECHOPGM(" "); - - // 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_ECHOPGM("\n ."); - SERIAL_ECHO_SP(18); - SERIAL_ECHOPGM("TIMER1C"); - print_is_also_tied(); - timer_prefix(1, 'C', 4); - #else - SERIAL_ECHOPGM("\n ."); - SERIAL_ECHO_SP(18); - SERIAL_ECHOPGM("TIMER0A"); - print_is_also_tied(); - timer_prefix(0, 'A', 3); - #endif - } - #else - UNUSED(print_is_also_tied); - #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 - -#ifndef PRINT_PORT - - void print_port(int8_t pin) { // print port number - #ifdef digitalPinToPort_DEBUG - uint8_t x; - SERIAL_ECHOPGM(" 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_ECHO_SP(10); - #endif - } - - #define PRINT_PORT(p) print_port(p) - -#endif - -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) - -#undef ABTEST diff --git a/src/HAL/AVR/pinsDebug_Teensyduino.h b/src/HAL/AVR/pinsDebug_Teensyduino.h deleted file mode 100644 index 582ae79..0000000 --- a/src/HAL/AVR/pinsDebug_Teensyduino.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// -// some of the pin mapping functions of the Teensduino extension to the Arduino IDE -// do not function the same as the other Arduino extensions -// - - -#define TEENSYDUINO_IDE - -//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 - -// digitalPinToPort function just returns the pin number so need to create our own -#define PA 1 -#define PB 2 -#define PC 3 -#define PD 4 -#define PE 5 -#define PF 6 - -#undef digitalPinToPort - -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - 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(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) - -// digitalPinToBitMask(pin) is OK - -#define digitalRead_mod(p) extDigitalRead(p) // Teensyduino's version of digitalRead doesn't - // disable the PWMs so we can use it as is - -// portModeRegister(pin) is OK diff --git a/src/HAL/AVR/pinsDebug_plus_70.h b/src/HAL/AVR/pinsDebug_plus_70.h deleted file mode 100644 index d9aa44c..0000000 --- a/src/HAL/AVR/pinsDebug_plus_70.h +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Structures for 2560 family boards that use more than 70 pins - */ - -#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14) - #undef NUM_DIGITAL_PINS - #define NUM_DIGITAL_PINS 85 -#elif MB(MIGHTYBOARD_REVE) - #undef NUM_DIGITAL_PINS - #define NUM_DIGITAL_PINS 80 -#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 - */ diff --git a/src/HAL/AVR/spi_pins.h b/src/HAL/AVR/spi_pins.h deleted file mode 100644 index 8319729..0000000 --- a/src/HAL/AVR/spi_pins.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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 SD_SCK_PIN - #define SD_SCK_PIN AVR_SCK_PIN -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN AVR_MISO_PIN -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN AVR_MOSI_PIN -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN AVR_SS_PIN -#endif diff --git a/src/HAL/AVR/timers.h b/src/HAL/AVR/timers.h deleted file mode 100644 index 33c3880..0000000 --- a/src/HAL/AVR/timers.h +++ /dev/null @@ -1,260 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -// ------------------------ -// Types -// ------------------------ - -typedef uint16_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFF - -// ------------------------ -// Defines -// ------------------------ - -#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 1 -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 0 -#endif - -#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0) - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_PRESCALE 8 -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A) -#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A) - -#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0A) -#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0A) -#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0A) - -FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) { - switch (timer_num) { - case MF_TIMER_STEP: - // 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 - // (F_CPU) / (STEPPER_TIMER_PRESCALE) / frequency - OCR1A = 0x4000; - TCNT1 = 0; - break; - - case MF_TIMER_TEMP: - // Use timer0 for temperature measurement - // Interleave temperature interrupt with millies interrupt - OCR0A = 128; - break; - } -} - -#define TIMER_OCR_1 OCR1A -#define TIMER_COUNTER_1 TCNT1 - -#define TIMER_OCR_0 OCR0A -#define TIMER_COUNTER_0 TCNT0 - -#define _CAT(a,V...) a##V -#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare) -#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer) -#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer) - -/** - * On AVR there is no hardware prioritization and preemption of - * interrupts, so this emulates it. The UART has first priority - * (otherwise, characters will be lost due to UART overflow). - * Then: Stepper, Endstops, Temperature, and -finally- all others. - */ -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP - -#ifndef HAL_STEP_TIMER_ISR - -/* 18 cycles maximum latency */ -#define HAL_STEP_TIMER_ISR() \ -extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \ -extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \ -void TIMER1_COMPA_vect() { \ - __asm__ __volatile__ ( \ - A("push r16") /* 2 Save R16 */ \ - A("in r16, __SREG__") /* 1 Get SREG */ \ - A("push r16") /* 2 Save SREG into stack */ \ - A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \ - A("push r16") /* 2 Save TIMSK0 into the stack */ \ - A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \ - A("sts %[timsk0], r16") /* 2 And set the new value */ \ - A("lds r16, %[timsk1]") /* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \ - A("andi r16,~%[msk1]") /* 1 Disable the stepper ISR */ \ - A("sts %[timsk1], r16") /* 2 And set the new value */ \ - A("push r16") /* 2 Save TIMSK1 into stack */ \ - A("in r16, 0x3B") /* 1 Get RAMPZ register */ \ - A("push r16") /* 2 Save RAMPZ into stack */ \ - A("in r16, 0x3C") /* 1 Get EIND register */ \ - A("push r0") /* C runtime can modify all the following registers without restoring them */ \ - A("push r1") \ - A("push r18") \ - A("push r19") \ - A("push r20") \ - A("push r21") \ - A("push r22") \ - A("push r23") \ - A("push r24") \ - A("push r25") \ - A("push r26") \ - A("push r27") \ - A("push r30") \ - A("push r31") \ - A("clr r1") /* C runtime expects this register to be 0 */ \ - A("call TIMER1_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \ - A("pop r31") \ - A("pop r30") \ - A("pop r27") \ - A("pop r26") \ - A("pop r25") \ - A("pop r24") \ - A("pop r23") \ - A("pop r22") \ - A("pop r21") \ - A("pop r20") \ - A("pop r19") \ - A("pop r18") \ - A("pop r1") \ - A("pop r0") \ - A("out 0x3C, r16") /* 1 Restore EIND register */ \ - A("pop r16") /* 2 Get the original RAMPZ register value */ \ - A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \ - A("pop r16") /* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \ - A("ori r16,%[msk1]") /* 1 Reenable the stepper ISR */ \ - A("cli") /* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \ - A("sts %[timsk1], r16") /* 2 And restore the old value - This reenables the stepper ISR */ \ - A("pop r16") /* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \ - A("sts %[timsk0], r16") /* 2 And restore the old value - This reenables the temperature ISR */ \ - A("pop r16") /* 2 Get the old SREG value */ \ - A("out __SREG__, r16") /* 1 And restore the SREG value */ \ - A("pop r16") /* 2 Restore R16 value */ \ - A("reti") /* 4 Return from interrupt */ \ - : \ - : [timsk0] "i" ((uint16_t)&TIMSK0), \ - [timsk1] "i" ((uint16_t)&TIMSK1), \ - [msk0] "M" ((uint8_t)(1<. - * - */ - -/** - * Based on u8g_com_st7920_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. - */ - -#if defined(ARDUINO) && !defined(ARDUINO_ARCH_STM32) && !defined(ARDUINO_ARCH_SAM) - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include "../shared/Marduino.h" -#include "../shared/Delay.h" - -#include - -static uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock; -static volatile uint8_t *u8g_outData, *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 ^= 0xFF; - - u8g_bitNotData = u8g_bitData; - u8g_bitNotData ^= 0xFF; -} - -void u8g_spiSend_sw_AVR_mode_0(uint8_t val) { - uint8_t bitData = u8g_bitData, - bitNotData = u8g_bitNotData, - bitClock = u8g_bitClock, - bitNotClock = u8g_bitNotClock; - volatile uint8_t *outData = u8g_outData, - *outClock = u8g_outClock; - U8G_ATOMIC_START(); - LOOP_L_N(i, 8) { - if (val & 0x80) - *outData |= bitData; - else - *outData &= bitNotData; - *outClock |= bitClock; - val <<= 1; - *outClock &= bitNotClock; - } - U8G_ATOMIC_END(); -} - -void u8g_spiSend_sw_AVR_mode_3(uint8_t val) { - uint8_t bitData = u8g_bitData, - bitNotData = u8g_bitNotData, - bitClock = u8g_bitClock, - bitNotClock = u8g_bitNotClock; - volatile uint8_t *outData = u8g_outData, - *outClock = u8g_outClock; - U8G_ATOMIC_START(); - LOOP_L_N(i, 8) { - *outClock &= bitNotClock; - if (val & 0x80) - *outData |= bitData; - else - *outData &= bitNotData; - *outClock |= bitClock; - val <<= 1; - } - U8G_ATOMIC_END(); -} - - -#if ENABLED(FYSETC_MINI_12864) - #define SPISEND_SW_AVR u8g_spiSend_sw_AVR_mode_3 -#else - #define SPISEND_SW_AVR u8g_spiSend_sw_AVR_mode_0 -#endif - -uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - u8g_com_arduino_init_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK]); - u8g_com_arduino_assign_pin_output_high(u8g); - u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, 0); - u8g_com_arduino_digital_write(u8g, U8G_PI_MOSI, 0); - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - #if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0 - if (arg_val) { // SCK idle state needs to be set to the proper idle state before - // the next chip select goes active - u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active - u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW); - } - else { - u8g_com_arduino_digital_write(u8g, U8G_PI_CS, HIGH); - u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive - } - #else - u8g_com_arduino_digital_write(u8g, U8G_PI_CS, !arg_val); - #endif - break; - - case U8G_COM_MSG_WRITE_BYTE: - SPISEND_SW_AVR(arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - SPISEND_SW_AVR(*ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - SPISEND_SW_AVR(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; -} - -#endif // HAS_MARLINUI_U8GLIB -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/HAL.cpp b/src/HAL/DUE/HAL.cpp deleted file mode 100644 index 4353f16..0000000 --- a/src/HAL/DUE/HAL.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for Arduino Due and compatible (SAM3X8E) - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" -#include "../../MarlinCore.h" - -#include -#include "usb/usb_task.h" - -// ------------------------ -// Public Variables -// ------------------------ - -uint16_t MarlinHAL::adc_result; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(POSTMORTEM_DEBUGGING) - extern void install_min_serial(); -#endif - -void MarlinHAL::init() { - #if ENABLED(SDSUPPORT) - OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up - #endif - usb_task_init(); // Initialize the USB stack - TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler -} - -void MarlinHAL::init_board() { - #ifdef BOARD_INIT - BOARD_INIT(); - #endif -} - -void MarlinHAL::idletask() { usb_task_idle(); } // Perform USB stack housekeeping - -uint8_t MarlinHAL::get_reset_source() { - switch ((RSTC->RSTC_SR >> 8) & 0x07) { - case 0: return RST_POWER_ON; - case 1: return RST_BACKUP; - case 2: return RST_WATCHDOG; - case 3: return RST_SOFTWARE; - case 4: return RST_EXTERNAL; - default: return 0; - } -} - -void MarlinHAL::reboot() { rstc_start_software_reset(RSTC); } - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - // Initialize watchdog - On SAM3X, Watchdog was already configured - // and enabled or disabled at startup, so no need to reconfigure it - // here. - void MarlinHAL::watchdog_init() { WDT_Restart(WDT); } // Reset watchdog to start clean - - // Reset watchdog. MUST be called at least every 4 seconds after the - // first watchdog_init or AVR will go into emergency procedures. - void MarlinHAL::watchdog_refresh() { watchdogReset(); } - -#endif - -// Override Arduino runtime to either config or disable the watchdog -// -// We need to configure the watchdog as soon as possible in the boot -// process, because watchdog initialization at hardware reset on SAM3X8E -// is unreliable, and there is risk of unintended resets if we delay -// that initialization to a later time. -void watchdogSetup() { - - #if ENABLED(USE_WATCHDOG) - - // 4 seconds timeout - uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000); - - // Calculate timeout value in WDT counter ticks: This assumes - // the slow clock is running at 32.768 kHz watchdog - // frequency is therefore 32768 / 128 = 256 Hz - timeout = (timeout << 8) / 1000; - if (timeout == 0) - timeout = 1; - else if (timeout > 0xFFF) - timeout = 0xFFF; - - // We want to enable the watchdog with the specified timeout - uint32_t value = - WDT_MR_WDV(timeout) | // With the specified timeout - WDT_MR_WDD(timeout) | // and no invalid write window - #if !(SAMV70 || SAMV71 || SAME70 || SAMS70) - WDT_MR_WDRPROC | // WDT fault resets processor only - We want - // to keep PIO controller state - #endif - WDT_MR_WDDBGHLT | // WDT stops in debug state. - WDT_MR_WDIDLEHLT; // WDT stops in idle state. - - #if ENABLED(WATCHDOG_RESET_MANUAL) - // We enable the watchdog timer, but only for the interrupt. - - // Configure WDT to only trigger an interrupt - value |= WDT_MR_WDFIEN; // Enable WDT fault interrupt. - - // Disable WDT interrupt (just in case, to avoid triggering it!) - NVIC_DisableIRQ(WDT_IRQn); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - // Initialize WDT with the given parameters - WDT_Enable(WDT, value); - - // Configure and enable WDT interrupt. - NVIC_ClearPendingIRQ(WDT_IRQn); - NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups - NVIC_EnableIRQ(WDT_IRQn); - - #else - - // a WDT fault triggers a reset - value |= WDT_MR_WDRSTEN; - - // Initialize WDT with the given parameters - WDT_Enable(WDT, value); - - #endif - - // Reset the watchdog - WDT_Restart(WDT); - - #else - - // Make sure to completely disable the Watchdog - WDT_Disable(WDT); - - #endif -} - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -extern "C" { - extern unsigned int _ebss; // end of bss section -} - -// Return free memory between end of heap (or end bss) and whatever is current -int freeMemory() { - int free_memory, heap_end = (int)_sbrk(0); - return (int)&free_memory - (heap_end ?: (int)&_ebss); -} - -// ------------------------ -// Serial Ports -// ------------------------ - -// Forward the default serial ports -#if USING_HW_SERIAL0 - DefaultSerial1 MSerial0(false, Serial); -#endif -#if USING_HW_SERIAL1 - DefaultSerial2 MSerial1(false, Serial1); -#endif -#if USING_HW_SERIAL2 - DefaultSerial3 MSerial2(false, Serial2); -#endif -#if USING_HW_SERIAL3 - DefaultSerial4 MSerial3(false, Serial3); -#endif - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/HAL.h b/src/HAL/DUE/HAL.h deleted file mode 100644 index 4d3f482..0000000 --- a/src/HAL/DUE/HAL.h +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Arduino Due and compatible (SAM3X8E) - */ - -#define CPU_32_BIT - -#include "../shared/Marduino.h" -#include "../shared/eeprom_if.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" - -#include - -#include "../../core/serial_hook.h" - -// ------------------------ -// Serial ports -// ------------------------ - -typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1; -typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2; -typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3; -typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4; -extern DefaultSerial1 MSerial0; -extern DefaultSerial2 MSerial1; -extern DefaultSerial3 MSerial2; -extern DefaultSerial4 MSerial3; - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER) - #define MYSERIAL1 customizedSerial1 -#elif WITHIN(SERIAL_PORT, 0, 3) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #error "The required SERIAL_PORT must be from 0 to 3, or -1 for USB Serial." -#endif - -#ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER) - #define MYSERIAL2 customizedSerial2 - #elif WITHIN(SERIAL_PORT_2, 0, 3) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial." - #endif -#endif - -#ifdef SERIAL_PORT_3 - #if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER) - #define MYSERIAL3 customizedSerial3 - #elif WITHIN(SERIAL_PORT_3, 0, 3) - #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) - #else - #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial." - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if WITHIN(MMU2_SERIAL_PORT, 0, 3) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #else - #error "MMU2_SERIAL_PORT must be from 0 to 3." - #endif -#endif - -#ifdef LCD_SERIAL_PORT - #if WITHIN(LCD_SERIAL_PORT, 0, 3) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #else - #error "LCD_SERIAL_PORT must be from 0 to 3." - #endif -#endif - -#include "MarlinSerial.h" -#include "MarlinSerialUSB.h" - -// ------------------------ -// Types -// ------------------------ - -typedef int8_t pin_t; - -#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp - -class Servo; -typedef Servo hal_servo_t; - -// -// Interrupts -// -#define sei() interrupts() -#define cli() noInterrupts() - -#define CRITICAL_SECTION_START() const bool _irqon = hal.isr_state(); hal.isr_off() -#define CRITICAL_SECTION_END() if (_irqon) hal.isr_on() - -// -// ADC -// -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 - -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) -#endif - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -// -// Tone -// -void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0); -void noTone(const pin_t _pin); - -// ------------------------ -// Class Utilities -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -#pragma GCC diagnostic pop - -#ifdef __cplusplus - extern "C" { -#endif -char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s); -#ifdef __cplusplus - } -#endif - -// Return free RAM between end of heap (or end bss) and whatever is current -int freeMemory(); - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init(); // Called early in setup() - static void init_board(); // Called less early in setup() - static void reboot(); // Restart the firmware - - // Interrupts - static bool isr_state() { return !__get_PRIMASK(); } - static void isr_on() { __enable_irq(); } - static void isr_off() { __disable_irq(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask(); - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint16_t adc_result; - - // Called by Temperature::init once at startup - static void adc_init() {} - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const uint8_t ch) {} - - // Begin ADC sampling on the given channel. Called from Temperature::isr! - static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); } - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return adc_result; } - - /** - * Set the PWM duty cycle for the pin to the given value. - * No inverting the duty cycle in this HAL. - * No changing the maximum size of the provided value to enable finer PWM duty control in this HAL. - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -}; diff --git a/src/HAL/DUE/HAL_SPI.cpp b/src/HAL/DUE/HAL_SPI.cpp deleted file mode 100644 index 7e3fe01..0000000 --- a/src/HAL/DUE/HAL_SPI.cpp +++ /dev/null @@ -1,819 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Software SPI functions originally from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - * - * Completely rewritten and tuned by Eduardo José Tagle in 2017/2018 - * in ARM thumb2 inline assembler and tuned for maximum speed and performance - * allowing SPI clocks of up to 12 Mhz to increase SD card read/write performance - */ - -/** - * HAL for Arduino Due and compatible (SAM3X8E) - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" -#include "../shared/Delay.h" - -// ------------------------ -// Public functions -// ------------------------ - -#if EITHER(DUE_SOFTWARE_SPI, FORCE_SOFT_SPI) - - // ------------------------ - // Software SPI - // ------------------------ - - // Make sure GCC optimizes this file. - // Note that this line triggers a bug in GCC which is fixed by casting. - // See the note below. - #pragma GCC optimize (3) - - typedef uint8_t (*pfnSpiTransfer)(uint8_t b); - typedef void (*pfnSpiRxBlock)(uint8_t *buf, uint32_t nbyte); - typedef void (*pfnSpiTxBlock)(const uint8_t *buf, uint32_t nbyte); - - /* ---------------- Macros to be able to access definitions from asm */ - #define _PORT(IO) DIO ## IO ## _WPORT - #define _PIN_MASK(IO) MASK(DIO ## IO ## _PIN) - #define _PIN_SHIFT(IO) DIO ## IO ## _PIN - #define PORT(IO) _PORT(IO) - #define PIN_MASK(IO) _PIN_MASK(IO) - #define PIN_SHIFT(IO) _PIN_SHIFT(IO) - - // run at ~8 .. ~10Mhz - Tx version (Rx data discarded) - static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0 - uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */ - uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN); - uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */ - uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN); - uint32_t idx = 0; - - /* Negate bout, as the assembler requires a negated value */ - bout = ~bout; - - /* The software SPI routine */ - __asm__ __volatile__( - A(".syntax unified") // is to prevent CM0,CM1 non-unified syntax - - /* Bit 7 */ - A("ubfx %[idx],%[txval],#7,#1") /* Place bit 7 in bit 0 of idx*/ - - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#6,#1") /* Place bit 6 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 6 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#5,#1") /* Place bit 5 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 5 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#4,#1") /* Place bit 4 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 4 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#3,#1") /* Place bit 3 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 3 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#2,#1") /* Place bit 2 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 2 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#1,#1") /* Place bit 1 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 1 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[idx],%[txval],#0,#1") /* Place bit 0 in bit 0 of idx*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 0 */ - A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("nop") /* Result will be 0 */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - : [idx]"+r"( idx ) - : [txval]"r"( bout ) , - [mosi_mask]"r"( MOSI_MASK ), - [mosi_port]"r"( MOSI_PORT_PLUS30 ), - [sck_mask]"r"( SCK_MASK ), - [sck_port]"r"( SCK_PORT_PLUS30 ) - : "cc" - ); - - return 0; - } - - // Calculates the bit band alias address and returns a pointer address to word. - // addr: The byte address of bitbanding bit. - // bit: The bit position of bitbanding bit. - #define BITBAND_ADDRESS(addr, bit) \ - (((uint32_t)(addr) & 0xF0000000) + 0x02000000 + ((uint32_t)(addr)&0xFFFFF)*32 + (bit)*4) - - // run at ~8 .. ~10Mhz - Rx version (Tx line not altered) - static uint8_t spiTransferRx0(uint8_t) { // using Mode 0 - uint32_t bin = 0; - uint32_t work = 0; - uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */ - uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */ - uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN); - - /* The software SPI routine */ - __asm__ __volatile__( - A(".syntax unified") // is to prevent CM0,CM1 non-unified syntax - - /* bit 7 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#7,#1") /* Store read bit as the bit 7 */ - - /* bit 6 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#6,#1") /* Store read bit as the bit 6 */ - - /* bit 5 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#5,#1") /* Store read bit as the bit 5 */ - - /* bit 4 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#4,#1") /* Store read bit as the bit 4 */ - - /* bit 3 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#3,#1") /* Store read bit as the bit 3 */ - - /* bit 2 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#2,#1") /* Store read bit as the bit 2 */ - - /* bit 1 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#1,#1") /* Store read bit as the bit 1 */ - - /* bit 0 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#0,#1") /* Store read bit as the bit 0 */ - - : [bin]"+r"(bin), - [work]"+r"(work) - : [bitband_miso_port]"r"( BITBAND_MISO_PORT ), - [sck_mask]"r"( SCK_MASK ), - [sck_port]"r"( SCK_PORT_PLUS30 ) - : "cc" - ); - - return bin; - } - - // run at ~4Mhz - static uint8_t spiTransfer1(uint8_t b) { // using Mode 0 - int bits = 8; - do { - WRITE(SD_MOSI_PIN, b & 0x80); - b <<= 1; // little setup time - - WRITE(SD_SCK_PIN, HIGH); - DELAY_NS(125); // 10 cycles @ 84mhz - - b |= (READ(SD_MISO_PIN) != 0); - - WRITE(SD_SCK_PIN, LOW); - DELAY_NS(125); // 10 cycles @ 84mhz - } while (--bits); - return b; - } - - // all the others - static uint16_t spiDelayNS = 4000; // 4000ns => 125khz - - static uint8_t spiTransferX(uint8_t b) { // using Mode 0 - int bits = 8; - do { - WRITE(SD_MOSI_PIN, b & 0x80); - b <<= 1; // little setup time - - WRITE(SD_SCK_PIN, HIGH); - DELAY_NS(spiDelayNS); - - b |= (READ(SD_MISO_PIN) != 0); - - WRITE(SD_SCK_PIN, LOW); - DELAY_NS(spiDelayNS); - } while (--bits); - return b; - } - - // Pointers to generic functions for byte transfers - - /** - * Note: The cast is unnecessary, but without it, this file triggers a GCC 4.8.3-2014 bug. - * Later GCC versions do not have this problem, but at this time (May 2018) Arduino still - * uses that buggy and obsolete GCC version!! - */ - static pfnSpiTransfer spiTransferRx = (pfnSpiTransfer)spiTransferX; - static pfnSpiTransfer spiTransferTx = (pfnSpiTransfer)spiTransferX; - - // Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded) - static void spiTxBlock0(const uint8_t *ptr, uint32_t todo) { - uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */ - uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN); - uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */ - uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN); - uint32_t work = 0; - uint32_t txval = 0; - - /* The software SPI routine */ - __asm__ __volatile__( - A(".syntax unified") // is to prevent CM0,CM1 non-unified syntax - - L("loop%=") - A("ldrb.w %[txval], [%[ptr]], #1") /* Load value to send, increment buffer */ - A("mvn %[txval],%[txval]") /* Negate value */ - - /* Bit 7 */ - A("ubfx %[work],%[txval],#7,#1") /* Place bit 7 in bit 0 of work*/ - - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#6,#1") /* Place bit 6 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 6 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#5,#1") /* Place bit 5 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 5 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#4,#1") /* Place bit 4 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 4 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#3,#1") /* Place bit 3 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 3 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#2,#1") /* Place bit 2 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 2 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#1,#1") /* Place bit 1 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 1 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ubfx %[work],%[txval],#0,#1") /* Place bit 0 in bit 0 of work*/ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - - /* Bit 0 */ - A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("subs %[todo],#1") /* Decrement count of pending words to send, update status */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bne.n loop%=") /* Repeat until done */ - - : [ptr]"+r" ( ptr ) , - [todo]"+r" ( todo ) , - [work]"+r"( work ) , - [txval]"+r"( txval ) - : [mosi_mask]"r"( MOSI_MASK ), - [mosi_port]"r"( MOSI_PORT_PLUS30 ), - [sck_mask]"r"( SCK_MASK ), - [sck_port]"r"( SCK_PORT_PLUS30 ) - : "cc" - ); - } - - static void spiRxBlock0(uint8_t *ptr, uint32_t todo) { - uint32_t bin = 0; - uint32_t work = 0; - uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */ - uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */ - uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN); - - /* The software SPI routine */ - __asm__ __volatile__( - A(".syntax unified") // is to prevent CM0,CM1 non-unified syntax - - L("loop%=") - - /* bit 7 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#7,#1") /* Store read bit as the bit 7 */ - - /* bit 6 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#6,#1") /* Store read bit as the bit 6 */ - - /* bit 5 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#5,#1") /* Store read bit as the bit 5 */ - - /* bit 4 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#4,#1") /* Store read bit as the bit 4 */ - - /* bit 3 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#3,#1") /* Store read bit as the bit 3 */ - - /* bit 2 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#2,#1") /* Store read bit as the bit 2 */ - - /* bit 1 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#1,#1") /* Store read bit as the bit 1 */ - - /* bit 0 */ - A("str %[sck_mask],[%[sck_port]]") /* SODR */ - A("ldr %[work],[%[bitband_miso_port]]") /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ - A("str %[sck_mask],[%[sck_port],#0x4]") /* CODR */ - A("bfi %[bin],%[work],#0,#1") /* Store read bit as the bit 0 */ - - A("subs %[todo],#1") /* Decrement count of pending words to send, update status */ - A("strb.w %[bin], [%[ptr]], #1") /* Store read value into buffer, increment buffer pointer */ - A("bne.n loop%=") /* Repeat until done */ - - : [ptr]"+r"(ptr), - [todo]"+r"(todo), - [bin]"+r"(bin), - [work]"+r"(work) - : [bitband_miso_port]"r"( BITBAND_MISO_PORT ), - [sck_mask]"r"( SCK_MASK ), - [sck_port]"r"( SCK_PORT_PLUS30 ) - : "cc" - ); - } - - static void spiTxBlockX(const uint8_t *buf, uint32_t todo) { - do { - (void)spiTransferTx(*buf++); - } while (--todo); - } - - static void spiRxBlockX(uint8_t *buf, uint32_t todo) { - do { - *buf++ = spiTransferRx(0xFF); - } while (--todo); - } - - // Pointers to generic functions for block transfers - static pfnSpiTxBlock spiTxBlock = (pfnSpiTxBlock)spiTxBlockX; - static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX; - - #if MB(ALLIGATOR) - #define _SS_WRITE(S) WRITE(SD_SS_PIN, S) - #else - #define _SS_WRITE(S) NOOP - #endif - - void spiBegin() { - SET_OUTPUT(SD_SS_PIN); - _SS_WRITE(HIGH); - SET_OUTPUT(SD_SCK_PIN); - SET_INPUT(SD_MISO_PIN); - SET_OUTPUT(SD_MOSI_PIN); - } - - uint8_t spiRec() { - _SS_WRITE(LOW); - WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1 - uint8_t b = spiTransferRx(0xFF); - _SS_WRITE(HIGH); - return b; - } - - void spiRead(uint8_t *buf, uint16_t nbyte) { - if (nbyte) { - _SS_WRITE(LOW); - WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1 - spiRxBlock(buf, nbyte); - _SS_WRITE(HIGH); - } - } - - void spiSend(uint8_t b) { - _SS_WRITE(LOW); - (void)spiTransferTx(b); - _SS_WRITE(HIGH); - } - - void spiSendBlock(uint8_t token, const uint8_t *buf) { - _SS_WRITE(LOW); - (void)spiTransferTx(token); - spiTxBlock(buf, 512); - _SS_WRITE(HIGH); - } - - /** - * spiRate should be - * 0 : 8 - 10 MHz - * 1 : 4 - 5 MHz - * 2 : 2 - 2.5 MHz - * 3 : 1 - 1.25 MHz - * 4 : 500 - 625 kHz - * 5 : 250 - 312 kHz - * 6 : 125 - 156 kHz - */ - void spiInit(uint8_t spiRate) { - switch (spiRate) { - case 0: - spiTransferTx = (pfnSpiTransfer)spiTransferTx0; - spiTransferRx = (pfnSpiTransfer)spiTransferRx0; - spiTxBlock = (pfnSpiTxBlock)spiTxBlock0; - spiRxBlock = (pfnSpiRxBlock)spiRxBlock0; - break; - case 1: - spiTransferTx = (pfnSpiTransfer)spiTransfer1; - spiTransferRx = (pfnSpiTransfer)spiTransfer1; - spiTxBlock = (pfnSpiTxBlock)spiTxBlockX; - spiRxBlock = (pfnSpiRxBlock)spiRxBlockX; - break; - default: - spiDelayNS = 4000 >> (6 - spiRate); // spiRate of 2 gives the maximum error with current CPU - spiTransferTx = (pfnSpiTransfer)spiTransferX; - spiTransferRx = (pfnSpiTransfer)spiTransferX; - spiTxBlock = (pfnSpiTxBlock)spiTxBlockX; - spiRxBlock = (pfnSpiRxBlock)spiRxBlockX; - break; - } - - _SS_WRITE(HIGH); - WRITE(SD_MOSI_PIN, HIGH); - WRITE(SD_SCK_PIN, LOW); - } - - /** Begin SPI transaction, set clock, bit order, data mode */ - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - // TODO: to be implemented - } - - #pragma GCC reset_options - -#else // !SOFTWARE_SPI - - #define WHILE_TX(N) while ((SPI0->SPI_SR & SPI_SR_TDRE) == (N)) - #define WHILE_RX(N) while ((SPI0->SPI_SR & SPI_SR_RDRF) == (N)) - #define FLUSH_TX() do{ WHILE_RX(1) SPI0->SPI_RDR; }while(0) - - #if MB(ALLIGATOR) - - // slave selects controlled by SPI controller - // doesn't support changing SPI speeds for SD card - - // ------------------------ - // hardware SPI - // ------------------------ - static bool spiInitialized = false; - - void spiInit(uint8_t spiRate) { - if (spiInitialized) return; - - // 8.4 MHz, 4 MHz, 2 MHz, 1 MHz, 0.5 MHz, 0.329 MHz, 0.329 MHz - constexpr int spiDivider[] = { 10, 21, 42, 84, 168, 255, 255 }; - if (spiRate > 6) spiRate = 1; - - // Set SPI mode 1, clock, select not active after transfer, with delay between transfers - SPI_ConfigureNPCS(SPI0, SPI_CHAN_DAC, - SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDivider[spiRate]) | - SPI_CSR_DLYBCT(1)); - // Set SPI mode 0, clock, select not active after transfer, with delay between transfers - SPI_ConfigureNPCS(SPI0, SPI_CHAN_EEPROM1, SPI_CSR_NCPHA | - SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDivider[spiRate]) | - SPI_CSR_DLYBCT(1)); - - // Set SPI mode 0, clock, select not active after transfer, with delay between transfers - SPI_ConfigureNPCS(SPI0, SPI_CHAN, SPI_CSR_NCPHA | - SPI_CSR_CSAAT | SPI_CSR_SCBR(spiDivider[spiRate]) | - SPI_CSR_DLYBCT(1)); - SPI_Enable(SPI0); - spiInitialized = true; - } - - void spiBegin() { - if (spiInitialized) return; - - // Configure SPI pins - PIO_Configure( - g_APinDescription[SD_SCK_PIN].pPort, - g_APinDescription[SD_SCK_PIN].ulPinType, - g_APinDescription[SD_SCK_PIN].ulPin, - g_APinDescription[SD_SCK_PIN].ulPinConfiguration); - PIO_Configure( - g_APinDescription[SD_MOSI_PIN].pPort, - g_APinDescription[SD_MOSI_PIN].ulPinType, - g_APinDescription[SD_MOSI_PIN].ulPin, - g_APinDescription[SD_MOSI_PIN].ulPinConfiguration); - PIO_Configure( - g_APinDescription[SD_MISO_PIN].pPort, - g_APinDescription[SD_MISO_PIN].ulPinType, - g_APinDescription[SD_MISO_PIN].ulPin, - g_APinDescription[SD_MISO_PIN].ulPinConfiguration); - - // set master mode, peripheral select, fault detection - SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS); - SPI_Enable(SPI0); - - SET_OUTPUT(DAC0_SYNC_PIN); - #if HAS_MULTI_EXTRUDER - OUT_WRITE(DAC1_SYNC_PIN, HIGH); - #endif - WRITE(DAC0_SYNC_PIN, HIGH); - OUT_WRITE(SPI_EEPROM1_CS_PIN, HIGH); - OUT_WRITE(SPI_EEPROM2_CS_PIN, HIGH); - OUT_WRITE(SPI_FLASH_CS_PIN, HIGH); - WRITE(SD_SS_PIN, HIGH); - - OUT_WRITE(SDSS, LOW); - - PIO_Configure( - g_APinDescription[SPI_PIN].pPort, - g_APinDescription[SPI_PIN].ulPinType, - g_APinDescription[SPI_PIN].ulPin, - g_APinDescription[SPI_PIN].ulPinConfiguration - ); - - spiInit(1); - } - - // Read single byte from SPI - uint8_t spiRec() { - // write dummy byte with address and end transmission flag - SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER; - - WHILE_TX(0); - WHILE_RX(0); - - //DELAY_US(1U); - return SPI0->SPI_RDR; - } - - uint8_t spiRec(uint32_t chan) { - - WHILE_TX(0); - FLUSH_RX(); - - // write dummy byte with address and end transmission flag - SPI0->SPI_TDR = 0x000000FF | SPI_PCS(chan) | SPI_TDR_LASTXFER; - WHILE_RX(0); - - return SPI0->SPI_RDR; - } - - // Read from SPI into buffer - void spiRead(uint8_t *buf, uint16_t nbyte) { - if (!nbyte) return; - --nbyte; - for (int i = 0; i < nbyte; i++) { - //WHILE_TX(0); - SPI0->SPI_TDR = 0x000000FF | SPI_PCS(SPI_CHAN); - WHILE_RX(0); - buf[i] = SPI0->SPI_RDR; - //DELAY_US(1U); - } - buf[nbyte] = spiRec(); - } - - // Write single byte to SPI - void spiSend(const byte b) { - // write byte with address and end transmission flag - SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(SPI_CHAN) | SPI_TDR_LASTXFER; - WHILE_TX(0); - WHILE_RX(0); - SPI0->SPI_RDR; - //DELAY_US(1U); - } - - void spiSend(const uint8_t *buf, size_t nbyte) { - if (!nbyte) return; - --nbyte; - for (size_t i = 0; i < nbyte; i++) { - SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN); - WHILE_TX(0); - WHILE_RX(0); - SPI0->SPI_RDR; - //DELAY_US(1U); - } - spiSend(buf[nbyte]); - } - - void spiSend(uint32_t chan, byte b) { - WHILE_TX(0); - // write byte with address and end transmission flag - SPI0->SPI_TDR = (uint32_t)b | SPI_PCS(chan) | SPI_TDR_LASTXFER; - WHILE_RX(0); - FLUSH_RX(); - } - - void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) { - if (!nbyte) return; - --nbyte; - for (size_t i = 0; i < nbyte; i++) { - WHILE_TX(0); - SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(chan); - WHILE_RX(0); - FLUSH_RX(); - } - spiSend(chan, buf[nbyte]); - } - - // Write from buffer to SPI - void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI0->SPI_TDR = (uint32_t)token | SPI_PCS(SPI_CHAN); - WHILE_TX(0); - //WHILE_RX(0); - //SPI0->SPI_RDR; - for (int i = 0; i < 511; i++) { - SPI0->SPI_TDR = (uint32_t)buf[i] | SPI_PCS(SPI_CHAN); - WHILE_TX(0); - WHILE_RX(0); - SPI0->SPI_RDR; - //DELAY_US(1U); - } - spiSend(buf[511]); - } - - /** Begin SPI transaction, set clock, bit order, data mode */ - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - // TODO: to be implemented - } - - #else // U8G compatible hardware SPI - - #define SPI_MODE_0_DUE_HW 2 // DUE CPHA control bit is inverted - #define SPI_MODE_1_DUE_HW 3 - #define SPI_MODE_2_DUE_HW 0 - #define SPI_MODE_3_DUE_HW 1 - - /** - * The DUE SPI controller is set up so the upper word of the longword - * written to the transmit data register selects which SPI Chip Select - * Register is used. This allows different streams to have different SPI - * settings. - * - * In practice it's spooky. Some combinations hang the system, while others - * upset the peripheral device. - * - * SPI mode should be the same for all streams. The FYSETC_MINI_12864 gets - * upset if the clock phase changes after chip select goes active. - * - * SPI_CSR_CSAAT should be set for all streams. If not the WHILE_TX(0) - * macro returns immediately which can result in the SPI chip select going - * inactive before all the data has been sent. - * - * The TMC2130 library uses SPI0->SPI_CSR[3]. - * - * The U8G hardware SPI uses SPI0->SPI_CSR[0]. The system hangs and/or the - * FYSETC_MINI_12864 gets upset if lower baud rates are used and the SD card - * is inserted or removed. - * - * The SD card uses SPI0->SPI_CSR[3]. Efforts were made to use [1] and [2] - * but they all resulted in hangs or garbage on the LCD. - * - * The SPI controlled chip selects are NOT enabled in the GPIO controller. - * The application must control the chip select. - * - * All of the above can be avoided by defining FORCE_SOFT_SPI to force the - * display to use software SPI. - */ - - void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified) - // Also sets U8G SPI rate to 4MHz and the SPI mode to 3 - - // 8.4 MHz, 4 MHz, 2 MHz, 1 MHz, 0.5 MHz, 0.329 MHz, 0.329 MHz - constexpr int spiDivider[] = { 10, 21, 42, 84, 168, 255, 255 }; - if (spiRate > 6) spiRate = 1; - - // Enable PIOA and SPI0 - REG_PMC_PCER0 = (1UL << ID_PIOA) | (1UL << ID_SPI0); - - // Disable PIO on A26 and A27 - REG_PIOA_PDR = 0x0C000000; - OUT_WRITE(SDSS, HIGH); - - // 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; - - // TMC2103 compatible setup - // Master mode, no fault detection, PCS bits in data written to TDR select CSR register - SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS; - // SPI mode 3, 8 Bit data transfer, baud rate - SPI0->SPI_CSR[3] = SPI_CSR_SCBR(spiDivider[spiRate]) | SPI_CSR_CSAAT | SPI_MODE_3_DUE_HW; // use same CSR as TMC2130 - SPI0->SPI_CSR[0] = SPI_CSR_SCBR(spiDivider[1]) | SPI_CSR_CSAAT | SPI_MODE_3_DUE_HW; // U8G default to 4MHz - } - - void spiBegin() { spiInit(); } - - static uint8_t spiTransfer(uint8_t data) { - WHILE_TX(0); - SPI0->SPI_TDR = (uint32_t)data | 0x00070000UL; // Add TMC2130 PCS bits to every byte (use SPI0->SPI_CSR[3]) - WHILE_TX(0); - WHILE_RX(0); - return SPI0->SPI_RDR; - } - - uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); } - - void spiRead(uint8_t *buf, uint16_t nbyte) { - for (int i = 0; i < nbyte; i++) - buf[i] = spiTransfer(0xFF); - } - - void spiSend(uint8_t data) { spiTransfer(data); } - - void spiSend(const uint8_t *buf, size_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) - spiTransfer(buf[i]); - } - - void spiSendBlock(uint8_t token, const uint8_t *buf) { - spiTransfer(token); - for (uint16_t i = 0; i < 512; i++) - spiTransfer(buf[i]); - } - - #endif // !ALLIGATOR -#endif // !SOFTWARE_SPI - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/InterruptVectors.cpp b/src/HAL/DUE/InterruptVectors.cpp deleted file mode 100644 index e4e0ce9..0000000 --- a/src/HAL/DUE/InterruptVectors.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * InterruptVectors_Due.cpp - This module relocates the Interrupt vector table to SRAM, - * allowing to register new interrupt handlers at runtime. Specially valuable and needed - * because Arduino runtime allocates some interrupt handlers that we NEED to override to - * properly support extended functionality, as for example, USB host or USB device (MSD, MTP) - * and custom serial port handlers, and we don't actually want to modify and/or recompile the - * Arduino runtime. We just want to run as much as possible on Stock Arduino - * - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" -#include "InterruptVectors.h" - -/* The relocated Exception/Interrupt Table - According to the ARM - reference manual, alignment to 128 bytes should suffice, but in - practice, we need alignment to 256 bytes to make this work in all - cases */ -__attribute__ ((aligned(256))) -static DeviceVectors ram_tab = { nullptr }; - -/** - * This function checks if the exception/interrupt table is already in SRAM or not. - * If it is not, then it copies the ROM table to the SRAM and relocates the table - * by reprogramming the NVIC registers - */ -static pfnISR_Handler* get_relocated_table_addr() { - // Get the address of the interrupt/exception table - uint32_t isrtab = SCB->VTOR; - - // If already relocated, we are done! - if (isrtab >= IRAM0_ADDR) - return (pfnISR_Handler*)isrtab; - - // Get the address of the table stored in FLASH - const pfnISR_Handler* romtab = (const pfnISR_Handler*)isrtab; - - // Copy it to SRAM - memcpy(&ram_tab, romtab, sizeof(ram_tab)); - - // Disable global interrupts - CRITICAL_SECTION_START(); - - // Set the vector table base address to the SRAM copy - SCB->VTOR = (uint32_t)(&ram_tab); - - // Reenable interrupts - CRITICAL_SECTION_END(); - - // Return the address of the table - return (pfnISR_Handler*)(&ram_tab); -} - -pfnISR_Handler install_isr(IRQn_Type irq, pfnISR_Handler newHandler) { - // Get the address of the relocated table - pfnISR_Handler *isrtab = get_relocated_table_addr(); - - // Disable global interrupts - CRITICAL_SECTION_START(); - - // Get the original handler - pfnISR_Handler oldHandler = isrtab[irq + 16]; - - // Install the new one - isrtab[irq + 16] = newHandler; - - // Reenable interrupts - CRITICAL_SECTION_END(); - - // Return the original one - return oldHandler; -} - -#endif diff --git a/src/HAL/DUE/InterruptVectors.h b/src/HAL/DUE/InterruptVectors.h deleted file mode 100644 index 6faeb34..0000000 --- a/src/HAL/DUE/InterruptVectors.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * InterruptVectors_Due.h - * - * This module relocates the Interrupt vector table to SRAM, allowing new - * interrupt handlers to be added at runtime. This is required because the - * Arduino runtime steals interrupt handlers that Marlin MUST use to support - * extended functionality such as USB hosts and USB devices (MSD, MTP) and - * custom serial port handlers. Rather than modifying and/or recompiling the - * Arduino runtime, We just want to run as much as possible on Stock Arduino. - * - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - */ - -#ifdef ARDUINO_ARCH_SAM - -// ISR handler type -typedef void (*pfnISR_Handler)(); - -// Install a new interrupt vector handler for the given irq, returning the old one -pfnISR_Handler install_isr(IRQn_Type irq, pfnISR_Handler newHandler); - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/MarlinSPI.h b/src/HAL/DUE/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/DUE/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/DUE/MarlinSerial.cpp b/src/HAL/DUE/MarlinSerial.cpp deleted file mode 100644 index 638f7a1..0000000 --- a/src/HAL/DUE/MarlinSerial.cpp +++ /dev/null @@ -1,494 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - * Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved. - */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" - -#include "MarlinSerial.h" -#include "InterruptVectors.h" -#include "../../MarlinCore.h" - -template typename MarlinSerial::ring_buffer_r MarlinSerial::rx_buffer = { 0, 0, { 0 } }; -template typename MarlinSerial::ring_buffer_t MarlinSerial::tx_buffer = { 0 }; -template bool MarlinSerial::_written = false; -template uint8_t MarlinSerial::xon_xoff_state = MarlinSerial::XON_XOFF_CHAR_SENT | MarlinSerial::XON_CHAR; -template uint8_t MarlinSerial::rx_dropped_bytes = 0; -template uint8_t MarlinSerial::rx_buffer_overruns = 0; -template uint8_t MarlinSerial::rx_framing_errors = 0; -template typename MarlinSerial::ring_buffer_pos_t MarlinSerial::rx_max_enqueued = 0; - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() asm volatile("": : :"memory"); - -#include "../../feature/e_parser.h" - -// (called with RX interrupts disabled) -template -FORCE_INLINE void MarlinSerial::store_rxd_char() { - - static EmergencyParser::State emergency_state; // = EP_RESET - - // Get the tail - Nothing can alter its value while we are at this ISR - const ring_buffer_pos_t t = rx_buffer.tail; - - // Get the head pointer - ring_buffer_pos_t h = rx_buffer.head; - - // Get the next element - ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - uint8_t c = HWUART->UART_RHR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the RX FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - // Calculate count of bytes stored into the RX buffer - - // Keep track of the maximum count of enqueued bytes - if (Cfg::MAX_RX_QUEUED) NOLESS(rx_max_enqueued, rx_count); - - if (Cfg::XONOFF) { - // If the last char that was sent was an XON - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) { - - // Bytes stored into the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // If over 12.5% of RX buffer capacity, send XOFF before running out of - // RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react - // and stop sending bytes. This translates to 13mS propagation time. - if (rx_count >= (Cfg::RX_SIZE) / 8) { - - // At this point, definitely no TX interrupt was executing, since the TX isr can't be preempted. - // Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens - // to be in the middle of trying to disable the RX interrupt in the main program, eventually the - // enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure - // the sending of the XOFF char is to send it HERE AND NOW. - - // About to send the XOFF char - xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT; - - // Wait until the TX register becomes empty and send it - Here there could be a problem - // - While waiting for the TX register to empty, the RX register could receive a new - // character. This must also handle that situation! - uint32_t status; - while (!((status = HWUART->UART_SR) & UART_SR_TXRDY)) { - - if (status & UART_SR_RXRDY) { - // We received a char while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = HWUART->UART_RHR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - HWUART->UART_THR = XOFF_CHAR; - - // At this point there could be a race condition between the write() function - // and this sending of the XOFF char. This interrupt could happen between the - // wait to be empty TX buffer loop and the actual write of the character. Since - // the TX buffer is full because it's sending the XOFF char, the only way to be - // sure the write() function will succeed is to wait for the XOFF char to be - // completely sent. Since an extra character could be received during the wait - // it must also be handled! - while (!((status = HWUART->UART_SR) & UART_SR_TXRDY)) { - - if (status & UART_SR_RXRDY) { - // A char arrived while waiting for the TX buffer to be empty - Receive and process it! - - i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - - // Read the character from the USART - c = HWUART->UART_RHR; - - if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c); - - // If the character is to be stored at the index just before the tail - // (such that the head would advance to the current tail), the FIFO is - // full, so don't write the character or advance the head. - if (i != t) { - rx_buffer.buffer[h] = c; - h = i; - } - else if (Cfg::DROPPED_RX && !++rx_dropped_bytes) - --rx_dropped_bytes; - } - sw_barrier(); - } - - // At this point everything is ready. The write() function won't - // have any issues writing to the UART TX register if it needs to! - } - } - } - - // Store the new head value - rx_buffer.head = h; -} - -template -FORCE_INLINE void MarlinSerial::_tx_thr_empty_irq() { - if (Cfg::TX_SIZE > 0) { - // Read positions - uint8_t t = tx_buffer.tail; - const uint8_t h = tx_buffer.head; - - if (Cfg::XONOFF) { - // If an XON char is pending to be sent, do it now - if (xon_xoff_state == XON_CHAR) { - - // Send the character - HWUART->UART_THR = XON_CHAR; - - // Remember we sent it. - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - - // If nothing else to transmit, just disable TX interrupts. - if (h == t) HWUART->UART_IDR = UART_IDR_TXRDY; - - return; - } - } - - // If nothing to transmit, just disable TX interrupts. This could - // happen as the result of the non atomicity of the disabling of RX - // interrupts that could end reenabling TX interrupts as a side effect. - if (h == t) { - HWUART->UART_IDR = UART_IDR_TXRDY; - return; - } - - // There is something to TX, Send the next byte - const uint8_t c = tx_buffer.buffer[t]; - t = (t + 1) & (Cfg::TX_SIZE - 1); - HWUART->UART_THR = c; - tx_buffer.tail = t; - - // Disable interrupts if there is nothing to transmit following this byte - if (h == t) HWUART->UART_IDR = UART_IDR_TXRDY; - } -} - -template -void MarlinSerial::UART_ISR() { - const uint32_t status = HWUART->UART_SR; - - // Data received? - if (status & UART_SR_RXRDY) store_rxd_char(); - - if (Cfg::TX_SIZE > 0) { - // Something to send, and TX interrupts are enabled (meaning something to send)? - if ((status & UART_SR_TXRDY) && (HWUART->UART_IMR & UART_IMR_TXRDY)) _tx_thr_empty_irq(); - } - - // Acknowledge errors - if ((status & UART_SR_OVRE) || (status & UART_SR_FRAME)) { - if (Cfg::DROPPED_RX && (status & UART_SR_OVRE) && !++rx_dropped_bytes) --rx_dropped_bytes; - if (Cfg::RX_OVERRUNS && (status & UART_SR_OVRE) && !++rx_buffer_overruns) --rx_buffer_overruns; - if (Cfg::RX_FRAMING_ERRORS && (status & UART_SR_FRAME) && !++rx_framing_errors) --rx_framing_errors; - - // TODO: error reporting outside ISR - HWUART->UART_CR = UART_CR_RSTSTA; - } -} - -// Public Methods -template -void MarlinSerial::begin(const long baud_setting) { - - // Disable UART interrupt in NVIC - NVIC_DisableIRQ( HWUART_IRQ ); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - // Disable clock - pmc_disable_periph_clk( HWUART_IRQ_ID ); - - // Configure PMC - pmc_enable_periph_clk( HWUART_IRQ_ID ); - - // Disable PDC channel - HWUART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; - - // Reset and disable receiver and transmitter - HWUART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS; - - // Configure mode: 8bit, No parity, 1 bit stop - HWUART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO; - - // Configure baudrate (asynchronous, no oversampling) - HWUART->UART_BRGR = (SystemCoreClock / (baud_setting << 4)); - - // Configure interrupts - HWUART->UART_IDR = 0xFFFFFFFF; - HWUART->UART_IER = UART_IER_RXRDY | UART_IER_OVRE | UART_IER_FRAME; - - // Install interrupt handler - install_isr(HWUART_IRQ, UART_ISR); - - // Configure priority. We need a very high priority to avoid losing characters - // and we need to be able to preempt the Stepper ISR and everything else! - // (this could probably be fixed by using DMA with the Serial port) - NVIC_SetPriority(HWUART_IRQ, 1); - - // Enable UART interrupt in NVIC - NVIC_EnableIRQ(HWUART_IRQ); - - // Enable receiver and transmitter - HWUART->UART_CR = UART_CR_RXEN | UART_CR_TXEN; - - if (Cfg::TX_SIZE > 0) _written = false; -} - -template -void MarlinSerial::end() { - // Disable UART interrupt in NVIC - NVIC_DisableIRQ( HWUART_IRQ ); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - pmc_disable_periph_clk( HWUART_IRQ_ID ); -} - -template -int MarlinSerial::peek() { - const int v = rx_buffer.head == rx_buffer.tail ? -1 : rx_buffer.buffer[rx_buffer.tail]; - return v; -} - -template -int MarlinSerial::read() { - - const ring_buffer_pos_t h = rx_buffer.head; - ring_buffer_pos_t t = rx_buffer.tail; - - if (h == t) return -1; - - int v = rx_buffer.buffer[t]; - t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1); - - // Advance tail - rx_buffer.tail = t; - - if (Cfg::XONOFF) { - // If the XOFF char was sent, or about to be sent... - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - // Get count of bytes in the RX buffer - const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1); - // When below 10% of RX buffer capacity, send XON before running out of RX buffer bytes - if (rx_count < (Cfg::RX_SIZE) / 10) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX isr. - HWUART->UART_IER = UART_IER_TXRDY; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!(HWUART->UART_SR & UART_SR_TXRDY)) sw_barrier(); - HWUART->UART_THR = XON_CHAR; - } - } - } - } - - return v; -} - -template -typename MarlinSerial::ring_buffer_pos_t MarlinSerial::available() { - const ring_buffer_pos_t h = rx_buffer.head, t = rx_buffer.tail; - return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1); -} - -template -void MarlinSerial::flush() { - rx_buffer.tail = rx_buffer.head; - - if (Cfg::XONOFF) { - if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) { - if (Cfg::TX_SIZE > 0) { - // Signal we want an XON character to be sent. - xon_xoff_state = XON_CHAR; - // Enable TX isr. - HWUART->UART_IER = UART_IER_TXRDY; - } - else { - // If not using TX interrupts, we must send the XON char now - xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT; - while (!(HWUART->UART_SR & UART_SR_TXRDY)) sw_barrier(); - HWUART->UART_THR = XON_CHAR; - } - } - } -} - -template -size_t MarlinSerial::write(const uint8_t c) { - _written = true; - - if (Cfg::TX_SIZE == 0) { - while (!(HWUART->UART_SR & UART_SR_TXRDY)) sw_barrier(); - HWUART->UART_THR = c; - } - else { - - // If the TX interrupts are disabled and the data register - // is empty, just write the byte to the data register and - // be done. This shortcut helps significantly improve the - // effective datarate at high (>500kbit/s) bitrates, where - // interrupt overhead becomes a slowdown. - // Yes, there is a race condition between the sending of the - // XOFF char at the RX isr, but it is properly handled there - if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) { - HWUART->UART_THR = c; - return 1; - } - - const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1); - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!hal.isr_state()) { - - // Make room by polling if it is possible to transmit, and do so! - while (i == tx_buffer.tail) { - // If we can transmit another byte, do it. - if (HWUART->UART_SR & UART_SR_TXRDY) _tx_thr_empty_irq(); - // Make sure compiler rereads tx_buffer.tail - sw_barrier(); - } - } - else { - // Interrupts are enabled, just wait until there is space - while (i == tx_buffer.tail) sw_barrier(); - } - - // Store new char. head is always safe to move - tx_buffer.buffer[tx_buffer.head] = c; - tx_buffer.head = i; - - // Enable TX isr - Non atomic, but it will eventually enable TX isr - HWUART->UART_IER = UART_IER_TXRDY; - } - return 1; -} - -template -void MarlinSerial::flushTX() { - // TX - - if (Cfg::TX_SIZE == 0) { - // No bytes written, no need to flush. This special case is needed since there's - // no way to force the TXC (transmit complete) bit to 1 during initialization. - if (!_written) return; - - // Wait until everything was transmitted - while (!(HWUART->UART_SR & UART_SR_TXEMPTY)) sw_barrier(); - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - - } - else { - // 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; - - // If global interrupts are disabled (as the result of being called from an ISR)... - if (!hal.isr_state()) { - - // Wait until everything was transmitted - We must do polling, as interrupts are disabled - while (tx_buffer.head != tx_buffer.tail || !(HWUART->UART_SR & UART_SR_TXEMPTY)) { - // If there is more space, send an extra character - if (HWUART->UART_SR & UART_SR_TXRDY) _tx_thr_empty_irq(); - sw_barrier(); - } - - } - else { - // Wait until everything was transmitted - while (tx_buffer.head != tx_buffer.tail || !(HWUART->UART_SR & UART_SR_TXEMPTY)) sw_barrier(); - } - - // At this point nothing is queued anymore (DRIE is disabled) and - // the hardware finished transmission (TXC is set). - } -} - - -// If not using the USB port as serial port -#if defined(SERIAL_PORT) && SERIAL_PORT >= 0 - template class MarlinSerial< MarlinSerialCfg >; - MSerialT1 customizedSerial1(MarlinSerialCfg::EMERGENCYPARSER); -#endif - -#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 - template class MarlinSerial< MarlinSerialCfg >; - MSerialT2 customizedSerial2(MarlinSerialCfg::EMERGENCYPARSER); -#endif - -#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0 - template class MarlinSerial< MarlinSerialCfg >; - MSerialT3 customizedSerial3(MarlinSerialCfg::EMERGENCYPARSER); -#endif - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/MarlinSerial.h b/src/HAL/DUE/MarlinSerial.h deleted file mode 100644 index 5a61bff..0000000 --- a/src/HAL/DUE/MarlinSerial.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MarlinSerial_Due.h - Hardware serial library for Arduino DUE - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - * Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved. - */ - -#include - -#include "../../inc/MarlinConfigPre.h" -#include "../../core/serial_hook.h" - -// 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 "SERIAL_XON_XOFF requires RX_BUFFER_SIZE >= 1024 for reliable transfers without drops." -//#elif RX_BUFFER_SIZE && (RX_BUFFER_SIZE < 2 || !IS_POWER_OF_2(RX_BUFFER_SIZE)) -// #error "RX_BUFFER_SIZE must be a power of 2 greater than 1." -//#elif 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, a power of 2 greater than 1, and no greater than 256." -//#endif - -// Templated type selector -template struct TypeSelector { typedef T type;} ; -template struct TypeSelector { typedef F type; }; - -// Templated structure wrapper -template struct StructWrapper { - constexpr StructWrapper(int) {} - FORCE_INLINE S* operator->() const { return (S*)addr; } -}; - -template -class MarlinSerial { -protected: - // Information for all supported UARTs - static constexpr uint32_t BASES[] = {0x400E0800U, 0x40098000U, 0x4009C000U, 0x400A0000U, 0x400A4000U}; - static constexpr IRQn_Type IRQS[] = { UART_IRQn, USART0_IRQn, USART1_IRQn, USART2_IRQn, USART3_IRQn}; - static constexpr int IRQ_IDS[] = { ID_UART, ID_USART0, ID_USART1, ID_USART2, ID_USART3}; - - // Alias for shorter code - static constexpr StructWrapper HWUART = 0; - static constexpr IRQn_Type HWUART_IRQ = IRQS[Cfg::PORT]; - static constexpr int HWUART_IRQ_ID = IRQ_IDS[Cfg::PORT]; - - // Base size of type on buffer size - typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t; - - struct ring_buffer_r { - volatile ring_buffer_pos_t head, tail; - unsigned char buffer[Cfg::RX_SIZE]; - }; - - struct ring_buffer_t { - volatile uint8_t head, tail; - unsigned char buffer[Cfg::TX_SIZE]; - }; - - static ring_buffer_r rx_buffer; - static ring_buffer_t tx_buffer; - static bool _written; - - static constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80, // XON / XOFF Character was sent - XON_XOFF_CHAR_MASK = 0x1F; // XON / XOFF character to send - - // XON / XOFF character definitions - static constexpr uint8_t XON_CHAR = 17, XOFF_CHAR = 19; - static uint8_t xon_xoff_state, - rx_dropped_bytes, - rx_buffer_overruns, - rx_framing_errors; - static ring_buffer_pos_t rx_max_enqueued; - - FORCE_INLINE static void store_rxd_char(); - FORCE_INLINE static void _tx_thr_empty_irq(); - static void UART_ISR(); - -public: - MarlinSerial() {}; - static void begin(const long); - static void end(); - static int peek(); - static int read(); - static void flush(); - static ring_buffer_pos_t available(); - static size_t write(const uint8_t c); - static void flushTX(); - - static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; } - - FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; } - FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; } - FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; } - FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; } -}; - -// Serial port configuration -template -struct MarlinSerialCfg { - static constexpr int PORT = serial; - static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE; - static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE; - static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF); - static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER); - static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX); - static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS); - static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS); - static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED); -}; - -#if defined(SERIAL_PORT) && SERIAL_PORT >= 0 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1; - extern MSerialT1 customizedSerial1; -#endif - -#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2; - extern MSerialT2 customizedSerial2; -#endif - -#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0 - typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3; - extern MSerialT3 customizedSerial3; -#endif diff --git a/src/HAL/DUE/MarlinSerialUSB.cpp b/src/HAL/DUE/MarlinSerialUSB.cpp deleted file mode 100644 index 8de2dc7..0000000 --- a/src/HAL/DUE/MarlinSerialUSB.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_SAM - -/** - * MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - * Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved. - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_USB_SERIAL - -#include "MarlinSerialUSB.h" - -// Imports from Atmel USB Stack/CDC implementation -extern "C" { - bool usb_task_cdc_isenabled(); - bool usb_task_cdc_dtr_active(); - bool udi_cdc_is_rx_ready(); - int udi_cdc_getc(); - bool udi_cdc_is_tx_ready(); - int udi_cdc_putc(int value); -} - -// Pending character -static int pending_char = -1; - -// Public Methods -void MarlinSerialUSB::begin(const long) {} - -void MarlinSerialUSB::end() {} - -int MarlinSerialUSB::peek() { - if (pending_char >= 0) - return pending_char; - - // If USB CDC not enumerated or not configured on the PC side - if (!usb_task_cdc_isenabled()) - return -1; - - // If no bytes sent from the PC - if (!udi_cdc_is_rx_ready()) - return -1; - - pending_char = udi_cdc_getc(); - - TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)pending_char)); - - return pending_char; -} - -int MarlinSerialUSB::read() { - if (pending_char >= 0) { - int ret = pending_char; - pending_char = -1; - return ret; - } - - // If USB CDC not enumerated or not configured on the PC side - if (!usb_task_cdc_isenabled()) - return -1; - - // If no bytes sent from the PC - if (!udi_cdc_is_rx_ready()) - return -1; - - int c = udi_cdc_getc(); - - TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)c)); - - return c; -} - -int MarlinSerialUSB::available() { - if (pending_char > 0) return pending_char; - return pending_char == 0 || - // or USB CDC enumerated and configured on the PC side and some bytes where sent to us */ - (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready()); -} - -void MarlinSerialUSB::flush() { } - -size_t MarlinSerialUSB::write(const uint8_t c) { - - /* Do not even bother sending anything if USB CDC is not enumerated - or not configured on the PC side or there is no program on the PC - listening to our messages */ - if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active()) - return 0; - - /* Wait until the PC has read the pending to be sent data */ - while (usb_task_cdc_isenabled() && - usb_task_cdc_dtr_active() && - !udi_cdc_is_tx_ready()) { - }; - - /* Do not even bother sending anything if USB CDC is not enumerated - or not configured on the PC side or there is no program on the PC - listening to our messages at this point */ - if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active()) - return 0; - - // Fifo full - // udi_cdc_signal_overrun(); - udi_cdc_putc(c); - return 1; -} - -// Preinstantiate -#if SERIAL_PORT == -1 - MSerialT1 customizedSerial1(TERN0(EMERGENCY_PARSER, true)); -#endif -#if SERIAL_PORT_2 == -1 - MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true)); -#endif -#if SERIAL_PORT_3 == -1 - MSerialT3 customizedSerial3(TERN0(EMERGENCY_PARSER, true)); -#endif - -#endif // HAS_USB_SERIAL -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/MarlinSerialUSB.h b/src/HAL/DUE/MarlinSerialUSB.h deleted file mode 100644 index 6da1ef8..0000000 --- a/src/HAL/DUE/MarlinSerialUSB.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * MarlinSerialUSB_Due.h - Hardware Serial over USB (CDC) library for Arduino DUE - * Copyright (c) 2017 Eduardo José Tagle. All right reserved - */ - -#include "../../inc/MarlinConfig.h" -#include "../../core/serial_hook.h" - -#include - -struct MarlinSerialUSB { - void begin(const long); - void end(); - int peek(); - int read(); - void flush(); - int available(); - size_t write(const uint8_t c); - - #if ENABLED(SERIAL_STATS_DROPPED_RX) - FORCE_INLINE uint32_t dropped() { return 0; } - #endif - - #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - FORCE_INLINE int rxMaxEnqueued() { return 0; } - #endif -}; - -#if SERIAL_PORT == -1 - typedef Serial1Class MSerialT1; - extern MSerialT1 customizedSerial1; -#endif - -#if SERIAL_PORT_2 == -1 - typedef Serial1Class MSerialT2; - extern MSerialT2 customizedSerial2; -#endif - -#if SERIAL_PORT_3 == -1 - typedef Serial1Class MSerialT3; - extern MSerialT3 customizedSerial3; -#endif diff --git a/src/HAL/DUE/MinSerial.cpp b/src/HAL/DUE/MinSerial.cpp deleted file mode 100644 index e5b3dbf..0000000 --- a/src/HAL/DUE/MinSerial.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - -#include "../shared/MinSerial.h" - -#include - -static void TXBegin() { - // Disable UART interrupt in NVIC - NVIC_DisableIRQ( UART_IRQn ); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - // Disable clock - pmc_disable_periph_clk( ID_UART ); - - // Configure PMC - pmc_enable_periph_clk( ID_UART ); - - // Disable PDC channel - UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; - - // Reset and disable receiver and transmitter - UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS; - - // Configure mode: 8bit, No parity, 1 bit stop - UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO; - - // Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds - UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4)); - - // Enable receiver and transmitter - UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN; -} - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() __asm__ volatile("": : :"memory"); -static void TX(char c) { - while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); }; - UART->UART_THR = c; -} - -void install_min_serial() { - HAL_min_serial_init = &TXBegin; - HAL_min_serial_out = &TX; -} - -#if DISABLED(DYNAMIC_VECTORTABLE) -extern "C" { - __attribute__((naked)) void JumpHandler_ASM() { - __asm__ __volatile__ ( - "b CommonHandler_ASM\n" - ); - } - void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler(); -} -#endif - -#endif // POSTMORTEM_DEBUGGING -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/Servo.cpp b/src/HAL/DUE/Servo.cpp deleted file mode 100644 index 2dab882..0000000 --- a/src/HAL/DUE/Servo.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - Copyright (c) 2013 Arduino LLC. 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 -*/ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "../shared/servo.h" -#include "../shared/servo_private.h" - -static Flags<_Nbr_16timers> DisablePending; // ISR should disable the timer at the next timer reset - -// ------------------------ -/// Interrupt handler for the TC0 channel 1. -// ------------------------ -void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t); - -#ifdef _useTimer1 - void HANDLER_FOR_TIMER1() { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); } -#endif -#ifdef _useTimer2 - void HANDLER_FOR_TIMER2() { Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); } -#endif -#ifdef _useTimer3 - void HANDLER_FOR_TIMER3() { Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); } -#endif -#ifdef _useTimer4 - void HANDLER_FOR_TIMER4() { Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); } -#endif -#ifdef _useTimer5 - void HANDLER_FOR_TIMER5() { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); } -#endif - -void Servo_Handler(const timer16_Sequence_t timer, Tc *tc, const uint8_t channel) { - static int8_t Channel[_Nbr_16timers]; // Servo counters to pulse (or -1 for refresh interval) - int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first - if (cho < 0) { // Channel -1 indicates the refresh interval completed... - tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // ...so reset the timer - if (DisablePending[timer]) { - // Disabling only after the full servo period expires prevents - // pulses being too close together if immediately re-enabled. - DisablePending.clear(timer); - TC_Stop(tc, channel); - tc->TC_CHANNEL[channel].TC_SR; // clear interrupt - return; - } - } - else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled? - extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW - - Channel[timer] = ++cho; // go to the next channel (or 0) - if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) { - tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer, cho).ticks; - if (SERVO(timer, cho).Pin.isActive) // activated? - extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH - } - else { - // finished all channels so wait for the refresh period to expire before starting over - const unsigned int cval = tc->TC_CHANNEL[channel].TC_CV + 128 / (SERVO_TIMER_PRESCALER), // allow 128 cycles to ensure the next CV not missed - ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed - tc->TC_CHANNEL[channel].TC_RA = max(cval, ival); - - Channel[timer] = -1; // reset the timer CCR on the next call - } - - tc->TC_CHANNEL[channel].TC_SR; // clear interrupt -} - -static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) { - pmc_enable_periph_clk(id); - TC_Configure(tc, channel, - TC_CMR_WAVE // Waveform mode - | TC_CMR_WAVSEL_UP_RC // Counter running up and reset when equal to RC - | (SERVO_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0) // MCK/2 - | (SERVO_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0) // MCK/8 - | (SERVO_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0) // MCK/32 - | (SERVO_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0) // MCK/128 - ); - - // Wait 1ms before the first ISR - TC_SetRA(tc, channel, (F_CPU) / (SERVO_TIMER_PRESCALER) / 1000UL); // 1ms - - // Configure and enable interrupt - NVIC_EnableIRQ(irqn); - tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; // TC_IER_CPAS: RA Compare - - // Enables the timer clock and performs a software reset to start the counting - TC_Start(tc, channel); -} - -void initISR(const timer16_Sequence_t timer_index) { - CRITICAL_SECTION_START(); - const bool disable_soon = DisablePending[timer_index]; - DisablePending.clear(timer_index); - CRITICAL_SECTION_END(); - - if (!disable_soon) switch (timer_index) { - default: break; - #ifdef _useTimer1 - case _timer1: return _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1); - #endif - #ifdef _useTimer2 - case _timer2: return _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2); - #endif - #ifdef _useTimer3 - case _timer3: return _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3); - #endif - #ifdef _useTimer4 - case _timer4: return _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4); - #endif - #ifdef _useTimer5 - case _timer5: return _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5); - #endif - } -} - -void finISR(const timer16_Sequence_t timer_index) { - // Timer is disabled from the ISR, to ensure proper final pulse length. - DisablePending.set(timer_index); -} - -#endif // HAS_SERVOS - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/ServoTimers.h b/src/HAL/DUE/ServoTimers.h deleted file mode 100644 index 95bd404..0000000 --- a/src/HAL/DUE/ServoTimers.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright (c) 2013 Arduino LLC. 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 - */ - -/** - * Defines for 16 bit timers used with Servo library - * - * If _useTimerX is defined then TimerX is a 32 bit timer on the current board - * timer16_Sequence_t enumerates the sequence that the timers should be allocated - * _Nbr_16timers indicates how many timers are available. - */ - -/** - * SAM Only definitions - * -------------------- - */ - -// For SAM3X: -//!#define _useTimer1 -//!#define _useTimer2 -#define _useTimer3 -//!#define _useTimer4 -#define _useTimer5 - -#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays -#define SERVO_TIMER_PRESCALER 2 // timer prescaler - -/* - TC0, chan 0 => TC0_Handler - TC0, chan 1 => TC1_Handler - TC0, chan 2 => TC2_Handler - TC1, chan 0 => TC3_Handler - TC1, chan 1 => TC4_Handler - TC1, chan 2 => TC5_Handler - TC2, chan 0 => TC6_Handler - TC2, chan 1 => TC7_Handler - TC2, chan 2 => TC8_Handler - */ - -#ifdef _useTimer1 - #define TC_FOR_TIMER1 TC1 - #define CHANNEL_FOR_TIMER1 0 - #define ID_TC_FOR_TIMER1 ID_TC3 - #define IRQn_FOR_TIMER1 TC3_IRQn - #define HANDLER_FOR_TIMER1 TC3_Handler -#endif -#ifdef _useTimer2 - #define TC_FOR_TIMER2 TC1 - #define CHANNEL_FOR_TIMER2 1 - #define ID_TC_FOR_TIMER2 ID_TC4 - #define IRQn_FOR_TIMER2 TC4_IRQn - #define HANDLER_FOR_TIMER2 TC4_Handler -#endif -#ifdef _useTimer3 - #define TC_FOR_TIMER3 TC1 - #define CHANNEL_FOR_TIMER3 2 - #define ID_TC_FOR_TIMER3 ID_TC5 - #define IRQn_FOR_TIMER3 TC5_IRQn - #define HANDLER_FOR_TIMER3 TC5_Handler -#endif -#ifdef _useTimer4 - #define TC_FOR_TIMER4 TC0 - #define CHANNEL_FOR_TIMER4 2 - #define ID_TC_FOR_TIMER4 ID_TC2 - #define IRQn_FOR_TIMER4 TC2_IRQn - #define HANDLER_FOR_TIMER4 TC2_Handler -#endif -#ifdef _useTimer5 - #define TC_FOR_TIMER5 TC0 - #define CHANNEL_FOR_TIMER5 0 - #define ID_TC_FOR_TIMER5 ID_TC0 - #define IRQn_FOR_TIMER5 TC0_IRQn - #define HANDLER_FOR_TIMER5 TC0_Handler -#endif - -typedef enum : unsigned char { - #ifdef _useTimer1 - _timer1, - #endif - #ifdef _useTimer2 - _timer2, - #endif - #ifdef _useTimer3 - _timer3, - #endif - #ifdef _useTimer4 - _timer4, - #endif - #ifdef _useTimer5 - _timer5, - #endif - _Nbr_16timers -} timer16_Sequence_t; diff --git a/src/HAL/DUE/Tone.cpp b/src/HAL/DUE/Tone.cpp deleted file mode 100644 index 4bc8142..0000000 --- a/src/HAL/DUE/Tone.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Description: Tone function for Arduino Due and compatible (SAM3X8E) - * Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012 - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -static pin_t tone_pin; -volatile static int32_t toggles; - -void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) { - tone_pin = _pin; - toggles = 2 * frequency * duration / 1000; - HAL_timer_start(MF_TIMER_TONE, 2 * frequency); -} - -void noTone(const pin_t _pin) { - HAL_timer_disable_interrupt(MF_TIMER_TONE); - extDigitalWrite(_pin, LOW); -} - -HAL_TONE_TIMER_ISR() { - static uint8_t pin_state = 0; - HAL_timer_isr_prologue(MF_TIMER_TONE); - - if (toggles) { - toggles--; - extDigitalWrite(tone_pin, (pin_state ^= 1)); - } - else noTone(tone_pin); // turn off interrupt -} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp deleted file mode 100644 index 68f6a5c..0000000 --- a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_msp430_hw_spi.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. - */ - -#ifdef __SAM3X8E__ - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include - -#include "../../../MarlinCore.h" - -#ifndef LCD_SPI_SPEED - #define LCD_SPI_SPEED SPI_QUARTER_SPEED -#endif - -#include "../../shared/HAL_SPI.h" -#include "../fastio.h" - -void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) { - PIO_Configure(g_APinDescription[u8g->pin_list[pin_index]].pPort, PIO_OUTPUT_1, - g_APinDescription[u8g->pin_list[pin_index]].ulPin, g_APinDescription[u8g->pin_list[pin_index]].ulPinConfiguration); // OUTPUT -} - -void u8g_SetPILevel_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index, uint8_t level) { - volatile Pio* port = g_APinDescription[u8g->pin_list[pin_index]].pPort; - uint32_t mask = g_APinDescription[u8g->pin_list[pin_index]].ulPin; - if (level) port->PIO_SODR = mask; - else port->PIO_CODR = mask; -} - -uint8_t u8g_com_HAL_DUE_shared_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_SetPILevel_DUE_hw_spi(u8g, U8G_PI_CS, 1); - u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_A0, 1); - - u8g_SetPIOutput_DUE_hw_spi(u8g, U8G_PI_CS); - u8g_SetPIOutput_DUE_hw_spi(u8g, U8G_PI_A0); - - u8g_Delay(5); - - spiBegin(); - - spiInit(LCD_SPI_SPEED); - break; - - case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ - u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_A0, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - u8g_SetPILevel_DUE_hw_spi(u8g, U8G_PI_CS, (arg_val ? 0 : 1)); - break; - - case U8G_COM_MSG_RESET: - break; - - case U8G_COM_MSG_WRITE_BYTE: - - spiSend((uint8_t)arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - spiSend(*ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - spiSend(*ptr++); - arg_val--; - } - } - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB - -#endif // __SAM3X8E__ diff --git a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp b/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp deleted file mode 100644 index 8268cf3..0000000 --- a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_st7920_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. - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../../inc/MarlinConfigPre.h" - -#if IS_U8GLIB_ST7920 - -#include "../../../inc/MarlinConfig.h" -#include "../../shared/Delay.h" - -#include - -#include "u8g_com_HAL_DUE_sw_spi_shared.h" - -#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_0 - -static uint8_t rs_last_state = 255; - -static void u8g_com_DUE_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) { - if (rs != rs_last_state) { // time to send a command/data byte - rs_last_state = rs; - SPISEND_SW_DUE(rs ? 0x0FA : 0x0F8); // Command or Data - DELAY_US(40); // give the controller some time to process the data: 20 is bad, 30 is OK, 40 is safe - } - SPISEND_SW_DUE(val & 0xF0); - SPISEND_SW_DUE(val << 4); -} - -uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - SCK_pPio = g_APinDescription[u8g->pin_list[U8G_PI_SCK]].pPort; - SCK_dwMask = g_APinDescription[u8g->pin_list[U8G_PI_SCK]].ulPin; - MOSI_pPio = g_APinDescription[u8g->pin_list[U8G_PI_MOSI]].pPort; - MOSI_dwMask = g_APinDescription[u8g->pin_list[U8G_PI_MOSI]].ulPin; - - u8g_SetPILevel_DUE(u8g, U8G_PI_CS, 0); - u8g_SetPIOutput_DUE(u8g, U8G_PI_CS); - u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 0); - u8g_SetPIOutput_DUE(u8g, U8G_PI_SCK); - u8g_SetPILevel_DUE(u8g, U8G_PI_MOSI, 0); - u8g_SetPIOutput_DUE(u8g, U8G_PI_MOSI); - - SCK_pPio->PIO_CODR = SCK_dwMask; //SCK low - needed at power up but not after reset - MOSI_pPio->PIO_CODR = MOSI_dwMask; //MOSI low - needed at power up but not after reset - - u8g_Delay(5); - - u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */ - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel_DUE(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 (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) - u8g_SetPILevel_DUE(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select - break; - - case U8G_COM_MSG_WRITE_BYTE: - - u8g_com_DUE_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_DUE_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_DUE_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - } - return 1; -} - -#if ENABLED(LIGHTWEIGHT_UI) - #include "../../../lcd/marlinui.h" - #include "../../shared/HAL_ST7920.h" - - #define ST7920_CS_PIN LCD_PINS_RS - - #if DOGM_SPI_DELAY_US > 0 - #define U8G_DELAY() DELAY_US(DOGM_SPI_DELAY_US) - #else - #define U8G_DELAY() DELAY_US(10) - #endif - - void ST7920_cs() { - WRITE(ST7920_CS_PIN, HIGH); - U8G_DELAY(); - } - - void ST7920_ncs() { - WRITE(ST7920_CS_PIN, LOW); - } - - void ST7920_set_cmd() { - SPISEND_SW_DUE(0xF8); - DELAY_US(40); - } - - void ST7920_set_dat() { - SPISEND_SW_DUE(0xFA); - DELAY_US(40); - } - - void ST7920_write_byte(const uint8_t val) { - SPISEND_SW_DUE(val & 0xF0); - SPISEND_SW_DUE(val << 4); - } -#endif // LIGHTWEIGHT_UI - -#endif // IS_U8GLIB_ST7920 -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp deleted file mode 100644 index 68e3e74..0000000 --- a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_std_sw_spi.c - * - * Universal 8bit Graphics Library - * - * Copyright (c) 2015, 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. - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 - -#include "u8g_com_HAL_DUE_sw_spi_shared.h" - -#include "../../shared/Marduino.h" -#include "../../shared/Delay.h" - -#include - -#if ENABLED(FYSETC_MINI_12864) - #define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3 -#else - #define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_0 -#endif - -uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - SCK_pPio = g_APinDescription[u8g->pin_list[U8G_PI_SCK]].pPort; - SCK_dwMask = g_APinDescription[u8g->pin_list[U8G_PI_SCK]].ulPin; - MOSI_pPio = g_APinDescription[u8g->pin_list[U8G_PI_MOSI]].pPort; - MOSI_dwMask = g_APinDescription[u8g->pin_list[U8G_PI_MOSI]].ulPin; - u8g_SetPIOutput_DUE(u8g, U8G_PI_SCK); - u8g_SetPIOutput_DUE(u8g, U8G_PI_MOSI); - u8g_SetPIOutput_DUE(u8g, U8G_PI_CS); - u8g_SetPIOutput_DUE(u8g, U8G_PI_A0); - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput_DUE(u8g, U8G_PI_RESET); - u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 0); - u8g_SetPILevel_DUE(u8g, U8G_PI_MOSI, 0); - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel_DUE(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - #if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0 - if (arg_val) { // SCK idle state needs to be set to the proper idle state before - // the next chip select goes active - u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 1); //set SCK to mode 3 idle state before CS goes active - u8g_SetPILevel_DUE(u8g, U8G_PI_CS, LOW); - } - else { - u8g_SetPILevel_DUE(u8g, U8G_PI_CS, HIGH); - u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 0); //set SCK to mode 0 idle state after CS goes inactive - } - #else - u8g_SetPILevel_DUE(u8g, U8G_PI_CS, !arg_val); - #endif - break; - - case U8G_COM_MSG_WRITE_BYTE: - SPISEND_SW_DUE(arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - SPISEND_SW_DUE(*ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - SPISEND_SW_DUE(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_SetPILevel_DUE(u8g, U8G_PI_A0, arg_val); - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp b/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp deleted file mode 100644 index 9049247..0000000 --- a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_st7920_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. - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include "../../../inc/MarlinConfig.h" -#include "../../shared/Delay.h" - -#include - -#include "u8g_com_HAL_DUE_sw_spi_shared.h" - -void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index) { - PIO_Configure(g_APinDescription[u8g->pin_list[pin_index]].pPort, PIO_OUTPUT_1, - g_APinDescription[u8g->pin_list[pin_index]].ulPin, g_APinDescription[u8g->pin_list[pin_index]].ulPinConfiguration); // OUTPUT -} - -void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level) { - volatile Pio* port = g_APinDescription[u8g->pin_list[pin_index]].pPort; - uint32_t mask = g_APinDescription[u8g->pin_list[pin_index]].ulPin; - if (level) port->PIO_SODR = mask; else port->PIO_CODR = mask; -} - -Pio *SCK_pPio, *MOSI_pPio; -uint32_t SCK_dwMask, MOSI_dwMask; - -void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz - LOOP_L_N(i, 8) { - if (val & 0x80) - MOSI_pPio->PIO_SODR = MOSI_dwMask; - else - MOSI_pPio->PIO_CODR = MOSI_dwMask; - DELAY_NS(48); - SCK_pPio->PIO_SODR = SCK_dwMask; - DELAY_NS(905); - val <<= 1; - SCK_pPio->PIO_CODR = SCK_dwMask; - } -} - -void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz - LOOP_L_N(i, 8) { - SCK_pPio->PIO_CODR = SCK_dwMask; - DELAY_NS(50); - if (val & 0x80) - MOSI_pPio->PIO_SODR = MOSI_dwMask; - else - MOSI_pPio->PIO_CODR = MOSI_dwMask; - val <<= 1; - DELAY_NS(10); - SCK_pPio->PIO_SODR = SCK_dwMask; - DELAY_NS(70); - } -} - -#endif // HAS_MARLINUI_U8GLIB -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h b/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h deleted file mode 100644 index 45231fd..0000000 --- a/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfigPre.h" -#include "../../shared/Marduino.h" -#include - -void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index); -void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level); - -void u8g_spiSend_sw_DUE_mode_0(uint8_t val); -void u8g_spiSend_sw_DUE_mode_3(uint8_t val); - -extern Pio *SCK_pPio, *MOSI_pPio; -extern uint32_t SCK_dwMask, MOSI_dwMask; diff --git a/src/HAL/DUE/eeprom_flash.cpp b/src/HAL/DUE/eeprom_flash.cpp deleted file mode 100644 index 6077641..0000000 --- a/src/HAL/DUE/eeprom_flash.cpp +++ /dev/null @@ -1,998 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(FLASH_EEPROM_EMULATION) - -/* EEPROM emulation over flash with reduced wear - * - * We will use 2 contiguous groups of pages as main and alternate. - * We want an structure that allows to read as fast as possible, - * without the need of scanning the whole FLASH memory. - * - * FLASH bits default erased state is 1, and can be set to 0 - * on a per bit basis. To reset them to 1, a full page erase - * is needed. - * - * Values are stored as differences that should be applied to a - * completely erased EEPROM (filled with 0xFFs). We just encode - * the starting address of the values to change, the length of - * the block of new values, and the values themselves. All diffs - * are accumulated into a RAM buffer, compacted into the least - * amount of non overlapping diffs possible and sorted by starting - * address before being saved into the next available page of FLASH - * of the current group. - * Once the current group is completely full, we compact it and save - * it into the other group, then erase the current group and switch - * to that new group and set it as current. - * - * The FLASH endurance is about 1/10 ... 1/100 of an EEPROM - * endurance, but EEPROM endurance is specified per byte, not - * per page. We can't emulate EE endurance with FLASH for all - * bytes, but we can emulate endurance for a given percent of - * bytes. - */ - -//#define EE_EMU_DEBUG - -#define EEPROMSize 4096 -#define PagesPerGroup 128 -#define GroupCount 2 -#define PageSize 256U - - /* Flash storage */ -typedef struct FLASH_SECTOR { - uint8_t page[PageSize]; -} FLASH_SECTOR_T; - -#define PAGE_FILL \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, \ - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF - -#define FLASH_INIT_FILL \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL, \ - PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL,PAGE_FILL - -/* This is the FLASH area used to emulate a 2Kbyte EEPROM -- We need this buffer aligned - to a 256 byte boundary. */ -static const uint8_t flashStorage[PagesPerGroup * GroupCount * PageSize] __attribute__ ((aligned (PageSize))) = { FLASH_INIT_FILL }; - -/* Get the address of an specific page */ -static const FLASH_SECTOR_T* getFlashStorage(int page) { - return (const FLASH_SECTOR_T*)&flashStorage[page*PageSize]; -} - -static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes - curPage = 0, // Current FLASH page inside the group - curGroup = 0xFF; // Current FLASH group - -#define DEBUG_OUT ENABLED(EE_EMU_DEBUG) -#include "../../core/debug_out.h" - -static void ee_Dump(const int page, const void *data) { - - #ifdef EE_EMU_DEBUG - - const uint8_t *c = (const uint8_t*) data; - char buffer[80]; - - sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page); - DEBUG_ECHO(buffer); - - char* p = &buffer[0]; - for (int i = 0; i< PageSize; ++i) { - if ((i & 0xF) == 0) p += sprintf_P(p, PSTR("%04x] "), i); - - p += sprintf_P(p, PSTR(" %02x"), c[i]); - if ((i & 0xF) == 0xF) { - *p++ = '\n'; - *p = 0; - DEBUG_ECHO(buffer); - p = &buffer[0]; - } - } - - #else - UNUSED(page); - UNUSED(data); - #endif -} - -/* Flash Writing Protection Key */ -#define FWP_KEY 0x5Au - -#if SAM4S_SERIES - #define EEFC_FCR_FCMD(value) \ - ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos))) - #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE | EEFC_FSR_FLERR) -#else - #define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE) -#endif - -/** - * Writes the contents of the specified page (no previous erase) - * @param page (page #) - * @param data (pointer to the data buffer) - */ -__attribute__ ((long_call, section (".ramfunc"))) -static bool ee_PageWrite(uint16_t page, const void *data) { - - uint16_t i; - uint32_t addrflash = uint32_t(getFlashStorage(page)); - - // Read the flash contents - uint32_t pageContents[PageSize>>2]; - memcpy(pageContents, (void*)addrflash, PageSize); - - // We ONLY want to toggle bits that have changed, and that have changed to 0. - // SAM3X8E tends to destroy contiguous bits if reprogrammed without erasing, so - // we try by all means to avoid this. That is why it says: "The Partial - // Programming mode works only with 128-bit (or higher) boundaries. It cannot - // be used with boundaries lower than 128 bits (8, 16 or 32-bit for example)." - // All bits that did not change, set them to 1. - for (i = 0; i > 2; i++) - pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i])); - - DEBUG_ECHO_MSG("EEPROM PageWrite ", page); - DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash); - DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0)); - DEBUG_FLUSH(); - - // Get the page relative to the start of the EFC controller, and the EFC controller to use - Efc *efc; - uint16_t fpage; - if (addrflash >= IFLASH1_ADDR) { - efc = EFC1; - fpage = (addrflash - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE; - } - else { - efc = EFC0; - fpage = (addrflash - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE; - } - - // Get the page that must be unlocked, then locked - uint16_t lpage = fpage & (~((IFLASH0_LOCK_REGION_SIZE / IFLASH0_PAGE_SIZE) - 1)); - - // Disable all interrupts - __disable_irq(); - - // Get the FLASH wait states - uint32_t orgWS = (efc->EEFC_FMR & EEFC_FMR_FWS_Msk) >> EEFC_FMR_FWS_Pos; - - // Set wait states to 6 (SAM errata) - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(6); - - // Unlock the flash page - uint32_t status; - efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(lpage) | EEFC_FCR_FCMD(EFC_FCMD_CLB); - while (((status = efc->EEFC_FSR) & EEFC_FSR_FRDY) != EEFC_FSR_FRDY) { - // force compiler to not optimize this -- NOPs don't work! - __asm__ __volatile__(""); - }; - - if ((status & EEFC_ERROR_FLAGS) != 0) { - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - DEBUG_ECHO_MSG("EEPROM Unlock failure for page ", page); - return false; - } - - // Write page and lock: Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable data corruption. - const uint32_t * aligned_src = (const uint32_t *) &pageContents[0]; /*data;*/ - uint32_t * p_aligned_dest = (uint32_t *) addrflash; - for (i = 0; i < (IFLASH0_PAGE_SIZE / sizeof(uint32_t)); ++i) { - *p_aligned_dest++ = *aligned_src++; - } - efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(fpage) | EEFC_FCR_FCMD(EFC_FCMD_WPL); - while (((status = efc->EEFC_FSR) & EEFC_FSR_FRDY) != EEFC_FSR_FRDY) { - // force compiler to not optimize this -- NOPs don't work! - __asm__ __volatile__(""); - }; - - if ((status & EEFC_ERROR_FLAGS) != 0) { - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - DEBUG_ECHO_MSG("EEPROM Write failure for page ", page); - - return false; - } - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - // Compare contents - if (memcmp(getFlashStorage(page),data,PageSize)) { - - #ifdef EE_EMU_DEBUG - DEBUG_ECHO_MSG("EEPROM Verify Write failure for page ", page); - - ee_Dump( page, (uint32_t *)addrflash); - ee_Dump(-page, data); - - // Calculate count of changed bits - uint32_t *p1 = (uint32_t*)addrflash; - uint32_t *p2 = (uint32_t*)data; - int count = 0; - for (i =0; i> 2; i++) { - if (p1[i] != p2[i]) { - uint32_t delta = p1[i] ^ p2[i]; - while (delta) { - if ((delta&1) != 0) - count++; - delta >>= 1; - } - } - } - DEBUG_ECHOLNPGM("--> Differing bits: ", count); - #endif - - return false; - } - - return true; -} - -/** - * Erases the contents of the specified page - * @param page (page #) - */ -__attribute__ ((long_call, section (".ramfunc"))) -static bool ee_PageErase(uint16_t page) { - - uint16_t i; - uint32_t addrflash = uint32_t(getFlashStorage(page)); - - DEBUG_ECHO_MSG("EEPROM PageErase ", page); - DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash); - DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0)); - DEBUG_FLUSH(); - - // Get the page relative to the start of the EFC controller, and the EFC controller to use - Efc *efc; - uint16_t fpage; - if (addrflash >= IFLASH1_ADDR) { - efc = EFC1; - fpage = (addrflash - IFLASH1_ADDR) / IFLASH1_PAGE_SIZE; - } - else { - efc = EFC0; - fpage = (addrflash - IFLASH0_ADDR) / IFLASH0_PAGE_SIZE; - } - - // Get the page that must be unlocked, then locked - uint16_t lpage = fpage & (~((IFLASH0_LOCK_REGION_SIZE / IFLASH0_PAGE_SIZE) - 1)); - - // Disable all interrupts - __disable_irq(); - - // Get the FLASH wait states - uint32_t orgWS = (efc->EEFC_FMR & EEFC_FMR_FWS_Msk) >> EEFC_FMR_FWS_Pos; - - // Set wait states to 6 (SAM errata) - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(6); - - // Unlock the flash page - uint32_t status; - efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(lpage) | EEFC_FCR_FCMD(EFC_FCMD_CLB); - while (((status = efc->EEFC_FSR) & EEFC_FSR_FRDY) != EEFC_FSR_FRDY) { - // force compiler to not optimize this -- NOPs don't work! - __asm__ __volatile__(""); - }; - if ((status & EEFC_ERROR_FLAGS) != 0) { - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - DEBUG_ECHO_MSG("EEPROM Unlock failure for page ",page); - - return false; - } - - // Erase Write page and lock: Writing 8-bit and 16-bit data is not allowed and may lead to unpredictable data corruption. - uint32_t * p_aligned_dest = (uint32_t *) addrflash; - for (i = 0; i < (IFLASH0_PAGE_SIZE / sizeof(uint32_t)); ++i) { - *p_aligned_dest++ = 0xFFFFFFFF; - } - efc->EEFC_FCR = EEFC_FCR_FKEY(FWP_KEY) | EEFC_FCR_FARG(fpage) | EEFC_FCR_FCMD(EFC_FCMD_EWPL); - while (((status = efc->EEFC_FSR) & EEFC_FSR_FRDY) != EEFC_FSR_FRDY) { - // force compiler to not optimize this -- NOPs don't work! - __asm__ __volatile__(""); - }; - if ((status & EEFC_ERROR_FLAGS) != 0) { - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - DEBUG_ECHO_MSG("EEPROM Erase failure for page ",page); - - return false; - } - - // Restore original wait states - efc->EEFC_FMR = (efc->EEFC_FMR & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(orgWS); - - // Reenable interrupts - __enable_irq(); - - // Check erase - uint32_t * aligned_src = (uint32_t *) addrflash; - for (i = 0; i < PageSize >> 2; i++) { - if (*aligned_src++ != 0xFFFFFFFF) { - DEBUG_ECHO_MSG("EEPROM Verify Erase failure for page ",page); - ee_Dump(page, (uint32_t *)addrflash); - return false; - } - } - - return true; -} - -static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) { - - uint32_t baddr; - uint32_t blen; - - // If we were requested an address outside of the emulated range, fail now - if (address >= EEPROMSize) - return false; - - // Check that the value is not contained in the RAM buffer - if (!excludeRAMBuffer) { - uint16_t i = 0; - while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Get the address of the block - baddr = buffer[i] | (buffer[i + 1] << 8); - - // Get the length of the block - blen = buffer[i + 2]; - - // If we reach the end of the list, break loop - if (blen == 0xFF) - break; - - // Check if data is contained in this block - if (address >= baddr && - address < (baddr + blen)) { - - // Yes, it is contained. Return it! - return buffer[i + 3 + address - baddr]; - } - - // As blocks are always sorted, if the starting address of this block is higher - // than the address we are looking for, break loop now - We wont find the value - // associated to the address - if (baddr > address) - break; - - // Jump to the next block - i += 3 + blen; - } - } - - // It is NOT on the RAM buffer. It could be stored in FLASH. We are - // ensured on a given FLASH page, address contents are never repeated - // but on different pages, there is no such warranty, so we must go - // backwards from the last written FLASH page to the first one. - for (int page = curPage - 1; page >= 0; --page) { - - // Get a pointer to the flash page - uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup); - - uint16_t i = 0; - while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Get the address of the block - baddr = pflash[i] | (pflash[i + 1] << 8); - - // Get the length of the block - blen = pflash[i + 2]; - - // If we reach the end of the list, break loop - if (blen == 0xFF) - break; - - // Check if data is contained in this block - if (address >= baddr && address < (baddr + blen)) - return pflash[i + 3 + address - baddr]; // Yes, it is contained. Return it! - - // As blocks are always sorted, if the starting address of this block is higher - // than the address we are looking for, break loop now - We wont find the value - // associated to the address - if (baddr > address) break; - - // Jump to the next block - i += 3 + blen; - } - } - - // If reached here, value is not stored, so return its default value - return 0xFF; -} - -static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) { - uint32_t baddr, - blen, - nextAddr = 0xFFFF, - nextRange = 0; - - // Check that the value is not contained in the RAM buffer - if (!excludeRAMBuffer) { - uint16_t i = 0; - while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Get the address of the block - baddr = buffer[i] | (buffer[i + 1] << 8); - - // Get the length of the block - blen = buffer[i + 2]; - - // If we reach the end of the list, break loop - if (blen == 0xFF) break; - - // Check if address and address + 1 is contained in this block - if (address >= baddr && address < (baddr + blen)) - return address | ((blen - address + baddr) << 16); // Yes, it is contained. Return it! - - // Otherwise, check if we can use it as a limit - if (baddr > address && baddr < nextAddr) { - nextAddr = baddr; - nextRange = blen; - } - - // As blocks are always sorted, if the starting address of this block is higher - // than the address we are looking for, break loop now - We wont find the value - // associated to the address - if (baddr > address) break; - - // Jump to the next block - i += 3 + blen; - } - } - - // It is NOT on the RAM buffer. It could be stored in FLASH. We are - // ensured on a given FLASH page, address contents are never repeated - // but on different pages, there is no such warranty, so we must go - // backwards from the last written FLASH page to the first one. - for (int page = curPage - 1; page >= 0; --page) { - - // Get a pointer to the flash page - uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup); - - uint16_t i = 0; - while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Get the address of the block - baddr = pflash[i] | (pflash[i + 1] << 8); - - // Get the length of the block - blen = pflash[i + 2]; - - // If we reach the end of the list, break loop - if (blen == 0xFF) break; - - // Check if data is contained in this block - if (address >= baddr && address < (baddr + blen)) - return address | ((blen - address + baddr) << 16); // Yes, it is contained. Return it! - - // Otherwise, check if we can use it as a limit - if (baddr > address && baddr < nextAddr) { - nextAddr = baddr; - nextRange = blen; - } - - // As blocks are always sorted, if the starting address of this block is higher - // than the address we are looking for, break loop now - We wont find the value - // associated to the address - if (baddr > address) break; - - // Jump to the next block - i += 3 + blen; - } - } - - // If reached here, we will return the next valid address - return nextAddr | (nextRange << 16); -} - -static bool ee_IsPageClean(int page) { - uint32_t *pflash = (uint32_t*) getFlashStorage(page); - for (uint16_t i = 0; i < (PageSize >> 2); ++i) - if (*pflash++ != 0xFFFFFFFF) return false; - return true; -} - -static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData=0xFF) { - - // Check if RAM buffer has something to be written - bool isEmpty = true; - uint32_t *p = (uint32_t*) &buffer[0]; - for (uint16_t j = 0; j < (PageSize >> 2); j++) { - if (*p++ != 0xFFFFFFFF) { - isEmpty = false; - break; - } - } - - // If something has to be written, do so! - if (!isEmpty) { - - // Write the current ram buffer into FLASH - ee_PageWrite(curPage + curGroup * PagesPerGroup, buffer); - - // Clear the RAM buffer - memset(buffer, 0xFF, sizeof(buffer)); - - // Increment the page to use the next time - ++curPage; - } - - // Did we reach the maximum count of available pages per group for storage ? - if (curPage < PagesPerGroup) { - - // Do we have an override address ? - if (overrideAddress < EEPROMSize) { - - // Yes, just store the value into the RAM buffer - buffer[0] = overrideAddress & 0xFF; - buffer[0 + 1] = (overrideAddress >> 8) & 0xFF; - buffer[0 + 2] = 1; - buffer[0 + 3] = overrideData; - } - - // Done! - return true; - } - - // We have no space left on the current group - We must compact the values - uint16_t i = 0; - - // Compute the next group to use - int curwPage = 0, curwGroup = curGroup + 1; - if (curwGroup >= GroupCount) curwGroup = 0; - - uint32_t rdAddr = 0; - do { - - // Get the next valid range - uint32_t addrRange = ee_GetAddrRange(rdAddr, true); - - // Make sure not to skip the override address, if specified - int rdRange; - if (overrideAddress < EEPROMSize && - rdAddr <= overrideAddress && - (addrRange & 0xFFFF) > overrideAddress) { - - rdAddr = overrideAddress; - rdRange = 1; - } - else { - rdAddr = addrRange & 0xFFFF; - rdRange = addrRange >> 16; - } - - // If no range, break loop - if (rdRange == 0) - break; - - do { - - // Get the value - uint8_t rdValue = overrideAddress == rdAddr ? overrideData : ee_Read(rdAddr, true); - - // Do not bother storing default values - if (rdValue != 0xFF) { - - // If we have room, add it to the buffer - if (buffer[i + 2] == 0xFF) { - - // Uninitialized buffer, just add it! - buffer[i] = rdAddr & 0xFF; - buffer[i + 1] = (rdAddr >> 8) & 0xFF; - buffer[i + 2] = 1; - buffer[i + 3] = rdValue; - - } - else { - // Buffer already has contents. Check if we can extend it - - // Get the address of the block - uint32_t baddr = buffer[i] | (buffer[i + 1] << 8); - - // Get the length of the block - uint32_t blen = buffer[i + 2]; - - // Can we expand it ? - if (rdAddr == (baddr + blen) && - i < (PageSize - 4) && /* This block has a chance to contain data AND */ - buffer[i + 2] < (PageSize - i - 3)) {/* There is room for this block to be expanded */ - - // Yes, do it - ++buffer[i + 2]; - - // And store the value - buffer[i + 3 + rdAddr - baddr] = rdValue; - - } - else { - - // No, we can't expand it - Skip the existing block - i += 3 + blen; - - // Can we create a new slot ? - if (i > (PageSize - 4)) { - - // Not enough space - Write the current buffer to FLASH - ee_PageWrite(curwPage + curwGroup * PagesPerGroup, buffer); - - // Advance write page (as we are compacting, should never overflow!) - ++curwPage; - - // Clear RAM buffer - memset(buffer, 0xFF, sizeof(buffer)); - - // Start fresh */ - i = 0; - } - - // Enough space, add the new block - buffer[i] = rdAddr & 0xFF; - buffer[i + 1] = (rdAddr >> 8) & 0xFF; - buffer[i + 2] = 1; - buffer[i + 3] = rdValue; - } - } - } - - // Go to the next address - ++rdAddr; - - // Repeat for bytes of this range - } while (--rdRange); - - // Repeat until we run out of ranges - } while (rdAddr < EEPROMSize); - - // We must erase the previous group, in preparation for the next swap - for (int page = 0; page < curPage; page++) { - ee_PageErase(page + curGroup * PagesPerGroup); - } - - // Finally, Now the active group is the created new group - curGroup = curwGroup; - curPage = curwPage; - - // Done! - return true; -} - -static bool ee_Write(uint32_t address, uint8_t data) { - - // If we were requested an address outside of the emulated range, fail now - if (address >= EEPROMSize) return false; - - // Lets check if we have a block with that data previously defined. Block - // start addresses are always sorted in ascending order - uint16_t i = 0; - while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Get the address of the block - uint32_t baddr = buffer[i] | (buffer[i + 1] << 8); - - // Get the length of the block - uint32_t blen = buffer[i + 2]; - - // If we reach the end of the list, break loop - if (blen == 0xFF) - break; - - // Check if data is contained in this block - if (address >= baddr && - address < (baddr + blen)) { - - // Yes, it is contained. Just modify it - buffer[i + 3 + address - baddr] = data; - - // Done! - return true; - } - - // Maybe we could add it to the front or to the back - // of this block ? - if ((address + 1) == baddr || address == (baddr + blen)) { - - // Potentially, it could be done. But we must ensure there is room - // so we can expand the block. Lets find how much free space remains - uint32_t iend = i; - do { - uint32_t ln = buffer[iend + 2]; - if (ln == 0xFF) break; - iend += 3 + ln; - } while (iend <= (PageSize - 4)); /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - - // Here, inxt points to the first free address in the buffer. Do we have room ? - if (iend < PageSize) { - // Yes, at least a byte is free - We can expand the block - - // Do we have to insert at the beginning ? - if ((address + 1) == baddr) { - - // Insert at the beginning - - // Make room at the beginning for our byte - memmove(&buffer[i + 3 + 1], &buffer[i + 3], iend - i - 3); - - // Adjust the header and store the data - buffer[i] = address & 0xFF; - buffer[i + 1] = (address >> 8) & 0xFF; - buffer[i + 2]++; - buffer[i + 3] = data; - - } - else { - - // Insert at the end - There is a very interesting thing that could happen here: - // Maybe we could coalesce the next block with this block. Let's try to do it! - uint16_t inext = i + 3 + blen; - if (inext <= (PageSize - 4) && - (buffer[inext] | uint16_t(buffer[inext + 1] << 8)) == (baddr + blen + 1)) { - // YES! ... we can coalesce blocks! . Do it! - - // Adjust this block header to include the next one - buffer[i + 2] += buffer[inext + 2] + 1; - - // Store data at the right place - buffer[i + 3 + blen] = data; - - // Remove the next block header and append its data - memmove(&buffer[inext + 1], &buffer[inext + 3], iend - inext - 3); - - // Finally, as we have saved 2 bytes at the end, make sure to clean them - buffer[iend - 2] = 0xFF; - buffer[iend - 1] = 0xFF; - - } - else { - // NO ... No coalescing possible yet - - // Make room at the end for our byte - memmove(&buffer[i + 3 + blen + 1], &buffer[i + 3 + blen], iend - i - 3 - blen); - - // And add the data to the block - buffer[i + 2]++; - buffer[i + 3 + blen] = data; - } - } - - // Done! - return true; - } - } - - // As blocks are always sorted, if the starting address of this block is higher - // than the address we are looking for, break loop now - We wont find the value - // associated to the address - if (baddr > address) break; - - // Jump to the next block - i += 3 + blen; - } - - // Value is not stored AND we can't expand previous block to contain it. We must create a new block - - // First, lets find how much free space remains - uint32_t iend = i; - while (iend <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */ - uint32_t ln = buffer[iend + 2]; - if (ln == 0xFF) break; - iend += 3 + ln; - } - - // If there is room for a new block, insert it at the proper place - if (iend <= (PageSize - 4)) { - - // We have room to create a new block. Do so --- But add - // the block at the proper position, sorted by starting - // address, so it will be possible to compact it with other blocks. - - // Make space - memmove(&buffer[i + 4], &buffer[i], iend - i); - - // And add the block - buffer[i] = address & 0xFF; - buffer[i + 1] = (address >> 8) & 0xFF; - buffer[i + 2] = 1; - buffer[i + 3] = data; - - // Done! - return true; - } - - // Not enough room to store this information on this FLASH page - Perform a - // flush and override the address with the specified contents - return ee_Flush(address, data); -} - -static void ee_Init() { - - // Just init once! - if (curGroup != 0xFF) return; - - // Clean up the SRAM buffer - memset(buffer, 0xFF, sizeof(buffer)); - - // Now, we must find out the group where settings are stored - for (curGroup = 0; curGroup < GroupCount; curGroup++) - if (!ee_IsPageClean(curGroup * PagesPerGroup)) break; - - // If all groups seem to be used, default to first group - if (curGroup >= GroupCount) curGroup = 0; - - DEBUG_ECHO_MSG("EEPROM Current Group: ",curGroup); - DEBUG_FLUSH(); - - // Now, validate that all the other group pages are empty - for (int grp = 0; grp < GroupCount; grp++) { - if (grp == curGroup) continue; - - for (int page = 0; page < PagesPerGroup; page++) { - if (!ee_IsPageClean(grp * PagesPerGroup + page)) { - DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on group ", grp); - DEBUG_FLUSH(); - ee_PageErase(grp * PagesPerGroup + page); - } - } - } - - // Finally, for the active group, determine the first unused page - // and also validate that all the other ones are clean - for (curPage = 0; curPage < PagesPerGroup; curPage++) { - if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) { - ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage)); - break; - } - } - - DEBUG_ECHO_MSG("EEPROM Active page: ", curPage); - DEBUG_FLUSH(); - - // Make sure the pages following the first clean one are also clean - for (int page = curPage + 1; page < PagesPerGroup; page++) { - if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) { - DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on active group ", curGroup); - DEBUG_FLUSH(); - ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page)); - ee_PageErase(curGroup * PagesPerGroup + page); - } - } -} - -/* PersistentStore -----------------------------------------------------------*/ - -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { ee_Init(); return true; } -bool PersistentStore::access_finish() { ee_Flush(); return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != ee_Read(uint32_t(p))) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - ee_Write(uint32_t(p), v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (ee_Read(uint32_t(p)) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = ee_Read(uint32_t(pos)); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // FLASH_EEPROM_EMULATION -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/eeprom_wired.cpp b/src/HAL/DUE/eeprom_wired.cpp deleted file mode 100644 index 557a2f2..0000000 --- a/src/HAL/DUE/eeprom_wired.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_SAM - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -/** - * PersistentStore for Arduino-style EEPROM interface - * with simple implementations supplied by Marlin. - */ - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/endstop_interrupts.h b/src/HAL/DUE/endstop_interrupts.h deleted file mode 100644 index 9c7e210..0000000 --- a/src/HAL/DUE/endstop_interrupts.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -/** - * Endstop interrupts for Due based targets. - * On Due, all pins support external interrupt capability. - */ - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/DUE/fastio.h b/src/HAL/DUE/fastio.h deleted file mode 100644 index a609210..0000000 --- a/src/HAL/DUE/fastio.h +++ /dev/null @@ -1,565 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for SAM3X8E - * Use direct port manipulation to save scads of processor time. - * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. - */ - -/** - * Description: Fast IO functions for Arduino Due and compatible (SAM3X8E) - * - * For ARDUINO_ARCH_SAM - * Note the code here was specifically crafted by disassembling what GCC produces - * out of it, so GCC is able to optimize it out as much as possible to the least - * amount of instructions. Be very careful if you modify them, as "clean code" - * leads to less efficient compiled code!! - */ - -#include - -#include "../../inc/MarlinConfigPre.h" - -/** - * Utility functions - */ - -// Due has 12 PWMs assigned to logical pins 2-13. -// 6, 7, 8 & 9 come from the PWM controller. The others come from the timers. -#define PWM_PIN(P) WITHIN(P, 2, 13) - -#ifndef MASK - #define MASK(PIN) _BV(PIN) -#endif - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); - * - * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html - */ - -// Read a pin -#define _READ(IO) bool(DIO ## IO ## _WPORT -> PIO_PDSR & MASK(DIO ## IO ## _PIN)) - -// Write to a pin -#define _WRITE(IO,V) do { \ - volatile Pio* port = (DIO ## IO ## _WPORT); \ - const uint32_t mask = MASK(DIO ## IO ## _PIN); \ - if (V) port->PIO_SODR = mask; \ - else port->PIO_CODR = mask; \ -}while(0) - -// Toggle a pin -#define _TOGGLE(IO) _WRITE(IO, !READ(IO)) - -#if MB(PRINTRBOARD_G2) - - #include "fastio/G2_pins.h" - - // Set pin as input - #define _SET_INPUT(IO) do{ \ - pmc_enable_periph_clk(G2_g_APinDescription[IO].ulPeripheralId); \ - PIO_Configure((DIO ## IO ## _WPORT), PIO_INPUT, MASK(DIO ## IO ## _PIN), 0); \ - }while(0) - - // Set pin as output - #define _SET_OUTPUT(IO) do{ \ - uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \ - if ((PMC->PMC_PCSR0 & mask) != (mask)) PMC->PMC_PCER0 = mask; \ - volatile Pio* port = (DIO ## IO ## _WPORT); \ - mask = MASK(DIO ## IO ## _PIN); \ - if (_READ(IO)) port->PIO_SODR = mask; \ - else port->PIO_CODR = mask; \ - port->PIO_IDR = mask; \ - const uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \ - if (pin_config & PIO_PULLUP) port->PIO_PUER = mask; \ - else port->PIO_PUDR = mask; \ - if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \ - else port->PIO_MDDR = mask; \ - port->PIO_PER = mask; \ - port->PIO_OER = mask; \ - g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \ - }while(0) - - /** - * Set pin as output with comments - * #define _SET_OUTPUT(IO) do{ \ - * uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \ - * if ((PMC->PMC_PCSR0 & mask ) != (mask)) PMC->PMC_PCER0 = mask; \ // enable PIO clock if not already enabled - * - * volatile Pio* port = (DIO ## IO ## _WPORT); \ - * const uint32_t mask = MASK(DIO ## IO ## _PIN); \ - * if (_READ(IO)) port->PIO_SODR = mask; \ // set output to match input BEFORE setting direction or will glitch the output - * else port->PIO_CODR = mask; \ - * - * port->PIO_IDR = mask; \ // disable interrupt - * - * uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \ - * if (pin_config & PIO_PULLUP) pPio->PIO_PUER = mask; \ // enable pullup if necessary - * else pPio->PIO_PUDR = mask; \ - * - * if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \ // Enable multi-drive if necessary - * else port->PIO_MDDR = mask; \ - * - * port->PIO_PER = mask; \ - * port->PIO_OER = mask; \ // set to output - * - * g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \ - * }while(0) - */ - -#else - - // Set pin as input - #define _SET_INPUT(IO) do{ \ - pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ - PIO_Configure(digitalPinToPort(IO), PIO_INPUT, digitalPinToBitMask(IO), 0); \ - }while(0) - - // Set pin as output - #define _SET_OUTPUT(IO) do{ \ - pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ - PIO_Configure(digitalPinToPort(IO), _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, digitalPinToBitMask(IO), g_APinDescription[IO].ulPinConfiguration); \ - g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \ - }while(0) -#endif - -// Set pin as input with pullup mode -#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) - -// 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 input with pullup (wrapper) -#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) -// Set pin as input with pulldown (substitution) -#define SET_INPUT_PULLDOWN SET_INPUT - -// Set pin as output (wrapper) - reads the pin and sets the output to that value -#define SET_OUTPUT(IO) _SET_OUTPUT(IO) -// Set pin as PWM -#define SET_PWM SET_OUTPUT - -// Check if pin is an input -#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0) -// Check if pin is an output -#define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0) - -// Shorthand -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -/** - * Ports and functions - * Added as necessary or if I feel like it- not a comprehensive list! - */ - -// UART -#define RXD DIO0 -#define TXD DIO1 - -// TWI (I2C) -#define SCL DIO21 -#define SDA DIO20 - -/** - * pins - */ - -#define DIO0_PIN 8 -#define DIO0_WPORT PIOA - -#define DIO1_PIN 9 -#define DIO1_WPORT PIOA - -#define DIO2_PIN 25 -#define DIO2_WPORT PIOB - -#define DIO3_PIN 28 -#define DIO3_WPORT PIOC - -#define DIO4_PIN 26 -#define DIO4_WPORT PIOC - -#define DIO5_PIN 25 -#define DIO5_WPORT PIOC - -#define DIO6_PIN 24 -#define DIO6_WPORT PIOC - -#define DIO7_PIN 23 -#define DIO7_WPORT PIOC - -#define DIO8_PIN 22 -#define DIO8_WPORT PIOC - -#define DIO9_PIN 21 -#define DIO9_WPORT PIOC - -#define DIO10_PIN 29 -#define DIO10_WPORT PIOC - -#define DIO11_PIN 7 -#define DIO11_WPORT PIOD - -#define DIO12_PIN 8 -#define DIO12_WPORT PIOD - -#define DIO13_PIN 27 -#define DIO13_WPORT PIOB - -#define DIO14_PIN 4 -#define DIO14_WPORT PIOD - -#define DIO15_PIN 5 -#define DIO15_WPORT PIOD - -#define DIO16_PIN 13 -#define DIO16_WPORT PIOA - -#define DIO17_PIN 12 -#define DIO17_WPORT PIOA - -#define DIO18_PIN 11 -#define DIO18_WPORT PIOA - -#define DIO19_PIN 10 -#define DIO19_WPORT PIOA - -#define DIO20_PIN 12 -#define DIO20_WPORT PIOB - -#define DIO21_PIN 13 -#define DIO21_WPORT PIOB - -#define DIO22_PIN 26 -#define DIO22_WPORT PIOB - -#define DIO23_PIN 14 -#define DIO23_WPORT PIOA - -#define DIO24_PIN 15 -#define DIO24_WPORT PIOA - -#define DIO25_PIN 0 -#define DIO25_WPORT PIOD - -#define DIO26_PIN 1 -#define DIO26_WPORT PIOD - -#define DIO27_PIN 2 -#define DIO27_WPORT PIOD - -#define DIO28_PIN 3 -#define DIO28_WPORT PIOD - -#define DIO29_PIN 6 -#define DIO29_WPORT PIOD - -#define DIO30_PIN 9 -#define DIO30_WPORT PIOD - -#define DIO31_PIN 7 -#define DIO31_WPORT PIOA - -#define DIO32_PIN 10 -#define DIO32_WPORT PIOD - -#define DIO33_PIN 1 -#define DIO33_WPORT PIOC - -#if !MB(PRINTRBOARD_G2) // normal DUE pin mapping - - #define DIO34_PIN 2 - #define DIO34_WPORT PIOC - - #define DIO35_PIN 3 - #define DIO35_WPORT PIOC - - #define DIO36_PIN 4 - #define DIO36_WPORT PIOC - - #define DIO37_PIN 5 - #define DIO37_WPORT PIOC - - #define DIO38_PIN 6 - #define DIO38_WPORT PIOC - - #define DIO39_PIN 7 - #define DIO39_WPORT PIOC - - #define DIO40_PIN 8 - #define DIO40_WPORT PIOC - - #define DIO41_PIN 9 - #define DIO41_WPORT PIOC - -#endif // !PRINTRBOARD_G2 - -#define DIO42_PIN 19 -#define DIO42_WPORT PIOA - -#define DIO43_PIN 20 -#define DIO43_WPORT PIOA - -#define DIO44_PIN 19 -#define DIO44_WPORT PIOC - -#define DIO45_PIN 18 -#define DIO45_WPORT PIOC - -#define DIO46_PIN 17 -#define DIO46_WPORT PIOC - -#define DIO47_PIN 16 -#define DIO47_WPORT PIOC - -#define DIO48_PIN 15 -#define DIO48_WPORT PIOC - -#define DIO49_PIN 14 -#define DIO49_WPORT PIOC - -#define DIO50_PIN 13 -#define DIO50_WPORT PIOC - -#define DIO51_PIN 12 -#define DIO51_WPORT PIOC - -#define DIO52_PIN 21 -#define DIO52_WPORT PIOB - -#define DIO53_PIN 14 -#define DIO53_WPORT PIOB - -#define DIO54_PIN 16 -#define DIO54_WPORT PIOA - -#define DIO55_PIN 24 -#define DIO55_WPORT PIOA - -#define DIO56_PIN 23 -#define DIO56_WPORT PIOA - -#define DIO57_PIN 22 -#define DIO57_WPORT PIOA - -#define DIO58_PIN 6 -#define DIO58_WPORT PIOA - -#define DIO59_PIN 4 -#define DIO59_WPORT PIOA - -#define DIO60_PIN 3 -#define DIO60_WPORT PIOA - -#define DIO61_PIN 2 -#define DIO61_WPORT PIOA - -#define DIO62_PIN 17 -#define DIO62_WPORT PIOB - -#define DIO63_PIN 18 -#define DIO63_WPORT PIOB - -#define DIO64_PIN 19 -#define DIO64_WPORT PIOB - -#define DIO65_PIN 20 -#define DIO65_WPORT PIOB - -#define DIO66_PIN 15 -#define DIO66_WPORT PIOB - -#define DIO67_PIN 16 -#define DIO67_WPORT PIOB - -#define DIO68_PIN 1 -#define DIO68_WPORT PIOA - -#define DIO69_PIN 0 -#define DIO69_WPORT PIOA - -#define DIO70_PIN 17 -#define DIO70_WPORT PIOA - -#define DIO71_PIN 18 -#define DIO71_WPORT PIOA - -#define DIO72_PIN 30 -#define DIO72_WPORT PIOC - -#define DIO73_PIN 21 -#define DIO73_WPORT PIOA - -#define DIO74_PIN 25 -#define DIO74_WPORT PIOA - -#define DIO75_PIN 26 -#define DIO75_WPORT PIOA - -#define DIO76_PIN 27 -#define DIO76_WPORT PIOA - -#define DIO77_PIN 28 -#define DIO77_WPORT PIOA - -#define DIO78_PIN 23 -#define DIO78_WPORT PIOB - -#define DIO79_PIN 17 -#define DIO79_WPORT PIOA - -#define DIO80_PIN 12 -#define DIO80_WPORT PIOB - -#define DIO81_PIN 8 -#define DIO81_WPORT PIOA - -#define DIO82_PIN 11 -#define DIO82_WPORT PIOA - -#define DIO83_PIN 13 -#define DIO83_WPORT PIOA - -#define DIO84_PIN 4 -#define DIO84_WPORT PIOD - -#define DIO85_PIN 11 -#define DIO85_WPORT PIOB - -#define DIO86_PIN 21 -#define DIO86_WPORT PIOB - -#define DIO87_PIN 29 -#define DIO87_WPORT PIOA - -#define DIO88_PIN 15 -#define DIO88_WPORT PIOB - -#define DIO89_PIN 14 -#define DIO89_WPORT PIOB - -#define DIO90_PIN 1 -#define DIO90_WPORT PIOA - -#define DIO91_PIN 15 -#define DIO91_WPORT PIOB - -#ifdef ARDUINO_SAM_ARCHIM - - #define DIO92_PIN 11 - #define DIO92_WPORT PIOC - - #define DIO93_PIN 2 - #define DIO93_WPORT PIOB - - #define DIO94_PIN 1 - #define DIO94_WPORT PIOB - - #define DIO95_PIN 0 - #define DIO95_WPORT PIOB - - #define DIO96_PIN 10 - #define DIO96_WPORT PIOC - - #define DIO97_PIN 24 - #define DIO97_WPORT PIOB - - #define DIO98_PIN 7 - #define DIO98_WPORT PIOB - - #define DIO99_PIN 6 - #define DIO99_WPORT PIOB - - #define DIO100_PIN 8 - #define DIO100_WPORT PIOB - - #define DIO101_PIN 5 - #define DIO101_WPORT PIOB - - #define DIO102_PIN 4 - #define DIO102_WPORT PIOB - - #define DIO103_PIN 3 - #define DIO103_WPORT PIOB - - #define DIO104_PIN 20 - #define DIO104_WPORT PIOC - - #define DIO105_PIN 22 - #define DIO105_WPORT PIOB - - #define DIO106_PIN 27 - #define DIO106_WPORT PIOC - - #define DIO107_PIN 10 - #define DIO107_WPORT PIOB - - #define DIO108_PIN 9 - #define DIO108_WPORT PIOB - -#else // !ARDUINO_SAM_ARCHIM - - #define DIO92_PIN 5 - #define DIO92_WPORT PIOA - - #define DIO93_PIN 12 - #define DIO93_WPORT PIOB - - #define DIO94_PIN 22 - #define DIO94_WPORT PIOB - - #define DIO95_PIN 23 - #define DIO95_WPORT PIOB - - #define DIO96_PIN 24 - #define DIO96_WPORT PIOB - - #define DIO97_PIN 20 - #define DIO97_WPORT PIOC - - #define DIO98_PIN 27 - #define DIO98_WPORT PIOC - - #define DIO99_PIN 10 - #define DIO99_WPORT PIOC - - #define DIO100_PIN 11 - #define DIO100_WPORT PIOC - -#endif // !ARDUINO_SAM_ARCHIM diff --git a/src/HAL/DUE/fastio/G2_PWM.cpp b/src/HAL/DUE/fastio/G2_PWM.cpp deleted file mode 100644 index 800915f..0000000 --- a/src/HAL/DUE/fastio/G2_PWM.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * The PWM module is only used to generate interrupts at specified times. It - * is NOT used to directly toggle pins. The ISR writes to the pin assigned to - * that interrupt. - * - * All PWMs use the same repetition rate. The G2 needs about 10kHz min in order to - * not have obvious ripple on the Vref signals. - * - * The data structures are setup to minimize the computation done by the ISR which - * minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds. - * - * FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref - * signals are set active when this counter overflows and resets to zero. The compare - * values in channels 1-4 are set to give the desired duty cycle for that Vref pin. - * When counter 0 matches the compare value then that channel generates an interrupt. - * The ISR checks the source of the interrupt and sets the corresponding pin inactive. - * - * Some jitter in the Vref signal is OK so the interrupt priority is left at its default value. - */ - -#include "../../../inc/MarlinConfig.h" - -#if MB(PRINTRBOARD_G2) - -#include "G2_PWM.h" - -#if PIN_EXISTS(MOTOR_CURRENT_PWM_X) - #define G2_PWM_X 1 -#else - #define G2_PWM_X 0 -#endif -#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) - #define G2_PWM_Y 1 -#else - #define G2_PWM_Y 0 -#endif -#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - #define G2_PWM_Z 1 -#else - #define G2_PWM_Z 0 -#endif -#if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - #define G2_PWM_E 1 -#else - #define G2_PWM_E 0 -#endif -#define G2_MASK_X(V) (G2_PWM_X * (V)) -#define G2_MASK_Y(V) (G2_PWM_Y * (V)) -#define G2_MASK_Z(V) (G2_PWM_Z * (V)) -#define G2_MASK_E(V) (G2_PWM_E * (V)) - -volatile uint32_t *SODR_A = &PIOA->PIO_SODR, - *SODR_B = &PIOB->PIO_SODR, - *CODR_A = &PIOA->PIO_CODR, - *CODR_B = &PIOB->PIO_CODR; - -PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT; - -void Stepper::digipot_init() { - - #if PIN_EXISTS(MOTOR_CURRENT_PWM_X) - OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins - #endif - #if PIN_EXISTS(MOTOR_CURRENT_PWM_Y) - OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0); - #endif - #if G2_PWM_Z - OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0); - #endif - #if G2_PWM_E - OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0); - #endif - - #define WPKEY (0x50574D << 8) // “PWM†in ASCII - #define WPCMD_DIS_SW 0 // command to disable Write Protect SW - #define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups - - #define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz - - PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up) - - PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers - PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled - PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned - if (G2_PWM_X) PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned - if (G2_PWM_Y) PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned - if (G2_PWM_Z) PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned - if (G2_PWM_E) PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned - - PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period - - PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows - PWM->PWM_IER2 = PWM_IER2_CMPM0 - | G2_MASK_X(PWM_IER2_CMPM1) - | G2_MASK_Y(PWM_IER2_CMPM2) - | G2_MASK_Z(PWM_IER2_CMPM3) - | G2_MASK_E(PWM_IER2_CMPM4) - ; // generate interrupt on compare event - - if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive - if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive - if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive - if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive - - if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event - if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event - if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event - if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event - - PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 - | G2_MASK_X(PWM_SCM_SYNC1) - | G2_MASK_Y(PWM_SCM_SYNC2) - | G2_MASK_Z(PWM_SCM_SYNC3) - | G2_MASK_E(PWM_SCM_SYNC4) - ; // sync 1-4 with 0, use mode 0 for updates - - PWM->PWM_ENA = PWM_ENA_CHID0 - | G2_MASK_X(PWM_ENA_CHID1) - | G2_MASK_Y(PWM_ENA_CHID2) - | G2_MASK_Z(PWM_ENA_CHID3) - | G2_MASK_E(PWM_ENA_CHID4) - ; // enable channels used by G2 - - PWM->PWM_IER1 = PWM_IER1_CHID0 - | G2_MASK_X(PWM_IER1_CHID1) - | G2_MASK_Y(PWM_IER1_CHID2) - | G2_MASK_Z(PWM_IER1_CHID3) - | G2_MASK_E(PWM_IER1_CHID4) - ; // enable interrupts for channels used by G2 - - NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler - NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals) -} - -void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) { - - if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed - - switch (driver) { - case 0: - if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y - if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); - if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event - if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event - if (G2_PWM_X || G2_PWM_Y) PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - break; - case 1: - if (G2_PWM_Z) { - PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z - PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - } - break; - default: - if (G2_PWM_E) { - PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E - PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event - PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle - } - break; - } -} - -volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS; - -void PWM_Handler() { - PWM_ISR1_STATUS = PWM->PWM_ISR1; - PWM_ISR2_STATUS = PWM->PWM_ISR2; - if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt - if (G2_PWM_X) *ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active - if (G2_PWM_Y) *ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active - if (G2_PWM_Z) *ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active - if (G2_PWM_E) *ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active - } - else { - if (G2_PWM_X && (PWM_ISR2_STATUS & PWM_IER2_CMPM1)) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive - if (G2_PWM_Y && (PWM_ISR2_STATUS & PWM_IER2_CMPM2)) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive - if (G2_PWM_Z && (PWM_ISR2_STATUS & PWM_IER2_CMPM3)) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive - if (G2_PWM_E && (PWM_ISR2_STATUS & PWM_IER2_CMPM4)) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive - } - return; -} - -#endif // PRINTRBOARD_G2 diff --git a/src/HAL/DUE/fastio/G2_PWM.h b/src/HAL/DUE/fastio/G2_PWM.h deleted file mode 100644 index dc4edff..0000000 --- a/src/HAL/DUE/fastio/G2_PWM.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * This module is stripped down version of the LPC1768_PWM.h file from - * PR #7500. It is hardwired for the PRINTRBOARD_G2 Motor Current needs. - */ - -#include "../../../inc/MarlinConfigPre.h" -#include "../../../module/stepper.h" -//C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\module\stepper.h -//C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\HAL\HAL_DUE\G2_PWM.h - -#define PWM_PERIOD_US 100 // base repetition rate in micro seconds - -typedef struct { // holds the data needed by the ISR to control the Vref pin - volatile uint32_t* set_register; - volatile uint32_t* clr_register; - uint32_t write_mask; -} PWM_map; - -#define G2_VREF(I) (uint32_t)(I * 5 * 0.15) // desired Vref * 1000 (scaled so don't loose accuracy in next step) - -#define G2_VREF_COUNT(Q) (uint32_t)map(constrain(Q, 500, 3.3 * 1000), 0, 3.3 * 1000, 0, PWM_PERIOD_US) // under 500 the results are very non-linear - -extern volatile uint32_t *SODR_A, *SODR_B, *CODR_A, *CODR_B; - -#define _PIN(IO) (DIO ## IO ## _PIN) - -#define PWM_MAP_INIT_ROW(IO,ZZ) { ZZ == 'A' ? SODR_A : SODR_B, ZZ == 'A' ? CODR_A : CODR_B, 1 << _PIN(IO) } - - -#define PWM_MAP_INIT { PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_X_PIN, 'B'), \ - PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Y_PIN, 'B'), \ - PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Z_PIN, 'B'), \ - PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_E_PIN, 'A'), \ - }; - -#define NUM_PWMS 4 - -extern PWM_map ISR_table[NUM_PWMS]; - -extern uint32_t motor_current_setting[3]; - -#define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4) -#define COPY_ACTIVE_TABLE() do{ LOOP_L_N(i, 6) work_table[i] = active_table[i]; }while(0) - -#define PWM_MR0 19999 // base repetition rate minus one count - 20mS -#define PWM_PR 24 // prescaler value - prescaler divide by 24 + 1 - 1 MHz output -#define PWM_PCLKSEL0 0x00 // select clock source for prescaler - defaults to 25MHz on power up - // 0: 25MHz, 1: 100MHz, 2: 50MHz, 3: 12.5MHZ to PWM1 prescaler -#define MR0_MARGIN 200 // if channel value too close to MR0 the system locks up - -extern bool PWM_table_swap; // flag to tell the ISR that the tables have been swapped - -#define HAL_G2_PWM_ISR void PWM_Handler() - -extern volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS; diff --git a/src/HAL/DUE/fastio/G2_pins.h b/src/HAL/DUE/fastio/G2_pins.h deleted file mode 100644 index 80c87bd..0000000 --- a/src/HAL/DUE/fastio/G2_pins.h +++ /dev/null @@ -1,278 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -/** - * This file contains the custom port/pin definitions for the PRINTRBOARD_G2 - * motherboard. This motherboard uses the SAM3X8C which is a subset of the - * SAM3X8E used in the DUE board. It uses port/pin pairs that are not - * available using the DUE definitions. - * - * The first part is a copy of the pin descriptions in the - * "variants\arduino_due_x\variant.cpp" file but with pins 34-41 replaced by - * the G2 pins. - * - * The second part is the FASTIO port/pin definitions. - * - * THESE PINS CAN ONLY BE ACCESSED VIA FASTIO COMMANDS. - */ - -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -typedef struct _G2_PinDescription { - Pio* pPort; - uint32_t ulPin; - uint32_t ulPeripheralId; - EPioType ulPinType; - uint32_t ulPinConfiguration; - uint32_t ulPinAttribute; - EAnalogChannel ulAnalogChannel; /* Analog pin in the Arduino context (label on the board) */ - EAnalogChannel ulADCChannelNumber; /* ADC Channel number in the SAM device */ - EPWMChannel ulPWMChannel; - ETCChannel ulTCChannel; -} G2_PinDescription; - -/** - * This section is a copy of the pin descriptions in the "variants\arduino_due_x\variant.cpp" file - * with pins 34-41 replaced by the G2 pins. - */ - -/** - * Pins descriptions - */ -const G2_PinDescription G2_g_APinDescription[] = { - // 0 .. 53 - Digital pins - // ---------------------- - // 0/1 - UART (Serial) - { PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD - { PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD - - // 2 - { PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0 - { PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7 - { PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6 - - // 5 - { PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6 - { PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7 - { PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6 - { PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5 - { PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4 - // 10 - { PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7 - { PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8 - { PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8 - - // 13 - AMBER LED - { PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0 - - // 14/15 - USART3 (Serial3) - { PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3 - { PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3 - - // 16/17 - USART1 (Serial2) - { PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1 - { PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1 - - // 18/19 - USART0 (Serial1) - { PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0 - { PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0 - - // 20/21 - TWI1 - { PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0 - { PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0 - - // 22 - { PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22 - { PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23 - { PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24 - { PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25 - - // 26 - { PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26 - { PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27 - { PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28 - { PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29 - - // 30 - { PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30 - { PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31 - { PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32 - { PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33 - - // 34 - - // start of custom pins - { PIOA, PIO_PA29, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34 Y_STEP_PIN - { PIOB, PIO_PB1, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35 Y_DIR_PIN - { PIOB, PIO_PB0, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36 Y_ENABLE_PIN - { PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37 E0_ENABLE_PIN - { PIOB, PIO_PB11, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38 E0_MS1_PIN - { PIOB, PIO_PB10, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39 E0_MS3_PIN - { PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40 HEATER_0_PIN - { PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41 HEATER_BED_PIN - // end of custom pins - - // 42 - { PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42 - { PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43 - { PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44 - { PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45 - - // 46 - { PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46 - { PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47 - { PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48 - { PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49 - - // 50 - { PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50 - { PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51 - { PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52 - { PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53 - - - // 54 .. 65 - Analog pins - // ---------------------- - { PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0 - { PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1 - { PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2 - { PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3 - // 58 - { PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4 - { PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5 - { PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6 - { PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7 - // 62 - { PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8 - { PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9 - { PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10 - { PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11 - - // 66/67 - DAC0/DAC1 - { PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0 - { PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1 - - // 68/69 - CANRX0/CANTX0 - { PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX - { PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX - - // 70/71 - TWI0 - { PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1 - { PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1 - - // 72/73 - LEDs - { PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL - { PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL - - // 74/75/76 - SPI - { PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO - { PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI - { PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK - - // 77 - SPI CS0 - { PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0 - - // 78 - SPI CS3 (unconnected) - { PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3 - - // 79 .. 84 - "All pins" masks - - // 79 - TWI0 all pins - { PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 80 - TWI1 all pins - { PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 81 - UART (Serial) all pins - { PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 82 - USART0 (Serial1) all pins - { PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 83 - USART1 (Serial2) all pins - { PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 84 - USART3 (Serial3) all pins - { PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - - // 85 - USB - { PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF - - // 86 - SPI CS2 - { PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2 - - // 87 - SPI CS1 - { PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1 - - // 88/89 - CANRX1/CANTX1 (same physical pin for 66/53) - { PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1 - { PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1 - - // 90 .. 91 - "All CAN pins" masks - // 90 - CAN0 all pins - { PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - // 91 - CAN1 all pins - { PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, - - // END - { nullptr, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER } -}; - -// This section replaces the FASTIO definitions of pins 34-41 - -#define DIO34_PIN 29 -#define DIO34_WPORT PIOA // only available via FASTIO // 34 PA29 - Y_STEP_PIN - -#define DIO35_PIN 1 -#define DIO35_WPORT PIOB // only available via FASTIO // 35 PAB1 - Y_DIR_PIN - -#define DIO36_PIN 0 -#define DIO36_WPORT PIOB // only available via FASTIO // 36 PB0 - Y_ENABLE_PIN - -#define DIO37_PIN 22 -#define DIO37_WPORT PIOB // only available via FASTIO // 37 PB22 - E0_ENABLE_PIN - -#define DIO38_PIN 11 -#define DIO38_WPORT PIOB // only available via FASTIO // 38 PB11 - E0_MS1_PIN - -#define DIO39_PIN 10 -#define DIO39_WPORT PIOB // only available via FASTIO // 39 PB10 - E0_MS3_PIN - -#define DIO40_PIN 5 -#define DIO40_WPORT PIOA // only available via FASTIO // 40 PA5 - HEATER_0_PIN - -#define DIO41_PIN 24 -#define DIO41_WPORT PIOB // only available via FASTIO // 41 PB24 - HEATER_BED_PIN diff --git a/src/HAL/DUE/inc/Conditionals_LCD.h b/src/HAL/DUE/inc/Conditionals_LCD.h deleted file mode 100644 index 5867414..0000000 --- a/src/HAL/DUE/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/DUE." -#endif diff --git a/src/HAL/DUE/inc/Conditionals_adv.h b/src/HAL/DUE/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/DUE/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/DUE/inc/Conditionals_post.h b/src/HAL/DUE/inc/Conditionals_post.h deleted file mode 100644 index ce6d3fd..0000000 --- a/src/HAL/DUE/inc/Conditionals_post.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define FLASH_EEPROM_EMULATION -#elif EITHER(I2C_EEPROM, SPI_EEPROM) - #define USE_SHARED_EEPROM 1 -#endif diff --git a/src/HAL/DUE/inc/SanityCheck.h b/src/HAL/DUE/inc/SanityCheck.h deleted file mode 100644 index 13484f7..0000000 --- a/src/HAL/DUE/inc/SanityCheck.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test Arduino Due specific configuration values for errors at compile-time. - */ - -/** - * Check for common serial pin conflicts - */ -#define CHECK_SERIAL_PIN(N) ( \ - X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \ - || X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \ - || X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \ - || X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \ - || X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \ - || X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \ -) -#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts. -#endif -#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)) - #error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board." -#endif -#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17)) - #error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board." -#endif -#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15)) - #error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board." -#endif -#undef CHECK_SERIAL_PIN - -/** - * HARDWARE VS. SOFTWARE SPI COMPATIBILITY - * - * DUE selects hardware vs. software SPI depending on whether one of the hardware-controllable SDSS pins is in use. - * - * The hardware SPI controller doesn't allow software SPIs to control any shared pins. - * - * When DUE software SPI is used then Trinamic drivers must use the TMC softSPI. - * - * When DUE hardware SPI is used then a Trinamic driver can use either its hardware SPI or, if there are no shared - * pins, its software SPI. - * - * Usually the hardware SPI pins are only available to the LCD. This makes the DUE hard SPI used at the same time - * as the TMC2130 soft SPI the most common setup. - */ -#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == SD_MOSI_PIN || TMC_SW_##P == SD_MISO_PIN || TMC_SW_##P == SD_SCK_PIN)) - -#if ENABLED(SDSUPPORT) && HAS_DRIVER(TMC2130) - #if ENABLED(TMC_USE_SW_SPI) - #if DISABLED(DUE_SOFTWARE_SPI) && (_IS_HW_SPI(MOSI) || _IS_HW_SPI(MISO) || _IS_HW_SPI(SCK)) - #error "DUE hardware SPI is required but is incompatible with TMC2130 software SPI. Either disable TMC_USE_SW_SPI or use separate pins for the two SPIs." - #endif - #elif ENABLED(DUE_SOFTWARE_SPI) - #error "DUE software SPI is required but is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix." - #endif -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on DUE." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on the DUE platform." -#endif - -#if USING_PULLDOWNS - #error "PULLDOWN pin mode is not available on DUE boards." -#endif diff --git a/src/HAL/DUE/pinsDebug.h b/src/HAL/DUE/pinsDebug.h deleted file mode 100644 index df1ba41..0000000 --- a/src/HAL/DUE/pinsDebug.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Support routines for Due - */ - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#include "../shared/Marduino.h" - -/** - * Due/Marlin quirks - * - * a) determining the state of a pin - * The Due/Arduino status definitions for the g_pinStatus[pin] array are: - * #define PIN_STATUS_DIGITAL_INPUT_PULLUP (0x01) - * #define PIN_STATUS_DIGITAL_INPUT (0x02) - * #define PIN_STATUS_DIGITAL_OUTPUT (0x03) - * #define PIN_STATUS_ANALOG (0x04) - * #define PIN_STATUS_PWM (0x05) - * #define PIN_STATUS_TIMER (0x06) - * - * These are only valid if the following Due/Arduino provided functions are used: - * analogRead - * analogWrite - * digitalWrite - * pinMode - * - * The FASTIO routines do not touch the g_pinStatus[pin] array. - * - * The net result is that both the g_pinStatus[pin] array and the PIO_OSR register - * needs to be looked at when determining if a pin is an input or an output. - * - * b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1kHz - * - * c) NUM_DIGITAL_PINS does not include the analog pins - * - * d) Pins 0-78 are defined for Due but 78 has a comment of "unconnected!". 78 is - * included just in case. - */ - -#define NUMBER_PINS_TOTAL PINS_COUNT - -#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin -#define PRINT_PORT(p) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) -#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) -#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \ - ((g_APinDescription[pin].ulPinAttribute & PIN_ATTR_PWM) == PIN_ATTR_PWM)) -#define MULTI_NAME_PAD 14 // space needed to be pretty if not first name assigned to a pin - -bool GET_PINMODE(int8_t pin) { // 1: output, 0: input - volatile Pio* port = g_APinDescription[pin].pPort; - uint32_t mask = g_APinDescription[pin].ulPin; - uint8_t pin_status = g_pinStatus[pin] & 0xF; - return ( (pin_status == 0 && (port->PIO_OSR & mask)) - || pin_status == PIN_STATUS_DIGITAL_OUTPUT - || pwm_status(pin)); -} - -void pwm_details(int32_t pin) { - if (pwm_status(pin)) { - uint32_t chan = g_APinDescription[pin].ulPWMChannel; - SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY); - } -} - -/** - * DUE Board pin | PORT | Label - * ----------------+--------+------- - * 0 | PA8 | "RX0" - * 1 | PA9 | "TX0" - * 2 TIOA0 | PB25 | - * 3 TIOA7 | PC28 | - * 4 NPCS1 | PA29 | - * TIOB6 | PC26 | - * 5 TIOA6 | PC25 | - * 6 PWML7 | PC24 | - * 7 PWML6 | PC23 | - * 8 PWML5 | PC22 | - * 9 PWML4 | PC21 | - * 10 NPCS0 | PA28 | - * TIOB7 | PC29 | - * 11 TIOA8 | PD7 | - * 12 TIOB8 | PD8 | - * 13 TIOB0 | PB27 | LED AMBER "L" - * 14 TXD3 | PD4 | "TX3" - * 15 RXD3 | PD5 | "RX3" - * 16 TXD1 | PA13 | "TX2" - * 17 RXD1 | PA12 | "RX2" - * 18 TXD0 | PA11 | "TX1" - * 19 RXD0 | PA10 | "RX1" - * 20 | PB12 | "SDA" - * 21 | PB13 | "SCL" - * 22 | PB26 | - * 23 | PA14 | - * 24 | PA15 | - * 25 | PD0 | - * 26 | PD1 | - * 27 | PD2 | - * 28 | PD3 | - * 29 | PD6 | - * 30 | PD9 | - * 31 | PA7 | - * 32 | PD10 | - * 33 | PC1 | - * 34 | PC2 | - * 35 | PC3 | - * 36 | PC4 | - * 37 | PC5 | - * 38 | PC6 | - * 39 | PC7 | - * 40 | PC8 | - * 41 | PC9 | - * 42 | PA19 | - * 43 | PA20 | - * 44 | PC19 | - * 45 | PC18 | - * 46 | PC17 | - * 47 | PC16 | - * 48 | PC15 | - * 49 | PC14 | - * 50 | PC13 | - * 51 | PC12 | - * 52 NPCS2 | PB21 | - * 53 | PB14 | - * 54 | PA16 | "A0" - * 55 | PA24 | "A1" - * 56 | PA23 | "A2" - * 57 | PA22 | "A3" - * 58 TIOB2 | PA6 | "A4" - * 69 | PA4 | "A5" - * 60 TIOB1 | PA3 | "A6" - * 61 TIOA1 | PA2 | "A7" - * 62 | PB17 | "A8" - * 63 | PB18 | "A9" - * 64 | PB19 | "A10" - * 65 | PB20 | "A11" - * 66 | PB15 | "DAC0" - * 67 | PB16 | "DAC1" - * 68 | PA1 | "CANRX" - * 69 | PA0 | "CANTX" - * 70 | PA17 | "SDA1" - * 71 | PA18 | "SCL1" - * 72 | PC30 | LED AMBER "RX" - * 73 | PA21 | LED AMBER "TX" - * 74 MISO | PA25 | - * 75 MOSI | PA26 | - * 76 SCLK | PA27 | - * 77 NPCS0 | PA28 | - * 78 NPCS3 | PB23 | unconnected! - * - * USB pin | PORT - * ----------------+-------- - * ID | PB11 - * VBOF | PB10 - */ diff --git a/src/HAL/DUE/spi_pins.h b/src/HAL/DUE/spi_pins.h deleted file mode 100644 index cec22c2..0000000 --- a/src/HAL/DUE/spi_pins.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Define SPI Pins: SCK, MISO, MOSI, SS - * - * Available chip select pins for HW SPI are 4 10 52 77 - */ -#if SDSS == 4 || SDSS == 10 || SDSS == 52 || SDSS == 77 || SDSS == 87 - #if SDSS == 4 - #define SPI_PIN 87 - #define SPI_CHAN 1 - #elif SDSS == 10 - #define SPI_PIN 77 - #define SPI_CHAN 0 - #elif SDSS == 52 - #define SPI_PIN 86 - #define SPI_CHAN 2 - #elif SDSS == 77 - #define SPI_PIN 77 - #define SPI_CHAN 0 - #else - #define SPI_PIN 87 - #define SPI_CHAN 1 - #endif - #define SD_SCK_PIN 76 - #define SD_MISO_PIN 74 - #define SD_MOSI_PIN 75 -#else - // defaults - #define DUE_SOFTWARE_SPI - #ifndef SD_SCK_PIN - #define SD_SCK_PIN 52 - #endif - #ifndef SD_MISO_PIN - #define SD_MISO_PIN 50 - #endif - #ifndef SD_MOSI_PIN - #define SD_MOSI_PIN 51 - #endif -#endif - -/* A.28, A.29, B.21, C.26, C.29 */ -#define SD_SS_PIN SDSS diff --git a/src/HAL/DUE/timers.cpp b/src/HAL/DUE/timers.cpp deleted file mode 100644 index e564781..0000000 --- a/src/HAL/DUE/timers.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Timers for Arduino Due and compatible (SAM3X8E) - */ - -#ifdef ARDUINO_ARCH_SAM - -// ------------------------ -// Includes -// ------------------------ -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -// ------------------------ -// Local defines -// ------------------------ - -#define NUM_HARDWARE_TIMERS 9 - -// ------------------------ -// Private Variables -// ------------------------ - -const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = { - { TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5] - { TC0, 1, TC1_IRQn, 0}, // 1 - { TC0, 2, TC2_IRQn, 2}, // 2 - stepper - { TC1, 0, TC3_IRQn, 0}, // 3 - stepper for BOARD_ARCHIM1 - { TC1, 1, TC4_IRQn, 15}, // 4 - temperature - { TC1, 2, TC5_IRQn, 3}, // 5 - [servo timer3] - { TC2, 0, TC6_IRQn, 14}, // 6 - tone - { TC2, 1, TC7_IRQn, 0}, // 7 - { TC2, 2, TC8_IRQn, 0}, // 8 -}; - -// ------------------------ -// Public functions -// ------------------------ - -/* - Timer_clock1: Prescaler 2 -> 42MHz - Timer_clock2: Prescaler 8 -> 10.5MHz - Timer_clock3: Prescaler 32 -> 2.625MHz - Timer_clock4: Prescaler 128 -> 656.25kHz -*/ - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - Tc *tc = timer_config[timer_num].pTimerRegs; - IRQn_Type irq = timer_config[timer_num].IRQ_Id; - uint32_t channel = timer_config[timer_num].channel; - - // Disable interrupt, just in case it was already enabled - NVIC_DisableIRQ(irq); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - // Disable timer interrupt - tc->TC_CHANNEL[channel].TC_IDR = TC_IDR_CPCS; - - // Stop timer, just in case, to be able to reconfigure it - TC_Stop(tc, channel); - - pmc_set_writeprotect(false); - pmc_enable_periph_clk((uint32_t)irq); - NVIC_SetPriority(irq, timer_config[timer_num].priority); - - // wave mode, reset counter on match with RC, - TC_Configure(tc, channel, - TC_CMR_WAVE - | TC_CMR_WAVSEL_UP_RC - | (HAL_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0) - | (HAL_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0) - | (HAL_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0) - | (HAL_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0) - ); - - // Set compare value - TC_SetRC(tc, channel, VARIANT_MCK / (HAL_TIMER_PRESCALER) / frequency); - - // And start timer - TC_Start(tc, channel); - - // enable interrupt on RC compare - tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPCS; - - // Finally, enable IRQ - NVIC_EnableIRQ(irq); -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - IRQn_Type irq = timer_config[timer_num].IRQ_Id; - NVIC_EnableIRQ(irq); -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - IRQn_Type irq = timer_config[timer_num].IRQ_Id; - NVIC_DisableIRQ(irq); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); -} - -// missing from CMSIS: Check if interrupt is enabled or not -static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) { - return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - IRQn_Type irq = timer_config[timer_num].IRQ_Id; - return NVIC_GetEnabledIRQ(irq); -} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/timers.h b/src/HAL/DUE/timers.h deleted file mode 100644 index dc35c77..0000000 --- a/src/HAL/DUE/timers.h +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Timers for Arduino Due and compatible (SAM3X8E) - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define HAL_TIMER_PRESCALER 2 -#define HAL_TIMER_RATE ((F_CPU) / (HAL_TIMER_PRESCALER)) // frequency of timers peripherals - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 2 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 4 // Timer Index for Temperature -#endif -#ifndef MF_TIMER_TONE - #define MF_TIMER_TONE 6 // index of timer to use for beeper tones -#endif - -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() void TC2_Handler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() void TC4_Handler() -#endif -#ifndef HAL_TONE_TIMER_ISR - #define HAL_TONE_TIMER_ISR() void TC6_Handler() -#endif - -// ------------------------ -// Types -// ------------------------ - -typedef struct { - Tc *pTimerRegs; - uint16_t channel; - IRQn_Type IRQ_Id; - uint8_t priority; -} tTimerConfig; - -// ------------------------ -// Public Variables -// ------------------------ - -extern const tTimerConfig timer_config[]; - -// ------------------------ -// Public functions -// ------------------------ - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - const tTimerConfig * const pConfig = &timer_config[timer_num]; - pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = compare; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - const tTimerConfig * const pConfig = &timer_config[timer_num]; - return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - const tTimerConfig * const pConfig = &timer_config[timer_num]; - return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV; -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { - const tTimerConfig * const pConfig = &timer_config[timer_num]; - // Reading the status register clears the interrupt flag - pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR; -} - -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/DUE/upload_extra_script.py b/src/HAL/DUE/upload_extra_script.py deleted file mode 100644 index 4f7a494..0000000 --- a/src/HAL/DUE/upload_extra_script.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# Set upload_command -# -# Windows: bossac.exe -# Other: leave unchanged -# -import pioutil -if pioutil.is_pio_build(): - import platform - current_OS = platform.system() - - if current_OS == 'Windows': - - Import("env") - - # Use bossac.exe on Windows - env.Replace( - UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE" - ) diff --git a/src/HAL/DUE/usb/arduino_due_x.h b/src/HAL/DUE/usb/arduino_due_x.h deleted file mode 100644 index e7b6f3d..0000000 --- a/src/HAL/DUE/usb/arduino_due_x.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * \file - * - * \brief Arduino Due/X Board Definition. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -#pragma once - -/** - * Support and FAQ: visit Atmel Support - */ - -/** - * \page arduino_due_x_opfreq "Arduino Due/X - Operating frequencies" - * This page lists several definition related to the board operating frequency - * - * \section Definitions - * - \ref BOARD_FREQ_* - * - \ref BOARD_MCK - */ - -/*! Board oscillator settings */ -#define BOARD_FREQ_SLCK_XTAL (32768U) -#define BOARD_FREQ_SLCK_BYPASS (32768U) -#define BOARD_FREQ_MAINCK_XTAL (12000000U) -#define BOARD_FREQ_MAINCK_BYPASS (12000000U) - -/*! Master clock frequency */ -#define BOARD_MCK CHIP_FREQ_CPU_MAX -#define BOARD_NO_32K_XTAL - -/** board main clock xtal startup time */ -#define BOARD_OSC_STARTUP_US 15625 - -/* ------------------------------------------------------------------------ */ - -/** - * \page arduino_due_x_board_info "Arduino Due/X - Board information" - * This page lists several definition related to the board description. - * - */ - -/* ------------------------------------------------------------------------ */ -/* USB */ -/* ------------------------------------------------------------------------ */ -/*! USB OTG VBus On/Off: Bus Power Control Port. */ -#define PIN_UOTGHS_VBOF { PIO_PB10, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP } -/*! USB OTG Identification: Mini Connector Identification Port. */ -#define PIN_UOTGHS_ID { PIO_PB11, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP } - -/*! Multiplexed pin used for USB_ID: */ -#define USB_ID PIO_PB11_IDX -#define USB_ID_GPIO (PIO_PB11_IDX) -#define USB_ID_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) -/*! Multiplexed pin used for USB_VBOF: */ -#define USB_VBOF PIO_PB10_IDX -#define USB_VBOF_GPIO (PIO_PB10_IDX) -#define USB_VBOF_FLAGS (PIO_PERIPH_A | PIO_DEFAULT) -/*! Active level of the USB_VBOF output pin. */ -#define USB_VBOF_ACTIVE_STATE LOW -/* ------------------------------------------------------------------------ */ diff --git a/src/HAL/DUE/usb/compiler.h b/src/HAL/DUE/usb/compiler.h deleted file mode 100644 index 6331979..0000000 --- a/src/HAL/DUE/usb/compiler.h +++ /dev/null @@ -1,1150 +0,0 @@ -/** - * \file - * - * \brief Commonly used includes, types and macros. - * - * Copyright (c) 2010-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef UTILS_COMPILER_H -#define UTILS_COMPILER_H - -#include -#include -#include "arduino_due_x.h" -#include "conf_clock.h" -#ifdef SAM3XA_SERIES -#define SAM3XA 1 -#endif -#define UDD_NO_SLEEP_MGR 1 -#define pmc_is_wakeup_clocks_restored() true - -#undef udd_get_endpoint_size_max -#define UDD_USB_INT_FUN USBD_ISR - -/** - * \defgroup group_sam_utils Compiler abstraction layer and code utilities - * - * Compiler abstraction layer and code utilities for AT91SAM. - * This module provides various abstraction layers and utilities to make code compatible between different compilers. - * - * \{ - */ -#include - -#if (defined __ICCARM__) -# include -#endif - -#include -#include "preprocessor.h" - -//_____ D E C L A R A T I O N S ____________________________________________ - -#ifndef __ASSEMBLY__ // Not defined for assembling. - -#include -#include -#include -#include - -#ifdef __ICCARM__ -/*! \name Compiler Keywords - * - * Port of some keywords from GCC to IAR Embedded Workbench. - */ -//! @{ -#define __asm__ asm -#define __inline__ inline -#define __volatile__ -//! @} - -#endif - -#define FUNC_PTR void * -/** - * \def UNUSED - * \brief Marking \a v as a unused parameter or value. - */ -#ifndef UNUSED - #define UNUSED(x) ((void)(x)) -#endif - -/** - * \def unused - * \brief Marking \a v as a unused parameter or value. - */ -#define unused(v) do { (void)(v); }while(0) - -/** - * \def barrier - * \brief Memory barrier - */ -#define barrier() __DMB() - -/** - * \brief Emit the compiler pragma \a arg. - * - * \param arg The pragma directive as it would appear after \e \#pragma - * (i.e. not stringified). - */ -#define COMPILER_PRAGMA(arg) _Pragma(#arg) - -/** - * \def COMPILER_PACK_SET(alignment) - * \brief Set maximum alignment for subsequent struct and union - * definitions to \a alignment. - */ -#define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) - -/** - * \def COMPILER_PACK_RESET() - * \brief Set default alignment for subsequent struct and union - * definitions. - */ -#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) - - -/** - * \brief Set aligned boundary. - */ -#if (defined __GNUC__) || (defined __CC_ARM) -# define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) -#elif (defined __ICCARM__) -# define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) -#endif - -/** - * \brief Set word-aligned boundary. - */ -#if (defined __GNUC__) || defined(__CC_ARM) -#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) -#elif (defined __ICCARM__) -#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) -#endif - -/** - * \def __always_inline - * \brief The function should always be inlined. - * - * This annotation instructs the compiler to ignore its inlining - * heuristics and inline the function no matter how big it thinks it - * becomes. - */ -#ifdef __CC_ARM -# define __always_inline __forceinline -#elif (defined __GNUC__) -#ifdef __always_inline -# undef __always_inline -#endif -# define __always_inline inline __attribute__((__always_inline__)) -#elif (defined __ICCARM__) -# define __always_inline _Pragma("inline=forced") -#endif - -/** - * \def __no_inline - * \brief The function should not be inlined. - * - * This annotation instructs the compiler to ignore its inlining - * heuristics and not inline the function. - */ -#ifdef __CC_ARM -# define __no_inline __attribute__((noinline)) -#elif (defined __GNUC__) -# define __no_inline __attribute__((__noinline__)) -#elif (defined __ICCARM__) -# define __no_inline _Pragma("inline=never") -#endif - -/*! \brief This macro is used to test fatal errors. - * - * The macro tests if the expression is false. If it is, a fatal error is - * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO - * is defined, a unit test version of the macro is used, to allow execution - * of further tests after a false expression. - * - * \param expr Expression to evaluate and supposed to be nonzero. - */ -#ifdef _ASSERT_ENABLE_ -# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) - // Assert() is defined in unit_test/suite.h -# include "unit_test/suite.h" -# else -#undef TEST_SUITE_DEFINE_ASSERT_MACRO -# define Assert(expr) \ - {\ - if (!(expr)) while (true);\ - } -# endif -#else -# define Assert(expr) ((void) 0) -#endif - -/* Define WEAK attribute */ -#if defined ( __CC_ARM ) /* Keil µVision 4 */ -# define WEAK __attribute__ ((weak)) -#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ -# define WEAK __weak -#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ -# define WEAK __attribute__ ((weak)) -#endif - -/* Define NO_INIT attribute */ -#if 0 //ndef NO_INIT -#ifdef __CC_ARM -# define NO_INIT __attribute__((zero_init)) -#elif defined ( __ICCARM__ ) -# define NO_INIT __no_init -#elif defined ( __GNUC__ ) -# define NO_INIT __attribute__((section(".no_init"))) -#endif -#endif - -/* Define RAMFUNC attribute */ -#if defined ( __CC_ARM ) /* Keil µVision 4 */ -# define RAMFUNC __attribute__ ((section(".ramfunc"))) -#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ -# define RAMFUNC __ramfunc -#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ -# define RAMFUNC __attribute__ ((section(".ramfunc"))) -#endif - -/* Define OPTIMIZE_HIGH attribute */ -#if defined ( __CC_ARM ) /* Keil µVision 4 */ -# define OPTIMIZE_HIGH _Pragma("O3") -#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ -# define OPTIMIZE_HIGH _Pragma("optimize=high") -#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ -# define OPTIMIZE_HIGH __attribute__((optimize("s"))) -#endif - -/*! \name Usual Types - */ -//! @{ -typedef unsigned char Bool; //!< Boolean. -#ifndef __cplusplus -#ifndef __bool_true_false_are_defined -typedef unsigned char bool; //!< Boolean. -#endif -#endif -typedef int8_t S8 ; //!< 8-bit signed integer. -typedef uint8_t U8 ; //!< 8-bit unsigned integer. -typedef int16_t S16; //!< 16-bit signed integer. -typedef uint16_t U16; //!< 16-bit unsigned integer. -typedef uint16_t le16_t; -typedef uint16_t be16_t; -typedef int32_t S32; //!< 32-bit signed integer. -typedef uint32_t U32; //!< 32-bit unsigned integer. -typedef uint32_t le32_t; -typedef uint32_t be32_t; -typedef int64_t S64; //!< 64-bit signed integer. -typedef uint64_t U64; //!< 64-bit unsigned integer. -typedef float F32; //!< 32-bit floating-point number. -typedef double F64; //!< 64-bit floating-point number. -typedef uint32_t iram_size_t; -//! @} - - -/*! \name Status Types - */ -//! @{ -typedef bool Status_bool_t; //!< Boolean status. -typedef U8 Status_t; //!< 8-bit-coded status. -//! @} - - -/*! \name Aliasing Aggregate Types - */ -//! @{ - -//! 16-bit union. -typedef union -{ - S16 s16 ; - U16 u16 ; - S8 s8 [2]; - U8 u8 [2]; -} Union16; - -//! 32-bit union. -typedef union -{ - S32 s32 ; - U32 u32 ; - S16 s16[2]; - U16 u16[2]; - S8 s8 [4]; - U8 u8 [4]; -} Union32; - -//! 64-bit union. -typedef union -{ - S64 s64 ; - U64 u64 ; - S32 s32[2]; - U32 u32[2]; - S16 s16[4]; - U16 u16[4]; - S8 s8 [8]; - U8 u8 [8]; -} Union64; - -//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. -typedef union -{ - S64 *s64ptr; - U64 *u64ptr; - S32 *s32ptr; - U32 *u32ptr; - S16 *s16ptr; - U16 *u16ptr; - S8 *s8ptr ; - U8 *u8ptr ; -} UnionPtr; - -//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. -typedef union -{ - volatile S64 *s64ptr; - volatile U64 *u64ptr; - volatile S32 *s32ptr; - volatile U32 *u32ptr; - volatile S16 *s16ptr; - volatile U16 *u16ptr; - volatile S8 *s8ptr ; - volatile U8 *u8ptr ; -} UnionVPtr; - -//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. -typedef union -{ - const S64 *s64ptr; - const U64 *u64ptr; - const S32 *s32ptr; - const U32 *u32ptr; - const S16 *s16ptr; - const U16 *u16ptr; - const S8 *s8ptr ; - const U8 *u8ptr ; -} UnionCPtr; - -//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. -typedef union -{ - const volatile S64 *s64ptr; - const volatile U64 *u64ptr; - const volatile S32 *s32ptr; - const volatile U32 *u32ptr; - const volatile S16 *s16ptr; - const volatile U16 *u16ptr; - const volatile S8 *s8ptr ; - const volatile U8 *u8ptr ; -} UnionCVPtr; - -//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. -typedef struct -{ - S64 *s64ptr; - U64 *u64ptr; - S32 *s32ptr; - U32 *u32ptr; - S16 *s16ptr; - U16 *u16ptr; - S8 *s8ptr ; - U8 *u8ptr ; -} StructPtr; - -//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. -typedef struct -{ - volatile S64 *s64ptr; - volatile U64 *u64ptr; - volatile S32 *s32ptr; - volatile U32 *u32ptr; - volatile S16 *s16ptr; - volatile U16 *u16ptr; - volatile S8 *s8ptr ; - volatile U8 *u8ptr ; -} StructVPtr; - -//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. -typedef struct -{ - const S64 *s64ptr; - const U64 *u64ptr; - const S32 *s32ptr; - const U32 *u32ptr; - const S16 *s16ptr; - const U16 *u16ptr; - const S8 *s8ptr ; - const U8 *u8ptr ; -} StructCPtr; - -//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. -typedef struct -{ - const volatile S64 *s64ptr; - const volatile U64 *u64ptr; - const volatile S32 *s32ptr; - const volatile U32 *u32ptr; - const volatile S16 *s16ptr; - const volatile U16 *u16ptr; - const volatile S8 *s8ptr ; - const volatile U8 *u8ptr ; -} StructCVPtr; - -//! @} - -#endif // #ifndef __ASSEMBLY__ - -/*! \name Usual Constants - */ -//! @{ -#define DISABLE 0 -#define ENABLE 1 -#ifndef __cplusplus -#ifndef __bool_true_false_are_defined -#define false (1==0) -#define true (1==1) -#endif -#endif -#ifndef PASS -#define PASS 0 -#endif -#ifndef FAIL -#define FAIL 1 -#endif -#ifndef LOW -#define LOW 0x0 -#endif -#ifndef HIGH -#define HIGH 0x1 -#endif -//! @} - - -#ifndef __ASSEMBLY__ // not for assembling. - -//! \name Optimization Control -//@{ - -/** - * \def likely(exp) - * \brief The expression \a exp is likely to be true - */ -#ifndef likely -# define likely(exp) (exp) -#endif - -/** - * \def unlikely(exp) - * \brief The expression \a exp is unlikely to be true - */ -#ifndef unlikely -# define unlikely(exp) (exp) -#endif - -/** - * \def is_constant(exp) - * \brief Determine if an expression evaluates to a constant value. - * - * \param exp Any expression - * - * \return true if \a exp is constant, false otherwise. - */ -#if (defined __GNUC__) || (defined __CC_ARM) -# define is_constant(exp) __builtin_constant_p(exp) -#else -# define is_constant(exp) (0) -#endif - -//! @} - -/*! \name Bit-Field Handling - */ -//! @{ - -/*! \brief Reads the bits of a value specified by a given bit-mask. - * - * \param value Value to read bits from. - * \param mask Bit-mask indicating bits to read. - * - * \return Read bits. - */ -#define Rd_bits( value, mask) ((value) & (mask)) - -/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. - * - * \param lvalue C lvalue to write bits to. - * \param mask Bit-mask indicating bits to write. - * \param bits Bits to write. - * - * \return Resulting value with written bits. - */ -#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ - ((bits ) & (mask))) - -/*! \brief Tests the bits of a value specified by a given bit-mask. - * - * \param value Value of which to test bits. - * \param mask Bit-mask indicating bits to test. - * - * \return \c 1 if at least one of the tested bits is set, else \c 0. - */ -#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) - -/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. - * - * \param lvalue C lvalue of which to clear bits. - * \param mask Bit-mask indicating bits to clear. - * - * \return Resulting value with cleared bits. - */ -#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) - -/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. - * - * \param lvalue C lvalue of which to set bits. - * \param mask Bit-mask indicating bits to set. - * - * \return Resulting value with set bits. - */ -#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) - -/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. - * - * \param lvalue C lvalue of which to toggle bits. - * \param mask Bit-mask indicating bits to toggle. - * - * \return Resulting value with toggled bits. - */ -#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) - -/*! \brief Reads the bit-field of a value specified by a given bit-mask. - * - * \param value Value to read a bit-field from. - * \param mask Bit-mask indicating the bit-field to read. - * - * \return Read bit-field. - */ -#define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask)) - -/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. - * - * \param lvalue C lvalue to write a bit-field to. - * \param mask Bit-mask indicating the bit-field to write. - * \param bitfield Bit-field to write. - * - * \return Resulting value with written bit-field. - */ -#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask))) - -//! @} - - -/*! \name Zero-Bit Counting - * - * Under GCC, __builtin_clz and __builtin_ctz behave like macros when - * applied to constant expressions (values known at compile time), so they are - * more optimized than the use of the corresponding assembly instructions and - * they can be used as constant expressions e.g. to initialize objects having - * static storage duration, and like the corresponding assembly instructions - * when applied to non-constant expressions (values unknown at compile time), so - * they are more optimized than an assembly periphrasis. Hence, clz and ctz - * ensure a possible and optimized behavior for both constant and non-constant - * expressions. - */ -//! @{ - -/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer. - * - * \param u Value of which to count the leading zero bits. - * - * \return The count of leading zero bits in \a u. - */ -#ifndef clz -#if (defined __GNUC__) || (defined __CC_ARM) -# define clz(u) ((u) ? __builtin_clz(u) : 32) -#elif (defined __ICCARM__) -# define clz(u) ((u) ? __CLZ(u) : 32) -#else -# define clz(u) (((u) == 0) ? 32 : \ - ((u) & (1UL << 31)) ? 0 : \ - ((u) & (1UL << 30)) ? 1 : \ - ((u) & (1UL << 29)) ? 2 : \ - ((u) & (1UL << 28)) ? 3 : \ - ((u) & (1UL << 27)) ? 4 : \ - ((u) & (1UL << 26)) ? 5 : \ - ((u) & (1UL << 25)) ? 6 : \ - ((u) & (1UL << 24)) ? 7 : \ - ((u) & (1UL << 23)) ? 8 : \ - ((u) & (1UL << 22)) ? 9 : \ - ((u) & (1UL << 21)) ? 10 : \ - ((u) & (1UL << 20)) ? 11 : \ - ((u) & (1UL << 19)) ? 12 : \ - ((u) & (1UL << 18)) ? 13 : \ - ((u) & (1UL << 17)) ? 14 : \ - ((u) & (1UL << 16)) ? 15 : \ - ((u) & (1UL << 15)) ? 16 : \ - ((u) & (1UL << 14)) ? 17 : \ - ((u) & (1UL << 13)) ? 18 : \ - ((u) & (1UL << 12)) ? 19 : \ - ((u) & (1UL << 11)) ? 20 : \ - ((u) & (1UL << 10)) ? 21 : \ - ((u) & (1UL << 9)) ? 22 : \ - ((u) & (1UL << 8)) ? 23 : \ - ((u) & (1UL << 7)) ? 24 : \ - ((u) & (1UL << 6)) ? 25 : \ - ((u) & (1UL << 5)) ? 26 : \ - ((u) & (1UL << 4)) ? 27 : \ - ((u) & (1UL << 3)) ? 28 : \ - ((u) & (1UL << 2)) ? 29 : \ - ((u) & (1UL << 1)) ? 30 : \ - 31) -#endif -#endif - -/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. - * - * \param u Value of which to count the trailing zero bits. - * - * \return The count of trailing zero bits in \a u. - */ -#ifndef ctz -#if (defined __GNUC__) || (defined __CC_ARM) -# define ctz(u) ((u) ? __builtin_ctz(u) : 32) -#else -# define ctz(u) ((u) & (1UL << 0) ? 0 : \ - (u) & (1UL << 1) ? 1 : \ - (u) & (1UL << 2) ? 2 : \ - (u) & (1UL << 3) ? 3 : \ - (u) & (1UL << 4) ? 4 : \ - (u) & (1UL << 5) ? 5 : \ - (u) & (1UL << 6) ? 6 : \ - (u) & (1UL << 7) ? 7 : \ - (u) & (1UL << 8) ? 8 : \ - (u) & (1UL << 9) ? 9 : \ - (u) & (1UL << 10) ? 10 : \ - (u) & (1UL << 11) ? 11 : \ - (u) & (1UL << 12) ? 12 : \ - (u) & (1UL << 13) ? 13 : \ - (u) & (1UL << 14) ? 14 : \ - (u) & (1UL << 15) ? 15 : \ - (u) & (1UL << 16) ? 16 : \ - (u) & (1UL << 17) ? 17 : \ - (u) & (1UL << 18) ? 18 : \ - (u) & (1UL << 19) ? 19 : \ - (u) & (1UL << 20) ? 20 : \ - (u) & (1UL << 21) ? 21 : \ - (u) & (1UL << 22) ? 22 : \ - (u) & (1UL << 23) ? 23 : \ - (u) & (1UL << 24) ? 24 : \ - (u) & (1UL << 25) ? 25 : \ - (u) & (1UL << 26) ? 26 : \ - (u) & (1UL << 27) ? 27 : \ - (u) & (1UL << 28) ? 28 : \ - (u) & (1UL << 29) ? 29 : \ - (u) & (1UL << 30) ? 30 : \ - (u) & (1UL << 31) ? 31 : \ - 32) -#endif -#endif - -//! @} - - -/*! \name Bit Reversing - */ -//! @{ - -/*! \brief Reverses the bits of \a u8. - * - * \param u8 U8 of which to reverse the bits. - * - * \return Value resulting from \a u8 with reversed bits. - */ -#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) - -/*! \brief Reverses the bits of \a u16. - * - * \param u16 U16 of which to reverse the bits. - * - * \return Value resulting from \a u16 with reversed bits. - */ -#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) - -/*! \brief Reverses the bits of \a u32. - * - * \param u32 U32 of which to reverse the bits. - * - * \return Value resulting from \a u32 with reversed bits. - */ -#define bit_reverse32(u32) __RBIT(u32) - -/*! \brief Reverses the bits of \a u64. - * - * \param u64 U64 of which to reverse the bits. - * - * \return Value resulting from \a u64 with reversed bits. - */ -#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ - ((U64)bit_reverse32((U64)(u64)) << 32))) - -//! @} - - -/*! \name Alignment - */ -//! @{ - -/*! \brief Tests alignment of the number \a val with the \a n boundary. - * - * \param val Input value. - * \param n Boundary. - * - * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. - */ -#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) - -/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. - * - * \param val Input value. - * \param n Boundary. - * - * \return Alignment of the number \a val with respect to the \a n boundary. - */ -#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) - -/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. - * - * \param lval Input/output lvalue. - * \param n Boundary. - * \param alg Alignment. - * - * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. - */ -#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) - -/*! \brief Aligns the number \a val with the upper \a n boundary. - * - * \param val Input value. - * \param n Boundary. - * - * \return Value resulting from the number \a val aligned with the upper \a n boundary. - */ -#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) - -/*! \brief Aligns the number \a val with the lower \a n boundary. - * - * \param val Input value. - * \param n Boundary. - * - * \return Value resulting from the number \a val aligned with the lower \a n boundary. - */ -#define Align_down(val, n ) ( (val) & ~((n) - 1)) - -//! @} - -/*! \brief Calls the routine at address \a addr. - * - * It generates a long call opcode. - * - * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if - * it is invoked from the CPU supervisor mode. - * - * \param addr Address of the routine to call. - * - * \note It may be used as a long jump opcode in some special cases. - */ -#define Long_call(addr) ((*(void (*)(void))(addr))()) - - -/*! \name MCU Endianism Handling - * ARM is MCU little endianism. - */ -//! @{ -#define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16. -#define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16. - -#define MSH(u32) (((U16 *)&(u32))[1]) //!< Most significant half-word of \a u32. -#define LSH(u32) (((U16 *)&(u32))[0]) //!< Least significant half-word of \a u32. -#define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. -#define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. -#define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. -#define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. -#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. -#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. -#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. -#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. - -#define MSW(u64) (((U32 *)&(u64))[1]) //!< Most significant word of \a u64. -#define LSW(u64) (((U32 *)&(u64))[0]) //!< Least significant word of \a u64. -#define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64. -#define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64. -#define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64. -#define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64. -#define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64. -#define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64. -#define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64. -#define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64. -#define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64. -#define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64. -#define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64. -#define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64. -#define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64. -#define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64. -#define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64. -#define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64. -#define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64. -#define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64. -#define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64. -#define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64. -#define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64. -#define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64. -#define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64. -#define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64. - -#define BE16(x) swap16(x) -#define LE16(x) (x) - -#define le16_to_cpu(x) (x) -#define cpu_to_le16(x) (x) -#define LE16_TO_CPU(x) (x) -#define CPU_TO_LE16(x) (x) - -#define be16_to_cpu(x) swap16(x) -#define cpu_to_be16(x) swap16(x) -#define BE16_TO_CPU(x) swap16(x) -#define CPU_TO_BE16(x) swap16(x) - -#define le32_to_cpu(x) (x) -#define cpu_to_le32(x) (x) -#define LE32_TO_CPU(x) (x) -#define CPU_TO_LE32(x) (x) - -#define be32_to_cpu(x) swap32(x) -#define cpu_to_be32(x) swap32(x) -#define BE32_TO_CPU(x) swap32(x) -#define CPU_TO_BE32(x) swap32(x) -//! @} - - -/*! \name Endianism Conversion - * - * The same considerations as for clz and ctz apply here but GCC's - * __builtin_bswap_32 and __builtin_bswap_64 do not behave like macros when - * applied to constant expressions, so two sets of macros are defined here: - * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known - * at compile time); - * - swap16, swap32 and swap64 to apply to non-constant expressions (values - * unknown at compile time). - */ -//! @{ - -/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). - * - * \param u16 U16 of which to toggle the endianism. - * - * \return Value resulting from \a u16 with toggled endianism. - * - * \note More optimized if only used with values known at compile time. - */ -#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ - ((U16)(u16) << 8))) - -/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). - * - * \param u32 U32 of which to toggle the endianism. - * - * \return Value resulting from \a u32 with toggled endianism. - * - * \note More optimized if only used with values known at compile time. - */ -#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ - ((U32)Swap16((U32)(u32)) << 16))) - -/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). - * - * \param u64 U64 of which to toggle the endianism. - * - * \return Value resulting from \a u64 with toggled endianism. - * - * \note More optimized if only used with values known at compile time. - */ -#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ - ((U64)Swap32((U64)(u64)) << 32))) - -/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). - * - * \param u16 U16 of which to toggle the endianism. - * - * \return Value resulting from \a u16 with toggled endianism. - * - * \note More optimized if only used with values unknown at compile time. - */ -#define swap16(u16) Swap16(u16) - -/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). - * - * \param u32 U32 of which to toggle the endianism. - * - * \return Value resulting from \a u32 with toggled endianism. - * - * \note More optimized if only used with values unknown at compile time. - */ -#if (defined __GNUC__) -# define swap32(u32) ((U32)__builtin_bswap32((U32)(u32))) -#else -# define swap32(u32) Swap32(u32) -#endif - -/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). - * - * \param u64 U64 of which to toggle the endianism. - * - * \return Value resulting from \a u64 with toggled endianism. - * - * \note More optimized if only used with values unknown at compile time. - */ -#if (defined __GNUC__) -# define swap64(u64) ((U64)__builtin_bswap64((U64)(u64))) -#else -# define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ - ((U64)swap32((U64)(u64)) << 32))) -#endif - -//! @} - - -/*! \name Target Abstraction - */ -//! @{ - -#define _GLOBEXT_ extern //!< extern storage-class specifier. -#define _CONST_TYPE_ const //!< const type qualifier. -#define _MEM_TYPE_SLOW_ //!< Slow memory type. -#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. -#define _MEM_TYPE_FAST_ //!< Fast memory type. - -typedef U8 Byte; //!< 8-bit unsigned integer. - -#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. -#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. -#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. -#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. - -#define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32. -#define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32. -#define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32. -#define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32. -#define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32. -#define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32. -#define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32. -#define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32. - -//! @} - -/** - * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using - * integer arithmetic. - * - * \param a An integer - * \param b Another integer - * - * \return (\a a / \a b) rounded up to the nearest integer. - */ -#define div_ceil(a, b) (((a) + (b) - 1) / (b)) - -#endif // #ifndef __ASSEMBLY__ - - -#ifdef __ICCARM__ -#define SHORTENUM __packed -#elif defined(__GNUC__) -#define SHORTENUM __attribute__((packed)) -#endif - -/* No operation */ -#ifdef __ICCARM__ -#define nop() __no_operation() -#elif defined(__GNUC__) -#define nop() (__NOP()) -#endif - -#define FLASH_DECLARE(x) const x -#define FLASH_EXTERN(x) extern const x -#define PGM_READ_BYTE(x) *(x) -#define PGM_READ_WORD(x) *(x) -#define PGM_READ_DWORD(x) *(x) -#define MEMCPY_ENDIAN memcpy -#define PGM_READ_BLOCK(dst, src, len) memcpy((dst), (src), (len)) - -/*Defines the Flash Storage for the request and response of MAC*/ -#define CMD_ID_OCTET (0) - -/* Converting of values from CPU endian to little endian. */ -#define CPU_ENDIAN_TO_LE16(x) (x) -#define CPU_ENDIAN_TO_LE32(x) (x) -#define CPU_ENDIAN_TO_LE64(x) (x) - -/* Converting of values from little endian to CPU endian. */ -#define LE16_TO_CPU_ENDIAN(x) (x) -#define LE32_TO_CPU_ENDIAN(x) (x) -#define LE64_TO_CPU_ENDIAN(x) (x) - -/* Converting of constants from little endian to CPU endian. */ -#define CLE16_TO_CPU_ENDIAN(x) (x) -#define CLE32_TO_CPU_ENDIAN(x) (x) -#define CLE64_TO_CPU_ENDIAN(x) (x) - -/* Converting of constants from CPU endian to little endian. */ -#define CCPU_ENDIAN_TO_LE16(x) (x) -#define CCPU_ENDIAN_TO_LE32(x) (x) -#define CCPU_ENDIAN_TO_LE64(x) (x) - -#define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src)) -#define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src)) - -/** - * @brief Converts a 64-Bit value into a 8 Byte array - * - * @param[in] value 64-Bit value - * @param[out] data Pointer to the 8 Byte array to be updated with 64-Bit value - * @ingroup apiPalApi - */ -static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data) -{ - uint8_t val_index = 0; - - while (val_index < 8) - { - data[val_index++] = value & 0xFF; - value >>= 8; - } -} - -/** - * @brief Converts a 16-Bit value into a 2 Byte array - * - * @param[in] value 16-Bit value - * @param[out] data Pointer to the 2 Byte array to be updated with 16-Bit value - * @ingroup apiPalApi - */ -static inline void convert_16_bit_to_byte_array(uint16_t value, uint8_t *data) -{ - data[0] = value & 0xFF; - data[1] = (value >> 8) & 0xFF; -} - -/* Converts a 16-Bit value into a 2 Byte array */ -static inline void convert_spec_16_bit_to_byte_array(uint16_t value, uint8_t *data) -{ - data[0] = value & 0xFF; - data[1] = (value >> 8) & 0xFF; -} - -/* Converts a 16-Bit value into a 2 Byte array */ -static inline void convert_16_bit_to_byte_address(uint16_t value, uint8_t *data) -{ - data[0] = value & 0xFF; - data[1] = (value >> 8) & 0xFF; -} - -/* - * @brief Converts a 2 Byte array into a 16-Bit value - * - * @param data Specifies the pointer to the 2 Byte array - * - * @return 16-Bit value - * @ingroup apiPalApi - */ -static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) -{ - return (data[0] | ((uint16_t)data[1] << 8)); -} - -/* Converts a 8 Byte array into a 32-Bit value */ -static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data) -{ - union - { - uint32_t u32; - uint8_t u8[8]; - }long_addr; - uint8_t index; - for (index = 0; index < 4; index++) { - long_addr.u8[index] = *data++; - } - return long_addr.u32; -} - -/** - * @brief Converts a 8 Byte array into a 64-Bit value - * - * @param data Specifies the pointer to the 8 Byte array - * - * @return 64-Bit value - * @ingroup apiPalApi - */ -static inline uint64_t convert_byte_array_to_64_bit(uint8_t *data) -{ - union - { - uint64_t u64; - uint8_t u8[8]; - } long_addr; - - uint8_t val_index; - - for (val_index = 0; val_index < 8; val_index++) - { - long_addr.u8[val_index] = *data++; - } - - return long_addr.u64; -} -/** - * \} - */ - -#endif /* UTILS_COMPILER_H */ diff --git a/src/HAL/DUE/usb/conf_access.h b/src/HAL/DUE/usb/conf_access.h deleted file mode 100644 index f401685..0000000 --- a/src/HAL/DUE/usb/conf_access.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * \file - * - * \brief Memory access control configuration file. - * - * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _CONF_ACCESS_H_ -#define _CONF_ACCESS_H_ - -#include "compiler.h" -#include "../../../inc/MarlinConfigPre.h" - -/*! \name Activation of Logical Unit Numbers - */ -//! @{ - -#define LUN_0 ENABLE //!< SD/MMC Card over MCI Slot 0. -#define LUN_1 DISABLE -#define LUN_2 DISABLE -#define LUN_3 DISABLE -#define LUN_4 DISABLE -#define LUN_5 DISABLE -#define LUN_6 DISABLE -#define LUN_7 DISABLE -#define LUN_USB DISABLE -//! @} - -/*! \name LUN 0 Definitions - */ -//! @{ -#define SD_MMC_SPI_MEM LUN_0 -#define LUN_ID_SD_MMC_SPI_MEM LUN_ID_0 -#define LUN_0_INCLUDE "sd_mmc_spi_mem.h" -#define Lun_0_test_unit_ready sd_mmc_spi_test_unit_ready -#define Lun_0_read_capacity sd_mmc_spi_read_capacity -#define Lun_0_unload sd_mmc_spi_unload -#define Lun_0_wr_protect sd_mmc_spi_wr_protect -#define Lun_0_removal sd_mmc_spi_removal -#define Lun_0_usb_read_10 sd_mmc_spi_usb_read_10 -#define Lun_0_usb_write_10 sd_mmc_spi_usb_write_10 -#define LUN_0_NAME "\"SD/MMC Card\"" -//! @} - - -/*! \name Actions Associated with Memory Accesses - * - * Write here the action to associate with each memory access. - * - * \warning Be careful not to waste time in order not to disturb the functions. - */ -//! @{ -#define memory_start_read_action(nb_sectors) -#define memory_stop_read_action() -#define memory_start_write_action(nb_sectors) -#define memory_stop_write_action() -//! @} - -/*! \name Activation of Interface Features - */ -//! @{ -#define ACCESS_USB true //!< MEM <-> USB interface. -#define ACCESS_MEM_TO_RAM false //!< MEM <-> RAM interface. -#define ACCESS_STREAM false //!< Streaming MEM <-> MEM interface. -#define ACCESS_STREAM_RECORD false //!< Streaming MEM <-> MEM interface in record mode. -#define ACCESS_MEM_TO_MEM false //!< MEM <-> MEM interface. -#define ACCESS_CODEC false //!< Codec interface. -//! @} - -/*! \name Specific Options for Access Control - */ -//! @{ -#define GLOBAL_WR_PROTECT false //!< Management of a global write protection. -//! @} - - -#endif // _CONF_ACCESS_H_ diff --git a/src/HAL/DUE/usb/conf_clock.h b/src/HAL/DUE/usb/conf_clock.h deleted file mode 100644 index 97e70e9..0000000 --- a/src/HAL/DUE/usb/conf_clock.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * \file - * - * \brief SAM3X clock configuration. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef CONF_CLOCK_H_INCLUDED -#define CONF_CLOCK_H_INCLUDED - -// ===== System Clock (MCK) Source Options -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS -#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK -//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_UPLLCK - -// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES)) -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 -#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64 -//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3 - -// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div) -// Use mul and div effective values here. -#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL -#define CONFIG_PLL0_MUL 14 -#define CONFIG_PLL0_DIV 1 - -// ===== UPLL (UTMI) Hardware fixed at 480MHz. - -// ===== USB Clock Source Options (Fusb = FpllX / USB_div) -// Use div effective value here. -//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 -#define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL -#define CONFIG_USBCLK_DIV 1 - -// ===== Target frequency (System clock) -// - XTAL frequency: 12MHz -// - System clock source: PLLA -// - System clock prescaler: 2 (divided by 2) -// - PLLA source: XTAL -// - PLLA output: XTAL * 14 / 1 -// - System clock is: 12 * 14 / 1 /2 = 84MHz -// ===== Target frequency (USB Clock) -// - USB clock source: UPLL -// - USB clock divider: 1 (not divided) -// - UPLL frequency: 480MHz -// - USB clock: 480 / 1 = 480MHz - - -#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/conf_usb.h b/src/HAL/DUE/usb/conf_usb.h deleted file mode 100644 index 4de9e34..0000000 --- a/src/HAL/DUE/usb/conf_usb.h +++ /dev/null @@ -1,296 +0,0 @@ -/** - * \file - * - * \brief USB configuration file - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _CONF_USB_H_ -#define _CONF_USB_H_ - -#undef UNUSED /* To avoid a macro clash as macros.h already defines it */ -#include "../../../inc/MarlinConfigPre.h" -#include "compiler.h" - -/** - * USB Device Configuration - * @{ - */ - -//! Device definition (mandatory) -#define USB_DEVICE_MAJOR_VERSION 1 -#define USB_DEVICE_MINOR_VERSION 0 -#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) -#define USB_DEVICE_ATTR \ - (USB_CONFIG_ATTR_SELF_POWERED) -// (USB_CONFIG_ATTR_BUS_POWERED) -// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) -// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) - -/** - * Device speeds support - * Low speed not supported by CDC and MSC - * @{ - */ - -//! To define a Low speed device -//#define USB_DEVICE_LOW_SPEED - -//! To define a Full speed device -//#define USB_DEVICE_FULL_SPEED - -//! To authorize the High speed -#ifndef USB_DEVICE_FULL_SPEED - #if (UC3A3||UC3A4) - #define USB_DEVICE_HS_SUPPORT - #elif (SAM3XA||SAM3U) - #define USB_DEVICE_HS_SUPPORT - #endif -#endif -//@} - - -/** - * USB Device Callbacks definitions (Optional) - * @{ - */ -#define UDC_VBUS_EVENT(b_vbus_high) -#define UDC_SOF_EVENT() -#define UDC_SUSPEND_EVENT() -#define UDC_RESUME_EVENT() -#define UDC_GET_EXTRA_STRING() usb_task_extra_string() -#define USB_DEVICE_SPECIFIC_REQUEST() usb_task_other_requests() -//@} - -#if ENABLED(SDSUPPORT) - /** - * USB Device low level configuration - * When only one interface is used, these configurations are defined by the class module. - * For composite device, these configuration must be defined here - * @{ - */ - //! Control endpoint size - #define USB_DEVICE_EP_CTRL_SIZE 64 - - //! Two interfaces for this device (CDC COM + CDC DATA + MSC) - #define USB_DEVICE_NB_INTERFACE 3 - - //! 5 endpoints used by CDC and MSC interfaces - #if SAM3U - // (3 | USB_EP_DIR_IN) // CDC Notify endpoint - // (6 | USB_EP_DIR_IN) // CDC TX - // (5 | USB_EP_DIR_OUT) // CDC RX - // (1 | USB_EP_DIR_IN) // MSC IN - // (2 | USB_EP_DIR_OUT) // MSC OUT - # define USB_DEVICE_MAX_EP 6 - # if defined(USB_DEVICE_HS_SUPPORT) - // In HS mode, size of bulk endpoints are 512 - // If CDC and MSC endpoints all uses 2 banks, DPRAM is not enough: 4 bulk - // endpoints requires 4K bytes. So reduce the number of banks of CDC bulk - // endpoints to use less DPRAM. Keep MSC setting to keep MSC performance. - # define UDD_BULK_NB_BANK(ep) ((ep == 5 || ep== 6) ? 1 : 2) - #endif - #else - // (3 | USB_EP_DIR_IN) // CDC Notify endpoint - // (4 | USB_EP_DIR_IN) // CDC TX - // (5 | USB_EP_DIR_OUT) // CDC RX - // (1 | USB_EP_DIR_IN) // MSC IN - // (2 | USB_EP_DIR_OUT) // MSC OUT - # define USB_DEVICE_MAX_EP 5 - # if SAM3XA && defined(USB_DEVICE_HS_SUPPORT) - // In HS mode, size of bulk endpoints are 512 - // If CDC and MSC endpoints all uses 2 banks, DPRAM is not enough: 4 bulk - // endpoints requires 4K bytes. So reduce the number of banks of CDC bulk - // endpoints to use less DPRAM. Keep MSC setting to keep MSC performance. - # define UDD_BULK_NB_BANK(ep) ((ep == 4 || ep== 5) ? 1 : 2) - # endif - #endif -#endif - -//@} - -//@} - - -/** - * USB Interface Configuration - * @{ - */ -/** - * Configuration of CDC interface - * @{ - */ - -//! Define one USB communication ports -#define UDI_CDC_PORT_NB 1 - -//! Interface callback definition -#define UDI_CDC_ENABLE_EXT(port) usb_task_cdc_enable(port) -#define UDI_CDC_DISABLE_EXT(port) usb_task_cdc_disable(port) -#define UDI_CDC_RX_NOTIFY(port) usb_task_cdc_rx_notify(port) -#define UDI_CDC_TX_EMPTY_NOTIFY(port) -#define UDI_CDC_SET_CODING_EXT(port,cfg) usb_task_cdc_config(port,cfg) -#define UDI_CDC_SET_DTR_EXT(port,set) usb_task_cdc_set_dtr(port,set) -#define UDI_CDC_SET_RTS_EXT(port,set) - -//! Define it when the transfer CDC Device to Host is a low rate (<512000 bauds) -//! to reduce CDC buffers size -//#define UDI_CDC_LOW_RATE - -//! Default configuration of communication port -#define UDI_CDC_DEFAULT_RATE 115200 -#define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 -#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE -#define UDI_CDC_DEFAULT_DATABITS 8 - -//! Enable id string of interface to add an extra USB string -#define UDI_CDC_IAD_STRING_ID 4 - -#if ENABLED(SDSUPPORT) - /** - * USB CDC low level configuration - * In standalone these configurations are defined by the CDC module. - * For composite device, these configuration must be defined here - * @{ - */ - //! Endpoint numbers definition - #if SAM3U - # define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint - # define UDI_CDC_DATA_EP_IN_0 (6 | USB_EP_DIR_IN) // TX - # define UDI_CDC_DATA_EP_OUT_0 (5 | USB_EP_DIR_OUT)// RX - #else - # define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint - # define UDI_CDC_DATA_EP_IN_0 (4 | USB_EP_DIR_IN) // TX - # define UDI_CDC_DATA_EP_OUT_0 (5 | USB_EP_DIR_OUT)// RX - #endif - - //! Interface numbers - #define UDI_CDC_COMM_IFACE_NUMBER_0 0 - #define UDI_CDC_DATA_IFACE_NUMBER_0 1 - - //@} - //@} - - - /** - * Configuration of MSC interface - * @{ - */ - //! Vendor name and Product version of MSC interface - #define UDI_MSC_GLOBAL_VENDOR_ID \ - 'M', 'A', 'R', 'L', 'I', 'N', '3', 'D' - #define UDI_MSC_GLOBAL_PRODUCT_VERSION \ - '1', '.', '0', '0' - - //! Interface callback definition - #define UDI_MSC_ENABLE_EXT() usb_task_msc_enable() - #define UDI_MSC_DISABLE_EXT() usb_task_msc_disable() - - //! Enable id string of interface to add an extra USB string - #define UDI_MSC_STRING_ID 5 - - /** - * USB MSC low level configuration - * In standalone these configurations are defined by the MSC module. - * For composite device, these configuration must be defined here - * @{ - */ - //! Endpoint numbers definition - #define UDI_MSC_EP_IN (1 | USB_EP_DIR_IN) - #define UDI_MSC_EP_OUT (2 | USB_EP_DIR_OUT) - - //! Interface number - #define UDI_MSC_IFACE_NUMBER 2 - //@} - //@} - - //@} - - - /** - * Description of Composite Device - * @{ - */ - //! USB Interfaces descriptor structure - #define UDI_COMPOSITE_DESC_T \ - usb_iad_desc_t udi_cdc_iad; \ - udi_cdc_comm_desc_t udi_cdc_comm; \ - udi_cdc_data_desc_t udi_cdc_data; \ - udi_msc_desc_t udi_msc - - //! USB Interfaces descriptor value for Full Speed - #define UDI_COMPOSITE_DESC_FS \ - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - .udi_msc = UDI_MSC_DESC_FS - - //! USB Interfaces descriptor value for High Speed - #define UDI_COMPOSITE_DESC_HS \ - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - .udi_msc = UDI_MSC_DESC_HS - - //! USB Interface APIs - #define UDI_COMPOSITE_API \ - &udi_api_cdc_comm, \ - &udi_api_cdc_data, \ - &udi_api_msc - //@} - - /** - * USB Device Driver Configuration - * @{ - */ - //@} - - //! The includes of classes and other headers must be done at the end of this file to avoid compile error - #include "udi_cdc.h" - #include "udi_msc.h" -#else - #include "udi_cdc_conf.h" -#endif - -#include "usb_task.h" - -#endif // _CONF_USB_H_ diff --git a/src/HAL/DUE/usb/ctrl_access.c b/src/HAL/DUE/usb/ctrl_access.c deleted file mode 100644 index 99f97f6..0000000 --- a/src/HAL/DUE/usb/ctrl_access.c +++ /dev/null @@ -1,647 +0,0 @@ -/***************************************************************************** - * - * \file - * - * \brief Abstraction layer for memory interfaces. - * - * This module contains the interfaces: - * - MEM <-> USB; - * - MEM <-> RAM; - * - MEM <-> MEM. - * - * This module may be configured and expanded to support the following features: - * - write-protected globals; - * - password-protected data; - * - specific features; - * - etc. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - ******************************************************************************/ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -//_____ I N C L U D E S ____________________________________________________ - -#include "compiler.h" -#include "preprocessor.h" -#ifdef FREERTOS_USED -#include "FreeRTOS.h" -#include "semphr.h" -#endif -#include "ctrl_access.h" - - -//_____ D E F I N I T I O N S ______________________________________________ - -#ifdef FREERTOS_USED - -/*! \name LUN Access Protection Macros - */ -//! @{ - -/*! \brief Locks accesses to LUNs. - * - * \return \c true if the access was successfully locked, else \c false. - */ -#define Ctrl_access_lock() ctrl_access_lock() - -/*! \brief Unlocks accesses to LUNs. - */ -#define Ctrl_access_unlock() xSemaphoreGive(ctrl_access_semphr) - -//! @} - -//! Handle to the semaphore protecting accesses to LUNs. -static xSemaphoreHandle ctrl_access_semphr = NULL; - -#else - -/*! \name LUN Access Protection Macros - */ -//! @{ - -/*! \brief Locks accesses to LUNs. - * - * \return \c true if the access was successfully locked, else \c false. - */ -#define Ctrl_access_lock() true - -/*! \brief Unlocks accesses to LUNs. - */ -#define Ctrl_access_unlock() - -//! @} - -#endif // FREERTOS_USED - - -#if MAX_LUN - -/*! \brief Initializes an entry of the LUN descriptor table. - * - * \param lun Logical Unit Number. - * - * \return LUN descriptor table entry initializer. - */ -#if ACCESS_USB == true && ACCESS_MEM_TO_RAM == true -#define Lun_desc_entry(lun) \ - {\ - TPASTE3(Lun_, lun, _test_unit_ready),\ - TPASTE3(Lun_, lun, _read_capacity),\ - TPASTE3(Lun_, lun, _unload),\ - TPASTE3(Lun_, lun, _wr_protect),\ - TPASTE3(Lun_, lun, _removal),\ - TPASTE3(Lun_, lun, _usb_read_10),\ - TPASTE3(Lun_, lun, _usb_write_10),\ - TPASTE3(Lun_, lun, _mem_2_ram),\ - TPASTE3(Lun_, lun, _ram_2_mem),\ - TPASTE3(LUN_, lun, _NAME)\ - } -#elif ACCESS_USB == true -#define Lun_desc_entry(lun) \ - {\ - TPASTE3(Lun_, lun, _test_unit_ready),\ - TPASTE3(Lun_, lun, _read_capacity),\ - TPASTE3(Lun_, lun, _unload),\ - TPASTE3(Lun_, lun, _wr_protect),\ - TPASTE3(Lun_, lun, _removal),\ - TPASTE3(Lun_, lun, _usb_read_10),\ - TPASTE3(Lun_, lun, _usb_write_10),\ - TPASTE3(LUN_, lun, _NAME)\ - } -#elif ACCESS_MEM_TO_RAM == true -#define Lun_desc_entry(lun) \ - {\ - TPASTE3(Lun_, lun, _test_unit_ready),\ - TPASTE3(Lun_, lun, _read_capacity),\ - TPASTE3(Lun_, lun, _unload),\ - TPASTE3(Lun_, lun, _wr_protect),\ - TPASTE3(Lun_, lun, _removal),\ - TPASTE3(Lun_, lun, _mem_2_ram),\ - TPASTE3(Lun_, lun, _ram_2_mem),\ - TPASTE3(LUN_, lun, _NAME)\ - } -#else -#define Lun_desc_entry(lun) \ - {\ - TPASTE3(Lun_, lun, _test_unit_ready),\ - TPASTE3(Lun_, lun, _read_capacity),\ - TPASTE3(Lun_, lun, _unload),\ - TPASTE3(Lun_, lun, _wr_protect),\ - TPASTE3(Lun_, lun, _removal),\ - TPASTE3(LUN_, lun, _NAME)\ - } -#endif - -//! LUN descriptor table. -static const struct -{ - Ctrl_status (*test_unit_ready)(void); - Ctrl_status (*read_capacity)(U32 *); - bool (*unload)(bool); - bool (*wr_protect)(void); - bool (*removal)(void); -#if ACCESS_USB == true - Ctrl_status (*usb_read_10)(U32, U16); - Ctrl_status (*usb_write_10)(U32, U16); -#endif -#if ACCESS_MEM_TO_RAM == true - Ctrl_status (*mem_2_ram)(U32, void *); - Ctrl_status (*ram_2_mem)(U32, const void *); -#endif - const char *name; -} lun_desc[MAX_LUN] = -{ -#if LUN_0 == ENABLE -# ifndef Lun_0_unload -# define Lun_0_unload NULL -# endif - Lun_desc_entry(0), -#endif -#if LUN_1 == ENABLE -# ifndef Lun_1_unload -# define Lun_1_unload NULL -# endif - Lun_desc_entry(1), -#endif -#if LUN_2 == ENABLE -# ifndef Lun_2_unload -# define Lun_2_unload NULL -# endif - Lun_desc_entry(2), -#endif -#if LUN_3 == ENABLE -# ifndef Lun_3_unload -# define Lun_3_unload NULL -# endif - Lun_desc_entry(3), -#endif -#if LUN_4 == ENABLE -# ifndef Lun_4_unload -# define Lun_4_unload NULL -# endif - Lun_desc_entry(4), -#endif -#if LUN_5 == ENABLE -# ifndef Lun_5_unload -# define Lun_5_unload NULL -# endif - Lun_desc_entry(5), -#endif -#if LUN_6 == ENABLE -# ifndef Lun_6_unload -# define Lun_6_unload NULL -# endif - Lun_desc_entry(6), -#endif -#if LUN_7 == ENABLE -# ifndef Lun_7_unload -# define Lun_7_unload NULL -# endif - Lun_desc_entry(7) -#endif -}; - -#endif - - -#if GLOBAL_WR_PROTECT == true -bool g_wr_protect; -#endif - - -/*! \name Control Interface - */ -//! @{ - - -#ifdef FREERTOS_USED - -bool ctrl_access_init(void) -{ - // If the handle to the protecting semaphore is not valid, - if (!ctrl_access_semphr) - { - // try to create the semaphore. - vSemaphoreCreateBinary(ctrl_access_semphr); - - // If the semaphore could not be created, there is no backup solution. - if (!ctrl_access_semphr) return false; - } - - return true; -} - - -/*! \brief Locks accesses to LUNs. - * - * \return \c true if the access was successfully locked, else \c false. - */ -static bool ctrl_access_lock(void) -{ - // If the semaphore could not be created, there is no backup solution. - if (!ctrl_access_semphr) return false; - - // Wait for the semaphore. - while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY)); - - return true; -} - -#endif // FREERTOS_USED - - -U8 get_nb_lun(void) -{ -#if MEM_USB == ENABLE -# ifndef Lun_usb_get_lun -# define Lun_usb_get_lun() host_get_lun() -# endif - U8 nb_lun; - - if (!Ctrl_access_lock()) return MAX_LUN; - - nb_lun = MAX_LUN + Lun_usb_get_lun(); - - Ctrl_access_unlock(); - - return nb_lun; -#else - return MAX_LUN; -#endif -} - - -U8 get_cur_lun(void) -{ - return LUN_ID_0; -} - - -Ctrl_status mem_test_unit_ready(U8 lun) -{ - Ctrl_status status; - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() : -#endif -#if LUN_USB == ENABLE - Lun_usb_test_unit_ready(lun - LUN_ID_USB); -#else - CTRL_FAIL; -#endif - - Ctrl_access_unlock(); - - return status; -} - - -Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector) -{ - Ctrl_status status; - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) : -#endif -#if LUN_USB == ENABLE - Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector); -#else - CTRL_FAIL; -#endif - - Ctrl_access_unlock(); - - return status; -} - - -U8 mem_sector_size(U8 lun) -{ - U8 sector_size; - - if (!Ctrl_access_lock()) return 0; - - sector_size = -#if MAX_LUN - (lun < MAX_LUN) ? 1 : -#endif -#if LUN_USB == ENABLE - Lun_usb_read_sector_size(lun - LUN_ID_USB); -#else - 0; -#endif - - Ctrl_access_unlock(); - - return sector_size; -} - - -bool mem_unload(U8 lun, bool unload) -{ - bool unloaded; -#if !MAX_LUN || !defined(Lun_usb_unload) - UNUSED(lun); -#endif - - if (!Ctrl_access_lock()) return false; - - unloaded = -#if MAX_LUN - (lun < MAX_LUN) ? - (lun_desc[lun].unload ? - lun_desc[lun].unload(unload) : !unload) : -#endif -#if LUN_USB == ENABLE -# if defined(Lun_usb_unload) - Lun_usb_unload(lun - LUN_ID_USB, unload); -# else - !unload; /* Can not unload: load success, unload fail */ -# endif -#else - false; /* No mem, unload/load fail */ -#endif - - Ctrl_access_unlock(); - - return unloaded; -} - -bool mem_wr_protect(U8 lun) -{ - bool wr_protect; - - if (!Ctrl_access_lock()) return true; - - wr_protect = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].wr_protect() : -#endif -#if LUN_USB == ENABLE - Lun_usb_wr_protect(lun - LUN_ID_USB); -#else - true; -#endif - - Ctrl_access_unlock(); - - return wr_protect; -} - - -bool mem_removal(U8 lun) -{ - bool removal; -#if MAX_LUN==0 - UNUSED(lun); -#endif - - if (!Ctrl_access_lock()) return true; - - removal = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].removal() : -#endif -#if LUN_USB == ENABLE - Lun_usb_removal(); -#else - true; -#endif - - Ctrl_access_unlock(); - - return removal; -} - - -const char *mem_name(U8 lun) -{ -#if MAX_LUN==0 - UNUSED(lun); -#endif - return -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].name : -#endif -#if LUN_USB == ENABLE - LUN_USB_NAME; -#else - NULL; -#endif -} - - -//! @} - - -#if ACCESS_USB == true - -/*! \name MEM <-> USB Interface - */ -//! @{ - - -Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector) -{ - Ctrl_status status; - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - memory_start_read_action(nb_sector); - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) : -#endif - CTRL_FAIL; - memory_stop_read_action(); - - Ctrl_access_unlock(); - - return status; -} - - -Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector) -{ - Ctrl_status status; - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - memory_start_write_action(nb_sector); - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) : -#endif - CTRL_FAIL; - memory_stop_write_action(); - - Ctrl_access_unlock(); - - return status; -} - - -//! @} - -#endif // ACCESS_USB == true - - -#if ACCESS_MEM_TO_RAM == true - -/*! \name MEM <-> RAM Interface - */ -//! @{ - - -Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram) -{ - Ctrl_status status; -#if MAX_LUN==0 - UNUSED(lun); -#endif - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - memory_start_read_action(1); - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) : -#endif -#if LUN_USB == ENABLE - Lun_usb_mem_2_ram(addr, ram); -#else - CTRL_FAIL; -#endif - memory_stop_read_action(); - - Ctrl_access_unlock(); - - return status; -} - - -Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram) -{ - Ctrl_status status; -#if MAX_LUN==0 - UNUSED(lun); -#endif - - if (!Ctrl_access_lock()) return CTRL_FAIL; - - memory_start_write_action(1); - status = -#if MAX_LUN - (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) : -#endif -#if LUN_USB == ENABLE - Lun_usb_ram_2_mem(addr, ram); -#else - CTRL_FAIL; -#endif - memory_stop_write_action(); - - Ctrl_access_unlock(); - - return status; -} - - -//! @} - -#endif // ACCESS_MEM_TO_RAM == true - - -#if ACCESS_STREAM == true - -/*! \name Streaming MEM <-> MEM Interface - */ -//! @{ - - - #if ACCESS_MEM_TO_MEM == true - -#include "fat.h" - -Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector) -{ - COMPILER_ALIGNED(4) - static U8 sector_buf[FS_512B]; - Ctrl_status status = CTRL_GOOD; - - while (nb_sector--) - { - if ((status = memory_2_ram(src_lun, src_addr++, sector_buf)) != CTRL_GOOD) break; - if ((status = ram_2_memory(dest_lun, dest_addr++, sector_buf)) != CTRL_GOOD) break; - } - - return status; -} - - #endif // ACCESS_MEM_TO_MEM == true - - -Ctrl_status stream_state(U8 id) -{ - UNUSED(id); - return CTRL_GOOD; -} - - -U16 stream_stop(U8 id) -{ - UNUSED(id); - return 0; -} - - -//! @} - -#endif // ACCESS_STREAM - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/ctrl_access.h b/src/HAL/DUE/usb/ctrl_access.h deleted file mode 100644 index b338390..0000000 --- a/src/HAL/DUE/usb/ctrl_access.h +++ /dev/null @@ -1,402 +0,0 @@ -/***************************************************************************** - * - * \file - * - * \brief Abstraction layer for memory interfaces. - * - * This module contains the interfaces: - * - MEM <-> USB; - * - MEM <-> RAM; - * - MEM <-> MEM. - * - * This module may be configured and expanded to support the following features: - * - write-protected globals; - * - password-protected data; - * - specific features; - * - etc. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - ******************************************************************************/ -/* - * Support and FAQ: visit Atmel Support - */ - - -#ifndef _CTRL_ACCESS_H_ -#define _CTRL_ACCESS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \defgroup group_common_services_storage_ctrl_access Memory Control Access - * - * Common abstraction layer for memory interfaces. It provides interfaces between: - * Memory and USB, Memory and RAM, Memory and Memory. Common API for XMEGA and UC3. - * - * \{ - */ - -#include "compiler.h" -#include "conf_access.h" - -#ifndef SECTOR_SIZE -#define SECTOR_SIZE 512 -#endif - -//! Status returned by CTRL_ACCESS interfaces. -typedef enum -{ - CTRL_GOOD = PASS, //!< Success, memory ready. - CTRL_FAIL = FAIL, //!< An error occurred. - CTRL_NO_PRESENT = FAIL + 1, //!< Memory unplugged. - CTRL_BUSY = FAIL + 2 //!< Memory not initialized or changed. -} Ctrl_status; - - -// FYI: Each Logical Unit Number (LUN) corresponds to a memory. - -// Check LUN defines. -#ifndef LUN_0 - #error LUN_0 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_1 - #error LUN_1 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_2 - #error LUN_2 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_3 - #error LUN_3 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_4 - #error LUN_4 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_5 - #error LUN_5 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_6 - #error LUN_6 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_7 - #error LUN_7 must be defined as ENABLE or DISABLE in conf_access.h -#endif -#ifndef LUN_USB - #error LUN_USB must be defined as ENABLE or DISABLE in conf_access.h -#endif - -/*! \name LUN IDs - */ -//! @{ -#define LUN_ID_0 (0) //!< First static LUN. -#define LUN_ID_1 (LUN_ID_0 + LUN_0) -#define LUN_ID_2 (LUN_ID_1 + LUN_1) -#define LUN_ID_3 (LUN_ID_2 + LUN_2) -#define LUN_ID_4 (LUN_ID_3 + LUN_3) -#define LUN_ID_5 (LUN_ID_4 + LUN_4) -#define LUN_ID_6 (LUN_ID_5 + LUN_5) -#define LUN_ID_7 (LUN_ID_6 + LUN_6) -#define MAX_LUN (LUN_ID_7 + LUN_7) //!< Number of static LUNs. -#define LUN_ID_USB (MAX_LUN) //!< First dynamic LUN (USB host mass storage). -//! @} - - -// Include LUN header files. -#if LUN_0 == ENABLE - #include LUN_0_INCLUDE -#endif -#if LUN_1 == ENABLE - #include LUN_1_INCLUDE -#endif -#if LUN_2 == ENABLE - #include LUN_2_INCLUDE -#endif -#if LUN_3 == ENABLE - #include LUN_3_INCLUDE -#endif -#if LUN_4 == ENABLE - #include LUN_4_INCLUDE -#endif -#if LUN_5 == ENABLE - #include LUN_5_INCLUDE -#endif -#if LUN_6 == ENABLE - #include LUN_6_INCLUDE -#endif -#if LUN_7 == ENABLE - #include LUN_7_INCLUDE -#endif -#if LUN_USB == ENABLE - #include LUN_USB_INCLUDE -#endif - - -// Check the configuration of write protection in conf_access.h. -#ifndef GLOBAL_WR_PROTECT - #error GLOBAL_WR_PROTECT must be defined as true or false in conf_access.h -#endif - - -#if GLOBAL_WR_PROTECT == true - -//! Write protect. -extern bool g_wr_protect; - -#endif - - -/*! \name Control Interface - */ -//! @{ - -#ifdef FREERTOS_USED - -/*! \brief Initializes the LUN access locker. - * - * \return \c true if the locker was successfully initialized, else \c false. - */ -extern bool ctrl_access_init(void); - -#endif // FREERTOS_USED - -/*! \brief Returns the number of LUNs. - * - * \return Number of LUNs in the system. - */ -extern U8 get_nb_lun(void); - -/*! \brief Returns the current LUN. - * - * \return Current LUN. - * - * \todo Implement. - */ -extern U8 get_cur_lun(void); - -/*! \brief Tests the memory state and initializes the memory if required. - * - * The TEST UNIT READY SCSI primary command allows an application client to poll - * a LUN until it is ready without having to allocate memory for returned data. - * - * This command may be used to check the media status of LUNs with removable - * media. - * - * \param lun Logical Unit Number. - * - * \return Status. - */ -extern Ctrl_status mem_test_unit_ready(U8 lun); - -/*! \brief Returns the address of the last valid sector (512 bytes) in the - * memory. - * - * \param lun Logical Unit Number. - * \param u32_nb_sector Pointer to the address of the last valid sector. - * - * \return Status. - */ -extern Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector); - -/*! \brief Returns the size of the physical sector. - * - * \param lun Logical Unit Number. - * - * \return Sector size (unit: 512 bytes). - */ -extern U8 mem_sector_size(U8 lun); - -/*! \brief Unload/load the medium. - * - * \param lun Logical Unit Number. - * \param unload \c true to unload the medium, \c false to load the medium. - * - * \return \c true if unload/load success, else \c false. - */ -extern bool mem_unload(U8 lun, bool unload); - -/*! \brief Returns the write-protection state of the memory. - * - * \param lun Logical Unit Number. - * - * \return \c true if the memory is write-protected, else \c false. - * - * \note Only used by removable memories with hardware-specific write - * protection. - */ -extern bool mem_wr_protect(U8 lun); - -/*! \brief Tells whether the memory is removable. - * - * \param lun Logical Unit Number. - * - * \return \c true if the memory is removable, else \c false. - */ -extern bool mem_removal(U8 lun); - -/*! \brief Returns a pointer to the LUN name. - * - * \param lun Logical Unit Number. - * - * \return Pointer to the LUN name string. - */ -extern const char *mem_name(U8 lun); - -//! @} - - -#if ACCESS_USB == true - -/*! \name MEM <-> USB Interface - */ -//! @{ - -/*! \brief Transfers data from the memory to USB. - * - * \param lun Logical Unit Number. - * \param addr Address of first memory sector to read. - * \param nb_sector Number of sectors to transfer. - * - * \return Status. - */ -extern Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector); - -/*! \brief Transfers data from USB to the memory. - * - * \param lun Logical Unit Number. - * \param addr Address of first memory sector to write. - * \param nb_sector Number of sectors to transfer. - * - * \return Status. - */ -extern Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector); - -//! @} - -#endif // ACCESS_USB == true - - -#if ACCESS_MEM_TO_RAM == true - -/*! \name MEM <-> RAM Interface - */ -//! @{ - -/*! \brief Copies 1 data sector from the memory to RAM. - * - * \param lun Logical Unit Number. - * \param addr Address of first memory sector to read. - * \param ram Pointer to RAM buffer to write. - * - * \return Status. - */ -extern Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram); - -/*! \brief Copies 1 data sector from RAM to the memory. - * - * \param lun Logical Unit Number. - * \param addr Address of first memory sector to write. - * \param ram Pointer to RAM buffer to read. - * - * \return Status. - */ -extern Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram); - -//! @} - -#endif // ACCESS_MEM_TO_RAM == true - - -#if ACCESS_STREAM == true - -/*! \name Streaming MEM <-> MEM Interface - */ -//! @{ - -//! Erroneous streaming data transfer ID. -#define ID_STREAM_ERR 0xFF - - #if ACCESS_MEM_TO_MEM == true - -/*! \brief Copies data from one memory to another. - * - * \param src_lun Source Logical Unit Number. - * \param src_addr Source address of first memory sector to read. - * \param dest_lun Destination Logical Unit Number. - * \param dest_addr Destination address of first memory sector to write. - * \param nb_sector Number of sectors to copy. - * - * \return Status. - */ -extern Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector); - - #endif // ACCESS_MEM_TO_MEM == true - -/*! \brief Returns the state of a streaming data transfer. - * - * \param id Transfer ID. - * - * \return Status. - * - * \todo Implement. - */ -extern Ctrl_status stream_state(U8 id); - -/*! \brief Stops a streaming data transfer. - * - * \param id Transfer ID. - * - * \return Number of remaining sectors. - * - * \todo Implement. - */ -extern U16 stream_stop(U8 id); - -//! @} - -#endif // ACCESS_STREAM == true - -/** - * \} - */ - -#ifdef __cplusplus -} -#endif - -#endif // _CTRL_ACCESS_H_ diff --git a/src/HAL/DUE/usb/genclk.h b/src/HAL/DUE/usb/genclk.h deleted file mode 100644 index cde03bc..0000000 --- a/src/HAL/DUE/usb/genclk.h +++ /dev/null @@ -1,278 +0,0 @@ -/** - * \file - * - * \brief Chip-specific generic clock management. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef CHIP_GENCLK_H_INCLUDED -#define CHIP_GENCLK_H_INCLUDED - -#include -#include - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -/** - * \weakgroup genclk_group - * @{ - */ - -//! \name Programmable Clock Identifiers (PCK) -//@{ -#define GENCLK_PCK_0 0 //!< PCK0 ID -#define GENCLK_PCK_1 1 //!< PCK1 ID -#define GENCLK_PCK_2 2 //!< PCK2 ID -//@} - -//! \name Programmable Clock Sources (PCK) -//@{ - -enum genclk_source { - GENCLK_PCK_SRC_SLCK_RC = 0, //!< Internal 32kHz RC oscillator as PCK source clock - GENCLK_PCK_SRC_SLCK_XTAL = 1, //!< External 32kHz crystal oscillator as PCK source clock - GENCLK_PCK_SRC_SLCK_BYPASS = 2, //!< External 32kHz bypass oscillator as PCK source clock - GENCLK_PCK_SRC_MAINCK_4M_RC = 3, //!< Internal 4MHz RC oscillator as PCK source clock - GENCLK_PCK_SRC_MAINCK_8M_RC = 4, //!< Internal 8MHz RC oscillator as PCK source clock - GENCLK_PCK_SRC_MAINCK_12M_RC = 5, //!< Internal 12MHz RC oscillator as PCK source clock - GENCLK_PCK_SRC_MAINCK_XTAL = 6, //!< External crystal oscillator as PCK source clock - GENCLK_PCK_SRC_MAINCK_BYPASS = 7, //!< External bypass oscillator as PCK source clock - GENCLK_PCK_SRC_PLLACK = 8, //!< Use PLLACK as PCK source clock - GENCLK_PCK_SRC_PLLBCK = 9, //!< Use PLLBCK as PCK source clock - GENCLK_PCK_SRC_MCK = 10, //!< Use Master Clk as PCK source clock -}; - -//@} - -//! \name Programmable Clock Prescalers (PCK) -//@{ - -enum genclk_divider { - GENCLK_PCK_PRES_1 = PMC_PCK_PRES_CLK_1, //!< Set PCK clock prescaler to 1 - GENCLK_PCK_PRES_2 = PMC_PCK_PRES_CLK_2, //!< Set PCK clock prescaler to 2 - GENCLK_PCK_PRES_4 = PMC_PCK_PRES_CLK_4, //!< Set PCK clock prescaler to 4 - GENCLK_PCK_PRES_8 = PMC_PCK_PRES_CLK_8, //!< Set PCK clock prescaler to 8 - GENCLK_PCK_PRES_16 = PMC_PCK_PRES_CLK_16, //!< Set PCK clock prescaler to 16 - GENCLK_PCK_PRES_32 = PMC_PCK_PRES_CLK_32, //!< Set PCK clock prescaler to 32 - GENCLK_PCK_PRES_64 = PMC_PCK_PRES_CLK_64, //!< Set PCK clock prescaler to 64 -}; - -//@} - -struct genclk_config { - uint32_t ctrl; -}; - -static inline void genclk_config_defaults(struct genclk_config *p_cfg, - uint32_t ul_id) -{ - ul_id = ul_id; - p_cfg->ctrl = 0; -} - -static inline void genclk_config_read(struct genclk_config *p_cfg, - uint32_t ul_id) -{ - p_cfg->ctrl = PMC->PMC_PCK[ul_id]; -} - -static inline void genclk_config_write(const struct genclk_config *p_cfg, - uint32_t ul_id) -{ - PMC->PMC_PCK[ul_id] = p_cfg->ctrl; -} - -//! \name Programmable Clock Source and Prescaler configuration -//@{ - -static inline void genclk_config_set_source(struct genclk_config *p_cfg, - enum genclk_source e_src) -{ - p_cfg->ctrl &= (~PMC_PCK_CSS_Msk); - - switch (e_src) { - case GENCLK_PCK_SRC_SLCK_RC: - case GENCLK_PCK_SRC_SLCK_XTAL: - case GENCLK_PCK_SRC_SLCK_BYPASS: - p_cfg->ctrl |= (PMC_PCK_CSS_SLOW_CLK); - break; - - case GENCLK_PCK_SRC_MAINCK_4M_RC: - case GENCLK_PCK_SRC_MAINCK_8M_RC: - case GENCLK_PCK_SRC_MAINCK_12M_RC: - case GENCLK_PCK_SRC_MAINCK_XTAL: - case GENCLK_PCK_SRC_MAINCK_BYPASS: - p_cfg->ctrl |= (PMC_PCK_CSS_MAIN_CLK); - break; - - case GENCLK_PCK_SRC_PLLACK: - p_cfg->ctrl |= (PMC_PCK_CSS_PLLA_CLK); - break; - - case GENCLK_PCK_SRC_PLLBCK: - p_cfg->ctrl |= (PMC_PCK_CSS_UPLL_CLK); - break; - - case GENCLK_PCK_SRC_MCK: - p_cfg->ctrl |= (PMC_PCK_CSS_MCK); - break; - } -} - -static inline void genclk_config_set_divider(struct genclk_config *p_cfg, - uint32_t e_divider) -{ - p_cfg->ctrl &= ~PMC_PCK_PRES_Msk; - p_cfg->ctrl |= e_divider; -} - -//@} - -static inline void genclk_enable(const struct genclk_config *p_cfg, - uint32_t ul_id) -{ - PMC->PMC_PCK[ul_id] = p_cfg->ctrl; - pmc_enable_pck(ul_id); -} - -static inline void genclk_disable(uint32_t ul_id) -{ - pmc_disable_pck(ul_id); -} - -static inline void genclk_enable_source(enum genclk_source e_src) -{ - switch (e_src) { - case GENCLK_PCK_SRC_SLCK_RC: - if (!osc_is_ready(OSC_SLCK_32K_RC)) { - osc_enable(OSC_SLCK_32K_RC); - osc_wait_ready(OSC_SLCK_32K_RC); - } - break; - - case GENCLK_PCK_SRC_SLCK_XTAL: - if (!osc_is_ready(OSC_SLCK_32K_XTAL)) { - osc_enable(OSC_SLCK_32K_XTAL); - osc_wait_ready(OSC_SLCK_32K_XTAL); - } - break; - - case GENCLK_PCK_SRC_SLCK_BYPASS: - if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) { - osc_enable(OSC_SLCK_32K_BYPASS); - osc_wait_ready(OSC_SLCK_32K_BYPASS); - } - break; - - case GENCLK_PCK_SRC_MAINCK_4M_RC: - if (!osc_is_ready(OSC_MAINCK_4M_RC)) { - osc_enable(OSC_MAINCK_4M_RC); - osc_wait_ready(OSC_MAINCK_4M_RC); - } - break; - - case GENCLK_PCK_SRC_MAINCK_8M_RC: - if (!osc_is_ready(OSC_MAINCK_8M_RC)) { - osc_enable(OSC_MAINCK_8M_RC); - osc_wait_ready(OSC_MAINCK_8M_RC); - } - break; - - case GENCLK_PCK_SRC_MAINCK_12M_RC: - if (!osc_is_ready(OSC_MAINCK_12M_RC)) { - osc_enable(OSC_MAINCK_12M_RC); - osc_wait_ready(OSC_MAINCK_12M_RC); - } - break; - - case GENCLK_PCK_SRC_MAINCK_XTAL: - if (!osc_is_ready(OSC_MAINCK_XTAL)) { - osc_enable(OSC_MAINCK_XTAL); - osc_wait_ready(OSC_MAINCK_XTAL); - } - break; - - case GENCLK_PCK_SRC_MAINCK_BYPASS: - if (!osc_is_ready(OSC_MAINCK_BYPASS)) { - osc_enable(OSC_MAINCK_BYPASS); - osc_wait_ready(OSC_MAINCK_BYPASS); - } - break; - -#ifdef CONFIG_PLL0_SOURCE - case GENCLK_PCK_SRC_PLLACK: - pll_enable_config_defaults(0); - break; -#endif - -#ifdef CONFIG_PLL1_SOURCE - case GENCLK_PCK_SRC_PLLBCK: - pll_enable_config_defaults(1); - break; -#endif - - case GENCLK_PCK_SRC_MCK: - break; - - default: - Assert(false); - break; - } -} - -//! @} - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif /* CHIP_GENCLK_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/mrepeat.h b/src/HAL/DUE/usb/mrepeat.h deleted file mode 100644 index 8363d9c..0000000 --- a/src/HAL/DUE/usb/mrepeat.h +++ /dev/null @@ -1,339 +0,0 @@ -/** - * \file - * - * \brief Preprocessor macro repeating utils. - * - * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _MREPEAT_H_ -#define _MREPEAT_H_ - -/** - * \defgroup group_sam_utils_mrepeat Preprocessor - Macro Repeat - * - * \ingroup group_sam_utils - * - * \{ - */ - -#include "preprocessor.h" - - -//! Maximal number of repetitions supported by MREPEAT. -#define MREPEAT_LIMIT 256 - -/*! \brief Macro repeat. - * - * This macro represents a horizontal repetition construct. - * - * \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT. - * \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with - * the current repetition number and the auxiliary data argument. - * \param data Auxiliary data passed to macro. - * - * \return macro(0, data) macro(1, data) ... macro(count - 1, data) - */ -#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data) - -#define MREPEAT0( macro, data) -#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data) -#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data) -#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data) -#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data) -#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data) -#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data) -#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data) -#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data) -#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data) -#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data) -#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data) -#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data) -#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data) -#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data) -#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data) -#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data) -#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data) -#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data) -#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data) -#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data) -#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data) -#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data) -#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data) -#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data) -#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data) -#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data) -#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data) -#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data) -#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data) -#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data) -#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data) -#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data) -#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data) -#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data) -#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data) -#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data) -#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data) -#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data) -#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data) -#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data) -#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data) -#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data) -#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data) -#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data) -#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data) -#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data) -#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data) -#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data) -#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data) -#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data) -#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data) -#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data) -#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data) -#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data) -#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data) -#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data) -#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data) -#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data) -#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data) -#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data) -#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data) -#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data) -#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data) -#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data) -#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data) -#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data) -#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data) -#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data) -#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data) -#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data) -#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data) -#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data) -#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data) -#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data) -#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data) -#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data) -#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data) -#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data) -#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data) -#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data) -#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data) -#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data) -#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data) -#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data) -#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data) -#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data) -#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data) -#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data) -#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data) -#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data) -#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data) -#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data) -#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data) -#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data) -#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data) -#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data) -#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data) -#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data) -#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data) -#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data) -#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data) -#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data) -#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data) -#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data) -#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data) -#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data) -#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data) -#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data) -#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data) -#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data) -#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data) -#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data) -#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data) -#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data) -#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data) -#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data) -#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data) -#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data) -#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data) -#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data) -#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data) -#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data) -#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data) -#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data) -#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data) -#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data) -#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data) -#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data) -#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data) -#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data) -#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data) -#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data) -#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data) -#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data) -#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data) -#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data) -#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data) -#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data) -#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data) -#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data) -#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data) -#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data) -#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data) -#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data) -#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data) -#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data) -#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data) -#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data) -#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data) -#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data) -#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data) -#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data) -#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data) -#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data) -#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data) -#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data) -#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data) -#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data) -#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data) -#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data) -#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data) -#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data) -#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data) -#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data) -#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data) -#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data) -#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data) -#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data) -#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data) -#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data) -#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data) -#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data) -#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data) -#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data) -#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data) -#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data) -#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data) -#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data) -#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data) -#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data) -#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data) -#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data) -#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data) -#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data) -#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data) -#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data) -#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data) -#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data) -#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data) -#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data) -#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data) -#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data) -#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data) -#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data) -#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data) -#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data) -#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data) -#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data) -#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data) -#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data) -#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data) -#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data) -#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data) -#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data) -#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data) -#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data) -#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data) -#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data) -#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data) -#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data) -#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data) -#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data) -#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data) -#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data) -#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data) -#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data) -#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data) -#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data) -#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data) -#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data) -#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data) -#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data) -#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data) -#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data) -#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data) -#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data) -#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data) -#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data) -#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data) -#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data) -#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data) -#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data) -#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data) -#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data) -#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data) -#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data) -#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data) -#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data) -#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data) -#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data) -#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data) -#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data) -#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data) -#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data) -#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data) -#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data) -#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data) -#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data) -#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data) -#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data) -#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data) -#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data) -#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data) -#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data) -#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data) -#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data) - -/** - * \} - */ - -#endif // _MREPEAT_H_ diff --git a/src/HAL/DUE/usb/osc.h b/src/HAL/DUE/usb/osc.h deleted file mode 100644 index 953bcbb..0000000 --- a/src/HAL/DUE/usb/osc.h +++ /dev/null @@ -1,261 +0,0 @@ -/** - * \file - * - * \brief Chip-specific oscillator management functions. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef CHIP_OSC_H_INCLUDED -#define CHIP_OSC_H_INCLUDED - -#include "compiler.h" - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -/* - * Below BOARD_XXX macros are related to the specific board, and - * should be defined by the board code, otherwise default value are used. - */ -#ifndef BOARD_FREQ_SLCK_XTAL -# warning The board slow clock xtal frequency has not been defined. -# define BOARD_FREQ_SLCK_XTAL (32768UL) -#endif - -#ifndef BOARD_FREQ_SLCK_BYPASS -# warning The board slow clock bypass frequency has not been defined. -# define BOARD_FREQ_SLCK_BYPASS (32768UL) -#endif - -#ifndef BOARD_FREQ_MAINCK_XTAL -# warning The board main clock xtal frequency has not been defined. -# define BOARD_FREQ_MAINCK_XTAL (12000000UL) -#endif - -#ifndef BOARD_FREQ_MAINCK_BYPASS -# warning The board main clock bypass frequency has not been defined. -# define BOARD_FREQ_MAINCK_BYPASS (12000000UL) -#endif - -#ifndef BOARD_OSC_STARTUP_US -# warning The board main clock xtal startup time has not been defined. -# define BOARD_OSC_STARTUP_US (15625UL) -#endif - -/** - * \weakgroup osc_group - * @{ - */ - -//! \name Oscillator identifiers -//@{ -#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator. -#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator. -#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator. -#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator. -#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator. -#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator. -#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator. -#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator. -//@} - -//! \name Oscillator clock speed in hertz -//@{ -#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator. -#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator. -#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator. -#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator. -#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator. -#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator. -#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator. -#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator. -//@} - -static inline void osc_enable(uint32_t ul_id) -{ - switch (ul_id) { - case OSC_SLCK_32K_RC: - break; - - case OSC_SLCK_32K_XTAL: - pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); - break; - - case OSC_SLCK_32K_BYPASS: - pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS); - break; - - - case OSC_MAINCK_4M_RC: - pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); - break; - - case OSC_MAINCK_8M_RC: - pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); - break; - - case OSC_MAINCK_12M_RC: - pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); - break; - - - case OSC_MAINCK_XTAL: - pmc_switch_mainck_to_xtal(PMC_OSC_XTAL/*, - pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, - OSC_SLCK_32K_RC_HZ)*/); - break; - - case OSC_MAINCK_BYPASS: - pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS/*, - pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, - OSC_SLCK_32K_RC_HZ)*/); - break; - } -} - -static inline void osc_disable(uint32_t ul_id) -{ - switch (ul_id) { - case OSC_SLCK_32K_RC: - case OSC_SLCK_32K_XTAL: - case OSC_SLCK_32K_BYPASS: - break; - - case OSC_MAINCK_4M_RC: - case OSC_MAINCK_8M_RC: - case OSC_MAINCK_12M_RC: - pmc_osc_disable_fastrc(); - break; - - case OSC_MAINCK_XTAL: - pmc_osc_disable_xtal(PMC_OSC_XTAL); - break; - - case OSC_MAINCK_BYPASS: - pmc_osc_disable_xtal(PMC_OSC_BYPASS); - break; - } -} - -static inline bool osc_is_ready(uint32_t ul_id) -{ - switch (ul_id) { - case OSC_SLCK_32K_RC: - return 1; - - case OSC_SLCK_32K_XTAL: - case OSC_SLCK_32K_BYPASS: - return pmc_osc_is_ready_32kxtal(); - - case OSC_MAINCK_4M_RC: - case OSC_MAINCK_8M_RC: - case OSC_MAINCK_12M_RC: - case OSC_MAINCK_XTAL: - case OSC_MAINCK_BYPASS: - return pmc_osc_is_ready_mainck(); - } - - return 0; -} - -static inline uint32_t osc_get_rate(uint32_t ul_id) -{ - switch (ul_id) { - case OSC_SLCK_32K_RC: - return OSC_SLCK_32K_RC_HZ; - - case OSC_SLCK_32K_XTAL: - return BOARD_FREQ_SLCK_XTAL; - - case OSC_SLCK_32K_BYPASS: - return BOARD_FREQ_SLCK_BYPASS; - - case OSC_MAINCK_4M_RC: - return OSC_MAINCK_4M_RC_HZ; - - case OSC_MAINCK_8M_RC: - return OSC_MAINCK_8M_RC_HZ; - - case OSC_MAINCK_12M_RC: - return OSC_MAINCK_12M_RC_HZ; - - case OSC_MAINCK_XTAL: - return BOARD_FREQ_MAINCK_XTAL; - - case OSC_MAINCK_BYPASS: - return BOARD_FREQ_MAINCK_BYPASS; - } - - return 0; -} - -/** - * \brief Wait until the oscillator identified by \a id is ready - * - * This function will busy-wait for the oscillator identified by \a id - * to become stable and ready to use as a clock source. - * - * \param id A number identifying the oscillator to wait for. - */ -static inline void osc_wait_ready(uint8_t id) -{ - while (!osc_is_ready(id)) { - /* Do nothing */ - } -} - -//! @} - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif /* CHIP_OSC_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/pll.h b/src/HAL/DUE/usb/pll.h deleted file mode 100644 index 8eaf276..0000000 --- a/src/HAL/DUE/usb/pll.h +++ /dev/null @@ -1,288 +0,0 @@ -/** - * \file - * - * \brief Chip-specific PLL definitions. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef CHIP_PLL_H_INCLUDED -#define CHIP_PLL_H_INCLUDED - -#include "osc.h" - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -/** - * \weakgroup pll_group - * @{ - */ - -#define PLL_OUTPUT_MIN_HZ 84000000 -#define PLL_OUTPUT_MAX_HZ 192000000 - -#define PLL_INPUT_MIN_HZ 8000000 -#define PLL_INPUT_MAX_HZ 16000000 - -#define NR_PLLS 2 -#define PLLA_ID 0 -#define UPLL_ID 1 //!< USB UTMI PLL. - -#define PLL_UPLL_HZ 480000000 - -#define PLL_COUNT 0x3FU - -enum pll_source { - PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator. - PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator. - PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator. - PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator. - PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator. - PLL_NR_SOURCES, //!< Number of PLL sources. -}; - -struct pll_config { - uint32_t ctrl; -}; - -#define pll_get_default_rate(pll_id) \ - ((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \ - * CONFIG_PLL##pll_id##_MUL) \ - / CONFIG_PLL##pll_id##_DIV) - -/* Force UTMI PLL parameters (Hardware defined) */ -#ifdef CONFIG_PLL1_SOURCE -# undef CONFIG_PLL1_SOURCE -#endif -#ifdef CONFIG_PLL1_MUL -# undef CONFIG_PLL1_MUL -#endif -#ifdef CONFIG_PLL1_DIV -# undef CONFIG_PLL1_DIV -#endif -#define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL -#define CONFIG_PLL1_MUL 0 -#define CONFIG_PLL1_DIV 0 - -/** - * \note The SAM3X PLL hardware interprets mul as mul+1. For readability the hardware mul+1 - * is hidden in this implementation. Use mul as mul effective value. - */ -static inline void pll_config_init(struct pll_config *p_cfg, - enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul) -{ - uint32_t vco_hz; - - Assert(e_src < PLL_NR_SOURCES); - - if (ul_div == 0 && ul_mul == 0) { /* Must only be true for UTMI PLL */ - p_cfg->ctrl = CKGR_UCKR_UPLLCOUNT(PLL_COUNT); - } else { /* PLLA */ - /* Calculate internal VCO frequency */ - vco_hz = osc_get_rate(e_src) / ul_div; - Assert(vco_hz >= PLL_INPUT_MIN_HZ); - Assert(vco_hz <= PLL_INPUT_MAX_HZ); - - vco_hz *= ul_mul; - Assert(vco_hz >= PLL_OUTPUT_MIN_HZ); - Assert(vco_hz <= PLL_OUTPUT_MAX_HZ); - - /* PMC hardware will automatically make it mul+1 */ - p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) | CKGR_PLLAR_PLLACOUNT(PLL_COUNT); - } -} - -#define pll_config_defaults(cfg, pll_id) \ - pll_config_init(cfg, \ - CONFIG_PLL##pll_id##_SOURCE, \ - CONFIG_PLL##pll_id##_DIV, \ - CONFIG_PLL##pll_id##_MUL) - -static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id) -{ - Assert(ul_pll_id < NR_PLLS); - - if (ul_pll_id == PLLA_ID) { - p_cfg->ctrl = PMC->CKGR_PLLAR; - } else { - p_cfg->ctrl = PMC->CKGR_UCKR; - } -} - -static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id) -{ - Assert(ul_pll_id < NR_PLLS); - - if (ul_pll_id == PLLA_ID) { - pmc_disable_pllack(); // Always stop PLL first! - PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; - } else { - PMC->CKGR_UCKR = p_cfg->ctrl; - } -} - -static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id) -{ - Assert(ul_pll_id < NR_PLLS); - - if (ul_pll_id == PLLA_ID) { - pmc_disable_pllack(); // Always stop PLL first! - PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; - } else { - PMC->CKGR_UCKR = p_cfg->ctrl | CKGR_UCKR_UPLLEN; - } -} - -/** - * \note This will only disable the selected PLL, not the underlying oscillator (mainck). - */ -static inline void pll_disable(uint32_t ul_pll_id) -{ - Assert(ul_pll_id < NR_PLLS); - - if (ul_pll_id == PLLA_ID) { - pmc_disable_pllack(); - } else { - PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; - } -} - -static inline uint32_t pll_is_locked(uint32_t ul_pll_id) -{ - Assert(ul_pll_id < NR_PLLS); - - if (ul_pll_id == PLLA_ID) { - return pmc_is_locked_pllack(); - } else { - return pmc_is_locked_upll(); - } -} - -static inline void pll_enable_source(enum pll_source e_src) -{ - switch (e_src) { - case PLL_SRC_MAINCK_4M_RC: - case PLL_SRC_MAINCK_8M_RC: - case PLL_SRC_MAINCK_12M_RC: - case PLL_SRC_MAINCK_XTAL: - case PLL_SRC_MAINCK_BYPASS: - osc_enable(e_src); - osc_wait_ready(e_src); - break; - - default: - Assert(false); - break; - } -} - -static inline void pll_enable_config_defaults(unsigned int ul_pll_id) -{ - struct pll_config pllcfg; - - if (pll_is_locked(ul_pll_id)) { - return; // Pll already running - } - switch (ul_pll_id) { -#ifdef CONFIG_PLL0_SOURCE - case 0: - pll_enable_source(CONFIG_PLL0_SOURCE); - pll_config_init(&pllcfg, - CONFIG_PLL0_SOURCE, - CONFIG_PLL0_DIV, - CONFIG_PLL0_MUL); - break; -#endif -#ifdef CONFIG_PLL1_SOURCE - case 1: - pll_enable_source(CONFIG_PLL1_SOURCE); - pll_config_init(&pllcfg, - CONFIG_PLL1_SOURCE, - CONFIG_PLL1_DIV, - CONFIG_PLL1_MUL); - break; -#endif - default: - Assert(false); - break; - } - pll_enable(&pllcfg, ul_pll_id); - while (!pll_is_locked(ul_pll_id)); -} - -/** - * \brief Wait for PLL \a pll_id to become locked - * - * \todo Use a timeout to avoid waiting forever and hanging the system - * - * \param pll_id The ID of the PLL to wait for. - * - * \retval STATUS_OK The PLL is now locked. - * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. - */ -static inline int pll_wait_for_lock(unsigned int pll_id) -{ - Assert(pll_id < NR_PLLS); - - while (!pll_is_locked(pll_id)) { - /* Do nothing */ - } - - return 0; -} - -//! @} - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif /* CHIP_PLL_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/preprocessor.h b/src/HAL/DUE/usb/preprocessor.h deleted file mode 100644 index c12d01c..0000000 --- a/src/HAL/DUE/usb/preprocessor.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \file - * - * \brief Preprocessor utils. - * - * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _PREPROCESSOR_H_ -#define _PREPROCESSOR_H_ - -#include "tpaste.h" -#include "stringz.h" -#include "mrepeat.h" - - -#endif // _PREPROCESSOR_H_ diff --git a/src/HAL/DUE/usb/sbc_protocol.h b/src/HAL/DUE/usb/sbc_protocol.h deleted file mode 100644 index ab84573..0000000 --- a/src/HAL/DUE/usb/sbc_protocol.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * \file - * - * \brief SCSI Block Commands - * - * This file contains definitions of some of the commands found in the - * SCSI SBC-2 standard. - * - * Note that the SBC specification depends on several commands defined - * by the SCSI Primary Commands (SPC) standard. Each version of the SBC - * standard is meant to be used in conjunction with a specific version - * of the SPC standard, as follows: - * - SBC depends on SPC - * - SBC-2 depends on SPC-3 - * - SBC-3 depends on SPC-4 - * - * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ -#ifndef _SBC_PROTOCOL_H_ -#define _SBC_PROTOCOL_H_ - - -/** - * \ingroup usb_msc_protocol - * \defgroup usb_sbc_protocol SCSI Block Commands protocol definitions - * - * @{ - */ - -//! \name SCSI commands defined by SBC-2 -//@{ -#define SBC_FORMAT_UNIT 0x04 -#define SBC_READ6 0x08 -#define SBC_WRITE6 0x0A -#define SBC_START_STOP_UNIT 0x1B -#define SBC_READ_CAPACITY10 0x25 -#define SBC_READ10 0x28 -#define SBC_WRITE10 0x2A -#define SBC_VERIFY10 0x2F -//@} - -//! \name SBC-2 Mode page definitions -//@{ - -enum scsi_sbc_mode { - SCSI_MS_MODE_RW_ERR_RECOV = 0x01, //!< Read-Write Error Recovery mode page - SCSI_MS_MODE_FORMAT_DEVICE = 0x03, //!< Format Device mode page - SCSI_MS_MODE_FLEXIBLE_DISK = 0x05, //!< Flexible Disk mode page - SCSI_MS_MODE_CACHING = 0x08, //!< Caching mode page -}; - - -//! \name SBC-2 Device-Specific Parameter -//@{ -#define SCSI_MS_SBC_WP 0x80 //!< Write Protected -#define SCSI_MS_SBC_DPOFUA 0x10 //!< DPO and FUA supported -//@} - -/** - * \brief SBC-2 Short LBA mode parameter block descriptor - */ -struct sbc_slba_block_desc { - be32_t nr_blocks; //!< Number of Blocks - be32_t block_len; //!< Block Length -#define SBC_SLBA_BLOCK_LEN_MASK 0x00FFFFFFU //!< Mask reserved bits -}; - -/** - * \brief SBC-2 Caching mode page - */ -struct sbc_caching_mode_page { - uint8_t page_code; - uint8_t page_length; - uint8_t flags2; -#define SBC_MP_CACHE_IC (1 << 7) //!< Initiator Control -#define SBC_MP_CACHE_ABPF (1 << 6) //!< Abort Pre-Fetch -#define SBC_MP_CACHE_CAP (1 << 5) //!< Catching Analysis Permitted -#define SBC_MP_CACHE_DISC (1 << 4) //!< Discontinuity -#define SBC_MP_CACHE_SIZE (1 << 3) //!< Size enable -#define SBC_MP_CACHE_WCE (1 << 2) //!< Write back Cache Enable -#define SBC_MP_CACHE_MF (1 << 1) //!< Multiplication Factor -#define SBC_MP_CACHE_RCD (1 << 0) //!< Read Cache Disable - uint8_t retention; - be16_t dis_pf_transfer_len; - be16_t min_prefetch; - be16_t max_prefetch; - be16_t max_prefetch_ceil; - uint8_t flags12; -#define SBC_MP_CACHE_FSW (1 << 7) //!< Force Sequential Write -#define SBC_MP_CACHE_LBCSS (1 << 6) //!< Logical Blk Cache Seg Sz -#define SBC_MP_CACHE_DRA (1 << 5) //!< Disable Read-Ahead -#define SBC_MP_CACHE_NV_DIS (1 << 0) //!< Non-Volatile Cache Disable - uint8_t nr_cache_segments; - be16_t cache_segment_size; - uint8_t reserved[4]; -}; - -/** - * \brief SBC-2 Read-Write Error Recovery mode page - */ -struct sbc_rdwr_error_recovery_mode_page { - uint8_t page_code; - uint8_t page_length; -#define SPC_MP_RW_ERR_RECOV_PAGE_LENGTH 0x0A - uint8_t flags1; -#define SBC_MP_RW_ERR_RECOV_AWRE (1 << 7) -#define SBC_MP_RW_ERR_RECOV_ARRE (1 << 6) -#define SBC_MP_RW_ERR_RECOV_TB (1 << 5) -#define SBC_MP_RW_ERR_RECOV_RC (1 << 4) -#define SBC_MP_RW_ERR_RECOV_ERR (1 << 3) -#define SBC_MP_RW_ERR_RECOV_PER (1 << 2) -#define SBC_MP_RW_ERR_RECOV_DTE (1 << 1) -#define SBC_MP_RW_ERR_RECOV_DCR (1 << 0) - uint8_t read_retry_count; - uint8_t correction_span; - uint8_t head_offset_count; - uint8_t data_strobe_offset_count; - uint8_t flags2; - uint8_t write_retry_count; - uint8_t flags3; - be16_t recovery_time_limit; -}; -//@} - -/** - * \brief SBC-2 READ CAPACITY (10) parameter data - */ -struct sbc_read_capacity10_data { - be32_t max_lba; //!< LBA of last logical block - be32_t block_len; //!< Number of bytes in the last logical block -}; - -//@} - -#endif // _SBC_PROTOCOL_H_ diff --git a/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp b/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp deleted file mode 100644 index 34cc256..0000000 --- a/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/** - * Interface from Atmel USB MSD to Marlin SD card - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(SDSUPPORT) - -#include "../../../sd/cardreader.h" -extern "C" { - #include "sd_mmc_spi_mem.h" -} - -#define SD_MMC_BLOCK_SIZE 512 - -void sd_mmc_spi_mem_init() { -} - -Ctrl_status sd_mmc_spi_test_unit_ready() { - #ifdef DISABLE_DUE_SD_MMC - return CTRL_NO_PRESENT; - #endif - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; - return CTRL_GOOD; -} - -// NOTE: This function is defined as returning the address of the last block -// in the card, which is cardSize() - 1 -Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) { - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; - *nb_sector = card.diskIODriver()->cardSize() - 1; - return CTRL_GOOD; -} - -bool sd_mmc_spi_unload(bool) { return true; } - -bool sd_mmc_spi_wr_protect() { return false; } - -bool sd_mmc_spi_removal() { - return (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()); -} - -#if ACCESS_USB == true -/** - * \name MEM <-> USB Interface - * @{ - */ - -#include "udi_msc.h" - -COMPILER_WORD_ALIGNED -uint8_t sector_buf[SD_MMC_BLOCK_SIZE]; - -// #define DEBUG_MMC - -Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) { - #ifdef DISABLE_DUE_SD_MMC - return CTRL_NO_PRESENT; - #endif - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; - - #ifdef DEBUG_MMC - { - char buffer[80]; - sprintf_P(buffer, PSTR("SDRD: %d @ 0x%08x\n"), nb_sector, addr); - PORT_REDIRECT(SERIAL_PORTMASK(0)); - SERIAL_ECHO(buffer); - } - #endif - - // Start reading - if (!card.diskIODriver()->readStart(addr)) - return CTRL_FAIL; - - // For each specified sector - while (nb_sector--) { - - // Read a sector - card.diskIODriver()->readData(sector_buf); - - // RAM -> USB - if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) { - card.diskIODriver()->readStop(); - return CTRL_FAIL; - } - } - - // Stop reading - card.diskIODriver()->readStop(); - - // Done - return CTRL_GOOD; -} - -Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) { - #ifdef DISABLE_DUE_SD_MMC - return CTRL_NO_PRESENT; - #endif - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; - - #ifdef DEBUG_MMC - { - char buffer[80]; - sprintf_P(buffer, PSTR("SDWR: %d @ 0x%08x\n"), nb_sector, addr); - PORT_REDIRECT(SERIAL_PORTMASK(0)); - SERIAL_ECHO(buffer); - } - #endif - - if (!card.diskIODriver()->writeStart(addr, nb_sector)) - return CTRL_FAIL; - - // For each specified sector - while (nb_sector--) { - - // USB -> RAM - if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) { - card.diskIODriver()->writeStop(); - return CTRL_FAIL; - } - - // Write a sector - card.diskIODriver()->writeData(sector_buf); - } - - // Stop writing - card.diskIODriver()->writeStop(); - - // Done - return CTRL_GOOD; -} - -#endif // ACCESS_USB == true - -#endif // SDSUPPORT -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/sd_mmc_spi_mem.h b/src/HAL/DUE/usb/sd_mmc_spi_mem.h deleted file mode 100644 index 553fd3c..0000000 --- a/src/HAL/DUE/usb/sd_mmc_spi_mem.h +++ /dev/null @@ -1,177 +0,0 @@ -/***************************************************************************** - * - * \file - * - * \brief CTRL_ACCESS interface for SD/MMC card. - * - * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - ******************************************************************************/ -/* - * Support and FAQ: visit Atmel Support - */ - - -#ifndef _SD_MMC_SPI_MEM_H_ -#define _SD_MMC_SPI_MEM_H_ - -/** - * \defgroup group_avr32_components_memory_sd_mmc_sd_mmc_spi_mem SD/MMC SPI Memory - * - * \ingroup group_avr32_components_memory_sd_mmc_sd_mmc_spi - * - * \{ - */ - -#include "conf_access.h" - -#if SD_MMC_SPI_MEM == DISABLE - #error sd_mmc_spi_mem.h is #included although SD_MMC_SPI_MEM is disabled -#endif - - -#include "ctrl_access.h" - - -//_____ D E F I N I T I O N S ______________________________________________ - -#define SD_MMC_REMOVED 0 -#define SD_MMC_INSERTED 1 -#define SD_MMC_REMOVING 2 - - -//---- CONTROL FUNCTIONS ---- -//! -//! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI. -//!/ -extern void sd_mmc_spi_mem_init(void); - -//! -//! @brief This function tests the state of the SD_MMC memory and sends it to the Host. -//! For a PC, this device is seen as a removable media -//! Before indicating any modification of the status of the media (GOOD->NO_PRESENT or vice-versa), -//! the function must return the BUSY data to make the PC accepting the change -//! -//! @return Ctrl_status -//! Media is ready -> CTRL_GOOD -//! Media not present -> CTRL_NO_PRESENT -//! Media has changed -> CTRL_BUSY -//!/ -extern Ctrl_status sd_mmc_spi_test_unit_ready(void); - -//! -//! @brief This function gives the address of the last valid sector. -//! -//! @param *nb_sector number of sector (sector = 512B). OUT -//! -//! @return Ctrl_status -//! Media ready -> CTRL_GOOD -//! Media not present -> CTRL_NO_PRESENT -//!/ -extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector); - -/*! \brief Unload/Load the SD/MMC card selected - * - * The START STOP UNIT SCSI optional command allows an application client to - * eject the removable medium on a LUN. - * - * \param unload \c true to unload the medium, \c false to load the medium. - * - * \return \c true if unload/load done success. - */ -extern bool sd_mmc_spi_unload(bool unload); - -//! -//! @brief This function returns the write protected status of the memory. -//! -//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection -//! ! The user must unplug the memory to change this write protected status, -//! which cannot be for a SD_MMC. -//! -//! @return false -> the memory is not write-protected (always) -//!/ -extern bool sd_mmc_spi_wr_protect(void); - -//! -//! @brief This function tells if the memory has been removed or not. -//! -//! @return false -> The memory isn't removed -//! -extern bool sd_mmc_spi_removal(void); - - -//---- ACCESS DATA FUNCTIONS ---- - -#if ACCESS_USB == true -// Standard functions for open in read/write mode the device - -//! -//! @brief This function performs a read operation of n sectors from a given address on. -//! (sector = 512B) -//! -//! DATA FLOW is: SD_MMC => USB -//! -//! @param addr Sector address to start the read from -//! @param nb_sector Number of sectors to transfer -//! -//! @return Ctrl_status -//! It is ready -> CTRL_GOOD -//! A error occur -> CTRL_FAIL -//! -extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector); - -//! This function initializes the SD/MMC memory for a write operation -//! -//! DATA FLOW is: USB => SD_MMC -//! -//! (sector = 512B) -//! @param addr Sector address to start write -//! @param nb_sector Number of sectors to transfer -//! -//! @return Ctrl_status -//! It is ready -> CTRL_GOOD -//! An error occurs -> CTRL_FAIL -//! -extern Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector); - -#endif // #if ACCESS_USB == true - -/** - * \} - */ - -#endif // _SD_MMC_SPI_MEM_H_ diff --git a/src/HAL/DUE/usb/spc_protocol.h b/src/HAL/DUE/usb/spc_protocol.h deleted file mode 100644 index d67cc5c..0000000 --- a/src/HAL/DUE/usb/spc_protocol.h +++ /dev/null @@ -1,337 +0,0 @@ -/** - * \file - * - * \brief SCSI Primary Commands - * - * This file contains definitions of some of the commands found in the - * SPC-2 standard. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -/* - * Support and FAQ: visit Atmel Support - */ -#ifndef _SPC_PROTOCOL_H_ -#define _SPC_PROTOCOL_H_ - -/** - * \ingroup usb_msc_protocol - * \defgroup usb_spc_protocol SCSI Primary Commands protocol definitions - * - * @{ - */ - -//! \name SCSI commands defined by SPC-2 -//@{ -#define SPC_TEST_UNIT_READY 0x00 -#define SPC_REQUEST_SENSE 0x03 -#define SPC_INQUIRY 0x12 -#define SPC_MODE_SELECT6 0x15 -#define SPC_MODE_SENSE6 0x1A -#define SPC_SEND_DIAGNOSTIC 0x1D -#define SPC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E -#define SPC_MODE_SENSE10 0x5A -#define SPC_REPORT_LUNS 0xA0 -//@} - -//! \brief May be set in byte 0 of the INQUIRY CDB -//@{ -//! Enable Vital Product Data -#define SCSI_INQ_REQ_EVPD 0x01 -//! Command Support Data specified by the PAGE OR OPERATION CODE field -#define SCSI_INQ_REQ_CMDT 0x02 -//@} - -COMPILER_PACK_SET(1) - -/** - * \brief SCSI Standard Inquiry data structure - */ -struct scsi_inquiry_data { - uint8_t pq_pdt; //!< Peripheral Qual / Peripheral Dev Type -#define SCSI_INQ_PQ_CONNECTED 0x00 //!< Peripheral connected -#define SCSI_INQ_PQ_NOT_CONN 0x20 //!< Peripheral not connected -#define SCSI_INQ_PQ_NOT_SUPP 0x60 //!< Peripheral not supported -#define SCSI_INQ_DT_DIR_ACCESS 0x00 //!< Direct Access (SBC) -#define SCSI_INQ_DT_SEQ_ACCESS 0x01 //!< Sequential Access -#define SCSI_INQ_DT_PRINTER 0x02 //!< Printer -#define SCSI_INQ_DT_PROCESSOR 0x03 //!< Processor device -#define SCSI_INQ_DT_WRITE_ONCE 0x04 //!< Write-once device -#define SCSI_INQ_DT_CD_DVD 0x05 //!< CD/DVD device -#define SCSI_INQ_DT_OPTICAL 0x07 //!< Optical Memory -#define SCSI_INQ_DT_MC 0x08 //!< Medium Changer -#define SCSI_INQ_DT_ARRAY 0x0C //!< Storage Array Controller -#define SCSI_INQ_DT_ENCLOSURE 0x0D //!< Enclosure Services -#define SCSI_INQ_DT_RBC 0x0E //!< Simplified Direct Access -#define SCSI_INQ_DT_OCRW 0x0F //!< Optical card reader/writer -#define SCSI_INQ_DT_BCC 0x10 //!< Bridge Controller Commands -#define SCSI_INQ_DT_OSD 0x11 //!< Object-based Storage -#define SCSI_INQ_DT_NONE 0x1F //!< No Peripheral - uint8_t flags1; //!< Flags (byte 1) -#define SCSI_INQ_RMB 0x80 //!< Removable Medium - uint8_t version; //!< Version -#define SCSI_INQ_VER_NONE 0x00 //!< No standards conformance -#define SCSI_INQ_VER_SPC 0x03 //!< SCSI Primary Commands (link to SBC) -#define SCSI_INQ_VER_SPC2 0x04 //!< SCSI Primary Commands - 2 (link to SBC-2) -#define SCSI_INQ_VER_SPC3 0x05 //!< SCSI Primary Commands - 3 (link to SBC-2) -#define SCSI_INQ_VER_SPC4 0x06 //!< SCSI Primary Commands - 4 (link to SBC-3) - uint8_t flags3; //!< Flags (byte 3) -#define SCSI_INQ_NORMACA 0x20 //!< Normal ACA Supported -#define SCSI_INQ_HISUP 0x10 //!< Hierarchal LUN addressing -#define SCSI_INQ_RSP_SPC2 0x02 //!< SPC-2 / SPC-3 response format - uint8_t addl_len; //!< Additional Length (n-4) -#define SCSI_INQ_ADDL_LEN(tot) ((tot)-5) //!< Total length is \a tot - uint8_t flags5; //!< Flags (byte 5) -#define SCSI_INQ_SCCS 0x80 - uint8_t flags6; //!< Flags (byte 6) -#define SCSI_INQ_BQUE 0x80 -#define SCSI_INQ_ENCSERV 0x40 -#define SCSI_INQ_MULTIP 0x10 -#define SCSI_INQ_MCHGR 0x08 -#define SCSI_INQ_ADDR16 0x01 - uint8_t flags7; //!< Flags (byte 7) -#define SCSI_INQ_WBUS16 0x20 -#define SCSI_INQ_SYNC 0x10 -#define SCSI_INQ_LINKED 0x08 -#define SCSI_INQ_CMDQUE 0x02 - uint8_t vendor_id[8]; //!< T10 Vendor Identification - uint8_t product_id[16]; //!< Product Identification - uint8_t product_rev[4]; //!< Product Revision Level -}; - -/** - * \brief SCSI Standard Request sense data structure - */ -struct scsi_request_sense_data { - /* 1st byte: REQUEST SENSE response flags*/ - uint8_t valid_reponse_code; -#define SCSI_SENSE_VALID 0x80 //!< Indicates the INFORMATION field contains valid information -#define SCSI_SENSE_RESPONSE_CODE_MASK 0x7F -#define SCSI_SENSE_CURRENT 0x70 //!< Response code 70h (current errors) -#define SCSI_SENSE_DEFERRED 0x71 - - /* 2nd byte */ - uint8_t obsolete; - - /* 3rd byte */ - uint8_t sense_flag_key; -#define SCSI_SENSE_FILEMARK 0x80 //!< Indicates that the current command has read a filemark or setmark. -#define SCSI_SENSE_EOM 0x40 //!< Indicates that an end-of-medium condition exists. -#define SCSI_SENSE_ILI 0x20 //!< Indicates that the requested logical block length did not match the logical block length of the data on the medium. -#define SCSI_SENSE_RESERVED 0x10 //!< Reserved -#define SCSI_SENSE_KEY(x) (x&0x0F) //!< Sense Key - - /* 4th to 7th bytes - INFORMATION field */ - uint8_t information[4]; - - /* 8th byte - ADDITIONAL SENSE LENGTH field */ - uint8_t AddSenseLen; -#define SCSI_SENSE_ADDL_LEN(total_len) ((total_len) - 8) - - /* 9th to 12th byte - COMMAND-SPECIFIC INFORMATION field */ - uint8_t CmdSpecINFO[4]; - - /* 13th byte - ADDITIONAL SENSE CODE field */ - uint8_t AddSenseCode; - - /* 14th byte - ADDITIONAL SENSE CODE QUALIFIER field */ - uint8_t AddSnsCodeQlfr; - - /* 15th byte - FIELD REPLACEABLE UNIT CODE field */ - uint8_t FldReplUnitCode; - - /* 16th byte */ - uint8_t SenseKeySpec[3]; -#define SCSI_SENSE_SKSV 0x80 //!< Indicates the SENSE-KEY SPECIFIC field contains valid information -}; - -COMPILER_PACK_RESET() - -/* Vital Product Data page codes */ -enum scsi_vpd_page_code { - SCSI_VPD_SUPPORTED_PAGES = 0x00, - SCSI_VPD_UNIT_SERIAL_NUMBER = 0x80, - SCSI_VPD_DEVICE_IDENTIFICATION = 0x83, -}; -#define SCSI_VPD_HEADER_SIZE 4 - -/* Constants associated with the Device Identification VPD page */ -#define SCSI_VPD_ID_HEADER_SIZE 4 - -#define SCSI_VPD_CODE_SET_BINARY 1 -#define SCSI_VPD_CODE_SET_ASCII 2 -#define SCSI_VPD_CODE_SET_UTF8 3 - -#define SCSI_VPD_ID_TYPE_T10 1 - - -/* Sense keys */ -enum scsi_sense_key { - SCSI_SK_NO_SENSE = 0x0, - SCSI_SK_RECOVERED_ERROR = 0x1, - SCSI_SK_NOT_READY = 0x2, - SCSI_SK_MEDIUM_ERROR = 0x3, - SCSI_SK_HARDWARE_ERROR = 0x4, - SCSI_SK_ILLEGAL_REQUEST = 0x5, - SCSI_SK_UNIT_ATTENTION = 0x6, - SCSI_SK_DATA_PROTECT = 0x7, - SCSI_SK_BLANK_CHECK = 0x8, - SCSI_SK_VENDOR_SPECIFIC = 0x9, - SCSI_SK_COPY_ABORTED = 0xA, - SCSI_SK_ABORTED_COMMAND = 0xB, - SCSI_SK_VOLUME_OVERFLOW = 0xD, - SCSI_SK_MISCOMPARE = 0xE, -}; - -/* Additional Sense Code / Additional Sense Code Qualifier pairs */ -enum scsi_asc_ascq { - SCSI_ASC_NO_ADDITIONAL_SENSE_INFO = 0x0000, - SCSI_ASC_LU_NOT_READY_REBUILD_IN_PROGRESS = 0x0405, - SCSI_ASC_WRITE_ERROR = 0x0C00, - SCSI_ASC_UNRECOVERED_READ_ERROR = 0x1100, - SCSI_ASC_INVALID_COMMAND_OPERATION_CODE = 0x2000, - SCSI_ASC_INVALID_FIELD_IN_CDB = 0x2400, - SCSI_ASC_WRITE_PROTECTED = 0x2700, - SCSI_ASC_NOT_READY_TO_READY_CHANGE = 0x2800, - SCSI_ASC_MEDIUM_NOT_PRESENT = 0x3A00, - SCSI_ASC_INTERNAL_TARGET_FAILURE = 0x4400, -}; - -/** - * \brief SPC-2 Mode parameter - * This subclause describes the block descriptors and the pages - * used with MODE SELECT and MODE SENSE commands - * that are applicable to all SCSI devices. - */ -enum scsi_spc_mode { - SCSI_MS_MODE_VENDOR_SPEC = 0x00, - SCSI_MS_MODE_INFEXP = 0x1C, // Informational exceptions control page - SCSI_MS_MODE_ALL = 0x3F, -}; - -/** - * \brief SPC-2 Informational exceptions control page - * See chapter 8.3.8 - */ -struct spc_control_page_info_execpt { - uint8_t page_code; - uint8_t page_length; -#define SPC_MP_INFEXP_PAGE_LENGTH 0x0A - uint8_t flags1; -#define SPC_MP_INFEXP_PERF (1<<7) //!< Initiator Control -#define SPC_MP_INFEXP_EBF (1<<5) //!< Caching Analysis Permitted -#define SPC_MP_INFEXP_EWASC (1<<4) //!< Discontinuity -#define SPC_MP_INFEXP_DEXCPT (1<<3) //!< Size enable -#define SPC_MP_INFEXP_TEST (1<<2) //!< Writeback Cache Enable -#define SPC_MP_INFEXP_LOGERR (1<<0) //!< Log errors bit - uint8_t mrie; -#define SPC_MP_INFEXP_MRIE_NO_REPORT 0x00 -#define SPC_MP_INFEXP_MRIE_ASYNC_EVENT 0x01 -#define SPC_MP_INFEXP_MRIE_GEN_UNIT 0x02 -#define SPC_MP_INFEXP_MRIE_COND_RECOV_ERROR 0x03 -#define SPC_MP_INFEXP_MRIE_UNCOND_RECOV_ERROR 0x04 -#define SPC_MP_INFEXP_MRIE_NO_SENSE 0x05 -#define SPC_MP_INFEXP_MRIE_ONLY_REPORT 0x06 - be32_t interval_timer; - be32_t report_count; -}; - - -enum scsi_spc_mode_sense_pc { - SCSI_MS_SENSE_PC_CURRENT = 0, - SCSI_MS_SENSE_PC_CHANGEABLE = 1, - SCSI_MS_SENSE_PC_DEFAULT = 2, - SCSI_MS_SENSE_PC_SAVED = 3, -}; - - - -static inline bool scsi_mode_sense_dbd_is_set(const uint8_t * cdb) -{ - return (cdb[1] >> 3) & 1; -} - -static inline uint8_t scsi_mode_sense_get_page_code(const uint8_t * cdb) -{ - return cdb[2] & 0x3F; -} - -static inline uint8_t scsi_mode_sense_get_pc(const uint8_t * cdb) -{ - return cdb[2] >> 6; -} - -/** - * \brief SCSI Mode Parameter Header used by MODE SELECT(6) and MODE - * SENSE(6) - */ -struct scsi_mode_param_header6 { - uint8_t mode_data_length; //!< Number of bytes after this - uint8_t medium_type; //!< Medium Type - uint8_t device_specific_parameter; //!< Defined by command set - uint8_t block_descriptor_length; //!< Length of block descriptors -}; - -/** - * \brief SCSI Mode Parameter Header used by MODE SELECT(10) and MODE - * SENSE(10) - */ -struct scsi_mode_param_header10 { - be16_t mode_data_length; //!< Number of bytes after this - uint8_t medium_type; //!< Medium Type - uint8_t device_specific_parameter; //!< Defined by command set - uint8_t flags4; //!< LONGLBA in bit 0 - uint8_t reserved; - be16_t block_descriptor_length; //!< Length of block descriptors -}; - -/** - * \brief SCSI Page_0 Mode Page header (SPF not set) - */ -struct scsi_mode_page_0_header { - uint8_t page_code; -#define SCSI_PAGE_CODE_PS (1 << 7) //!< Parameters Saveable -#define SCSI_PAGE_CODE_SPF (1 << 6) //!< SubPage Format - uint8_t page_length; //!< Number of bytes after this -#define SCSI_MS_PAGE_LEN(total) ((total) - 2) -}; - -//@} - -#endif // SPC_PROTOCOL_H_ diff --git a/src/HAL/DUE/usb/stringz.h b/src/HAL/DUE/usb/stringz.h deleted file mode 100644 index fc9aaf3..0000000 --- a/src/HAL/DUE/usb/stringz.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * \file - * - * \brief Preprocessor stringizing utils. - * - * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _STRINGZ_H_ -#define _STRINGZ_H_ - -/** - * \defgroup group_sam_utils_stringz Preprocessor - Stringize - * - * \ingroup group_sam_utils - * - * \{ - */ - -/*! \brief Stringize. - * - * Stringize a preprocessing token, this token being allowed to be \#defined. - * - * May be used only within macros with the token passed as an argument if the token is \#defined. - * - * For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN) - * and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to - * writing "A0". - */ -#define STRINGZ(x) #x - -/*! \brief Absolute stringize. - * - * Stringize a preprocessing token, this token being allowed to be \#defined. - * - * No restriction of use if the token is \#defined. - * - * For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is - * equivalent to writing "A0". - */ -#define ASTRINGZ(x) STRINGZ(x) - -/** - * \} - */ - -#endif // _STRINGZ_H_ diff --git a/src/HAL/DUE/usb/sysclk.c b/src/HAL/DUE/usb/sysclk.c deleted file mode 100644 index cbb4e2c..0000000 --- a/src/HAL/DUE/usb/sysclk.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \file - * - * \brief Chip-specific system clock management functions. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "sysclk.h" - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -/** - * \weakgroup sysclk_group - * @{ - */ - -#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) -/** - * \brief Enable full speed USB clock. - * - * \note The SAM3X PMC hardware interprets div as div+1. For readability the hardware div+1 - * is hidden in this implementation. Use div as div effective value. - * - * \param pll_id Source of the USB clock. - * \param div Actual clock divisor. Must be superior to 0. - */ -void sysclk_enable_usb(void) -{ - Assert(CONFIG_USBCLK_DIV > 0); - -#ifdef CONFIG_PLL0_SOURCE - if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL0) { - struct pll_config pllcfg; - - pll_enable_source(CONFIG_PLL0_SOURCE); - pll_config_defaults(&pllcfg, 0); - pll_enable(&pllcfg, 0); - pll_wait_for_lock(0); - pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); - pmc_enable_udpck(); - return; - } -#endif - - if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_UPLL) { - - pmc_enable_upll_clock(); - pmc_switch_udpck_to_upllck(CONFIG_USBCLK_DIV - 1); - pmc_enable_udpck(); - return; - } -} - -/** - * \brief Disable full speed USB clock. - * - * \note This implementation does not switch off the PLL, it just turns off the USB clock. - */ -void sysclk_disable_usb(void) -{ - pmc_disable_udpck(); -} -#endif // CONFIG_USBCLK_SOURCE - -//! @} - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/sysclk.h b/src/HAL/DUE/usb/sysclk.h deleted file mode 100644 index 16db8c8..0000000 --- a/src/HAL/DUE/usb/sysclk.h +++ /dev/null @@ -1,229 +0,0 @@ -/** - * \file - * - * \brief Chip-specific system clock management functions. - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef CHIP_SYSCLK_H_INCLUDED -#define CHIP_SYSCLK_H_INCLUDED - -#include "osc.h" -#include "pll.h" - -/** - * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (SAM3A) - * - * This is the quick start guide for the \ref sysclk_group "System Clock Management" - * service, with step-by-step instructions on how to configure and use the service for - * specific use cases. - * - * \section sysclk_quickstart_usecases System Clock Management use cases - * - \ref sysclk_quickstart_basic - * - * \section sysclk_quickstart_basic Basic usage of the System Clock Management service - * This section will present a basic use case for the System Clock Management service. - * This use case will configure the main system clock to 84MHz, using an internal PLL - * module to multiply the frequency of a crystal attached to the microcontroller. - * - * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites - * - None - * - * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code - * Add to the application initialization code: - * \code - sysclk_init(); -\endcode - * - * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow - * -# Configure the system clocks according to the settings in conf_clock.h: - * \code sysclk_init(); \endcode - * - * \subsection sysclk_quickstart_use_case_1_example_code Example code - * Add or uncomment the following in your conf_clock.h header file, commenting out all other - * definitions of the same symbol(s): - * \code - #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK - - // Fpll0 = (Fclk * PLL_mul) / PLL_div - #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL - #define CONFIG_PLL0_MUL (84000000UL / BOARD_FREQ_MAINCK_XTAL) - #define CONFIG_PLL0_DIV 1 - - // Fbus = Fsys / BUS_div - #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 -\endcode - * - * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow - * -# Configure the main system clock to use the output of the PLL module as its source: - * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode - * -# Configure the PLL module to use the fast external fast crystal oscillator as its source: - * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode - * -# Configure the PLL module to multiply the external fast crystal oscillator frequency up to 84MHz: - * \code - #define CONFIG_PLL0_MUL (84000000UL / BOARD_FREQ_MAINCK_XTAL) - #define CONFIG_PLL0_DIV 1 -\endcode - * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration - * file as the frequency of the fast crystal attached to the microcontroller. - * -# Configure the main clock to run at the full 84MHz, disable scaling of the main system clock speed: - * \code - #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 -\endcode - * \note Some dividers are powers of two, while others are integer division factors. Refer to the - * formulas in the conf_clock.h template commented above each division define. - */ - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -/** - * \weakgroup sysclk_group - * @{ - */ - -//! \name Configuration Symbols -//@{ -/** - * \def CONFIG_SYSCLK_SOURCE - * \brief Initial/static main system clock source - * - * The main system clock will be configured to use this clock during - * initialization. - */ -#ifndef CONFIG_SYSCLK_SOURCE -# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC -#endif -/** - * \def CONFIG_SYSCLK_PRES - * \brief Initial CPU clock divider (mck) - * - * The MCK will run at - * \f[ - * f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz} - * \f] - * after initialization. - */ -#ifndef CONFIG_SYSCLK_PRES -# define CONFIG_SYSCLK_PRES 0 -#endif - -//@} - -//! \name Master Clock Sources (MCK) -//@{ -#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock -#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock -#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock -#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock -#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock -#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock -#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock -#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock -#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock -#define SYSCLK_SRC_UPLLCK 9 //!< Use UPLLCK as master source clock -//@} - -//! \name Master Clock Prescalers (MCK) -//@{ -#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1 -#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2 -#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4 -#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8 -#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16 -#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32 -#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64 -#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3 -//@} - -//! \name USB Clock Sources -//@{ -#define USBCLK_SRC_PLL0 0 //!< Use PLLA -#define USBCLK_SRC_UPLL 1 //!< Use UPLL -//@} - -/** - * \def CONFIG_USBCLK_SOURCE - * \brief Configuration symbol for the USB generic clock source - * - * Sets the clock source to use for the USB. The source must also be properly - * configured. - * - * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if - * USB is not required. - */ -#ifdef __DOXYGEN__ -# define CONFIG_USBCLK_SOURCE -#endif - -/** - * \def CONFIG_USBCLK_DIV - * \brief Configuration symbol for the USB generic clock divider setting - * - * Sets the clock division for the USB generic clock. If a USB clock source is - * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be - * defined. - */ -#ifdef __DOXYGEN__ -# define CONFIG_USBCLK_DIV -#endif - - -extern void sysclk_enable_usb(void); -extern void sysclk_disable_usb(void); - -//! @} - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif /* CHIP_SYSCLK_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/tpaste.h b/src/HAL/DUE/usb/tpaste.h deleted file mode 100644 index 2ad3f27..0000000 --- a/src/HAL/DUE/usb/tpaste.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * \file - * - * \brief Preprocessor token pasting utils. - * - * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _TPASTE_H_ -#define _TPASTE_H_ - -/** - * \defgroup group_sam_utils_tpaste Preprocessor - Token Paste - * - * \ingroup group_sam_utils - * - * \{ - */ - -/*! \name Token Paste - * - * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. - * - * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. - * - * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by - * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is - * equivalent to writing U32. - */ -//! @{ -#define TPASTE2( a, b) a##b -#define TPASTE3( a, b, c) a##b##c -#define TPASTE4( a, b, c, d) a##b##c##d -#define TPASTE5( a, b, c, d, e) a##b##c##d##e -#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f -#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g -#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h -#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i -#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j -//! @} - -/*! \name Absolute Token Paste - * - * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. - * - * No restriction of use if the tokens are \#defined. - * - * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined - * as 32 is equivalent to writing U32. - */ -//! @{ -#define ATPASTE2( a, b) TPASTE2( a, b) -#define ATPASTE3( a, b, c) TPASTE3( a, b, c) -#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) -#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) -#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) -#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) -#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) -#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) -#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) -//! @} - -/** - * \} - */ - -#endif // _TPASTE_H_ diff --git a/src/HAL/DUE/usb/udc.c b/src/HAL/DUE/usb/udc.c deleted file mode 100644 index 60bf0cf..0000000 --- a/src/HAL/DUE/usb/udc.c +++ /dev/null @@ -1,1149 +0,0 @@ -/** - * \file - * - * \brief USB Device Controller (UDC) - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "udd.h" -#include "udc_desc.h" -#include "udi.h" -#include "udc.h" - -/** - * \ingroup udc_group - * \defgroup udc_group_interne Implementation of UDC - * - * Internal implementation - * @{ - */ - -//! \name Internal variables to manage the USB device -//! @{ - -//! Device status state (see enum usb_device_status in usb_protocol.h) -static le16_t udc_device_status; - -COMPILER_WORD_ALIGNED -//! Device interface setting value -static uint8_t udc_iface_setting = 0; - -//! Device Configuration number selected by the USB host -COMPILER_WORD_ALIGNED -static uint8_t udc_num_configuration = 0; - -//! Pointer on the selected speed device configuration -static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; - -//! Pointer on interface descriptor used by SETUP request. -static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; - -//! @} - - -//! \name Internal structure to store the USB device main strings -//! @{ - -/** - * \brief Language ID of USB device (US ID by default) - */ -COMPILER_WORD_ALIGNED -static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { - .desc.bLength = sizeof(usb_str_lgid_desc_t), - .desc.bDescriptorType = USB_DT_STRING, - .string = {LE16(USB_LANGID_EN_US)} -}; - -/** - * \brief USB device manufacture name storage - * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared - * by usb application configuration - */ -#ifdef USB_DEVICE_MANUFACTURE_NAME -static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; -# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ - (sizeof(udc_string_manufacturer_name)-1) -#else -# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 -#endif - -/** - * \brief USB device product name storage - * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared - * by usb application configuration - */ -#ifdef USB_DEVICE_PRODUCT_NAME -static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; -# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) -#else -# define USB_DEVICE_PRODUCT_NAME_SIZE 0 -#endif - -/** - * \brief Get USB device serial number - * - * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. - * - * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER - * to a suitable pointer. This will also require the serial number length - * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. - */ -#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER - static const uint8_t *udc_get_string_serial_name(void) - { - return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; - } -# define USB_DEVICE_SERIAL_NAME_SIZE \ - USB_DEVICE_GET_SERIAL_NAME_LENGTH -#elif defined USB_DEVICE_SERIAL_NAME - static const uint8_t *udc_get_string_serial_name(void) - { - return (const uint8_t *)USB_DEVICE_SERIAL_NAME; - } -# define USB_DEVICE_SERIAL_NAME_SIZE \ - (sizeof(USB_DEVICE_SERIAL_NAME)-1) -#else -# define USB_DEVICE_SERIAL_NAME_SIZE 0 -#endif - -/** - * \brief USB device string descriptor - * Structure used to transfer ASCII strings to USB String descriptor structure. - */ -struct udc_string_desc_t { - usb_str_desc_t header; - le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ - USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; -}; -COMPILER_WORD_ALIGNED -static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { - .header.bDescriptorType = USB_DT_STRING -}; -//! @} - -usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) -{ - return udc_ptr_iface; -} - -/** - * \brief Returns a value to check the end of USB Configuration descriptor - * - * \return address after the last byte of USB Configuration descriptor - */ -static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) -{ - return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) - udc_ptr_conf->desc + - le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); -} - -#if (0!=USB_DEVICE_MAX_EP) -/** - * \brief Search specific descriptor in global interface descriptor - * - * \param desc Address of interface descriptor - * or previous specific descriptor found - * \param desc_id Descriptor ID to search - * - * \return address of specific descriptor found - * \return NULL if it is the end of global interface descriptor - */ -static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t - UDC_DESC_STORAGE * desc, uint8_t desc_id) -{ - usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; - - ptr_eof_desc = udc_get_eof_conf(); - // Go to next descriptor - desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + - desc->bLength); - // Check the end of configuration descriptor - while (ptr_eof_desc > desc) { - // If new interface descriptor is found, - // then it is the end of the current global interface descriptor - if (USB_DT_INTERFACE == desc->bDescriptorType) { - break; // End of global interface descriptor - } - if (desc_id == desc->bDescriptorType) { - return desc; // Specific descriptor found - } - // Go to next descriptor - desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + - desc->bLength); - } - return NULL; // No specific descriptor found -} -#endif - -/** - * \brief Search an interface descriptor - * This routine updates the internal pointer udc_ptr_iface. - * - * \param iface_num Interface number to find in Configuration Descriptor - * \param setting_num Setting number of interface to find - * - * \return 1 if found or 0 if not found - */ -static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) -{ - usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; - - if (0 == udc_num_configuration) { - return false; - } - - if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { - return false; - } - - // Start at the beginning of configuration descriptor - udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) - udc_ptr_conf->desc; - - // Check the end of configuration descriptor - ptr_end_desc = udc_get_eof_conf(); - while (ptr_end_desc > - (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { - if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { - // A interface descriptor is found - // Check interface and alternate setting number - if ((iface_num == udc_ptr_iface->bInterfaceNumber) && - (setting_num == - udc_ptr_iface->bAlternateSetting)) { - return true; // Interface found - } - } - // Go to next descriptor - udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( - (uint8_t *) udc_ptr_iface + - udc_ptr_iface->bLength); - } - return false; // Interface not found -} - -/** - * \brief Disables an usb device interface (UDI) - * This routine call the UDI corresponding to interface number - * - * \param iface_num Interface number to disable - * - * \return 1 if it is done or 0 if interface is not found - */ -static bool udc_iface_disable(uint8_t iface_num) -{ - udi_api_t UDC_DESC_STORAGE *udi_api; - - // Select first alternate setting of the interface - // to update udc_ptr_iface before call iface->getsetting() - if (!udc_update_iface_desc(iface_num, 0)) { - return false; - } - - // Select the interface with the current alternate setting - udi_api = udc_ptr_conf->udi_apis[iface_num]; - -#if (0!=USB_DEVICE_MAX_EP) - if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { - return false; - } - - // Start at the beginning of interface descriptor - { - usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; - ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; - while (1) { - // Search Endpoint descriptor included in global interface descriptor - ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) - udc_next_desc_in_iface((UDC_DESC_STORAGE - usb_conf_desc_t *) - ep_desc, USB_DT_ENDPOINT); - if (NULL == ep_desc) { - break; - } - // Free the endpoint used by the interface - udd_ep_free(ep_desc->bEndpointAddress); - } - } -#endif - - // Disable interface - udi_api->disable(); - return true; -} - -/** - * \brief Enables an usb device interface (UDI) - * This routine calls the UDI corresponding - * to the interface and setting number. - * - * \param iface_num Interface number to enable - * \param setting_num Setting number to enable - * - * \return 1 if it is done or 0 if interface is not found - */ -static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) -{ - // Select the interface descriptor - if (!udc_update_iface_desc(iface_num, setting_num)) { - return false; - } - -#if (0!=USB_DEVICE_MAX_EP) - usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; - - // Start at the beginning of the global interface descriptor - ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; - while (1) { - // Search Endpoint descriptor included in the global interface descriptor - ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) - udc_next_desc_in_iface((UDC_DESC_STORAGE - usb_conf_desc_t *) ep_desc, - USB_DT_ENDPOINT); - if (NULL == ep_desc) - break; - // Alloc the endpoint used by the interface - if (!udd_ep_alloc(ep_desc->bEndpointAddress, - ep_desc->bmAttributes, - le16_to_cpu - (ep_desc->wMaxPacketSize))) { - return false; - } - } -#endif - // Enable the interface - return udc_ptr_conf->udi_apis[iface_num]->enable(); -} - -/*! \brief Start the USB Device stack - */ -void udc_start(void) -{ - udd_enable(); -} - -/*! \brief Stop the USB Device stack - */ -void udc_stop(void) -{ - udd_disable(); - udc_reset(); -} - -/** - * \brief Reset the current configuration of the USB device, - * This routines can be called by UDD when a RESET on the USB line occurs. - */ -void udc_reset(void) -{ - uint8_t iface_num; - - if (udc_num_configuration) { - for (iface_num = 0; - iface_num < udc_ptr_conf->desc->bNumInterfaces; - iface_num++) { - udc_iface_disable(iface_num); - } - } - udc_num_configuration = 0; -#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ - == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) - if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { - // Remote wakeup is enabled then disable it - UDC_REMOTEWAKEUP_DISABLE(); - } -#endif - udc_device_status = -#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) - CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); -#else - CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); -#endif -} - -void udc_sof_notify(void) -{ - uint8_t iface_num; - - if (udc_num_configuration) { - for (iface_num = 0; - iface_num < udc_ptr_conf->desc->bNumInterfaces; - iface_num++) { - if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { - udc_ptr_conf->udi_apis[iface_num]->sof_notify(); - } - } - } -} - -/** - * \brief Standard device request to get device status - * - * \return true if success - */ -static bool udc_req_std_dev_get_status(void) -{ - if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { - return false; - } - - udd_set_setup_payload( (uint8_t *) & udc_device_status, - sizeof(udc_device_status)); - return true; -} - -#if (0!=USB_DEVICE_MAX_EP) -/** - * \brief Standard endpoint request to get endpoint status - * - * \return true if success - */ -static bool udc_req_std_ep_get_status(void) -{ - static le16_t udc_ep_status; - - if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { - return false; - } - - udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. - wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; - - udd_set_setup_payload( (uint8_t *) & udc_ep_status, - sizeof(udc_ep_status)); - return true; -} -#endif - -/** - * \brief Standard device request to change device status - * - * \return true if success - */ -static bool udc_req_std_dev_clear_feature(void) -{ - if (udd_g_ctrlreq.req.wLength) { - return false; - } - - if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { - udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); -#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ - == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) - UDC_REMOTEWAKEUP_DISABLE(); -#endif - return true; - } - return false; -} - -#if (0!=USB_DEVICE_MAX_EP) -/** - * \brief Standard endpoint request to clear endpoint feature - * - * \return true if success - */ -static bool udc_req_std_ep_clear_feature(void) -{ - if (udd_g_ctrlreq.req.wLength) { - return false; - } - - if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { - return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); - } - return false; -} -#endif - -/** - * \brief Standard device request to set a feature - * - * \return true if success - */ -static bool udc_req_std_dev_set_feature(void) -{ - if (udd_g_ctrlreq.req.wLength) { - return false; - } - - switch (udd_g_ctrlreq.req.wValue) { - - case USB_DEV_FEATURE_REMOTE_WAKEUP: -#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ - == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) - udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); - UDC_REMOTEWAKEUP_ENABLE(); - return true; -#else - return false; -#endif - -#ifdef USB_DEVICE_HS_SUPPORT - case USB_DEV_FEATURE_TEST_MODE: - if (!udd_is_high_speed()) { - break; - } - if (udd_g_ctrlreq.req.wIndex & 0xFF) { - break; - } - // Unconfigure the device, terminating all ongoing requests - udc_reset(); - switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { - case USB_DEV_TEST_MODE_J: - udd_g_ctrlreq.callback = udd_test_mode_j; - return true; - - case USB_DEV_TEST_MODE_K: - udd_g_ctrlreq.callback = udd_test_mode_k; - return true; - - case USB_DEV_TEST_MODE_SE0_NAK: - udd_g_ctrlreq.callback = udd_test_mode_se0_nak; - return true; - - case USB_DEV_TEST_MODE_PACKET: - udd_g_ctrlreq.callback = udd_test_mode_packet; - return true; - - case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports - default: - break; - } - break; -#endif - default: - break; - } - return false; -} - -/** - * \brief Standard endpoint request to halt an endpoint - * - * \return true if success - */ -#if (0!=USB_DEVICE_MAX_EP) -static bool udc_req_std_ep_set_feature(void) -{ - if (udd_g_ctrlreq.req.wLength) { - return false; - } - if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { - udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); - return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); - } - return false; -} -#endif - -/** - * \brief Change the address of device - * Callback called at the end of request set address - */ -static void udc_valid_address(void) -{ - udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); -} - -/** - * \brief Standard device request to set device address - * - * \return true if success - */ -static bool udc_req_std_dev_set_address(void) -{ - if (udd_g_ctrlreq.req.wLength) { - return false; - } - - // The address must be changed at the end of setup request after the handshake - // then we use a callback to change address - udd_g_ctrlreq.callback = udc_valid_address; - return true; -} - -/** - * \brief Standard device request to get device string descriptor - * - * \return true if success - */ -static bool udc_req_std_dev_get_str_desc(void) -{ - uint8_t i; - const uint8_t *str; - uint8_t str_length = 0; - - // Link payload pointer to the string corresponding at request - switch (udd_g_ctrlreq.req.wValue & 0xFF) { - case 0: - udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, - sizeof(udc_string_desc_languageid)); - break; - -#ifdef USB_DEVICE_MANUFACTURE_NAME - case 1: - str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; - str = udc_string_manufacturer_name; - break; -#endif -#ifdef USB_DEVICE_PRODUCT_NAME - case 2: - str_length = USB_DEVICE_PRODUCT_NAME_SIZE; - str = udc_string_product_name; - break; -#endif -#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER - case 3: - str_length = USB_DEVICE_SERIAL_NAME_SIZE; - str = udc_get_string_serial_name(); - break; -#endif - default: -#ifdef UDC_GET_EXTRA_STRING - if (UDC_GET_EXTRA_STRING()) { - break; - } -#endif - return false; - } - - if (str_length) { - for(i = 0; i < str_length; i++) { - udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); - } - - udc_string_desc.header.bLength = 2 + (str_length) * 2; - udd_set_setup_payload( - (uint8_t *) &udc_string_desc, - udc_string_desc.header.bLength); - } - - return true; -} - -/** - * \brief Standard device request to get descriptors about USB device - * - * \return true if success - */ -static bool udc_req_std_dev_get_descriptor(void) -{ - uint8_t conf_num; - - conf_num = udd_g_ctrlreq.req.wValue & 0xFF; - - // Check descriptor ID - switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { - case USB_DT_DEVICE: - // Device descriptor requested -#ifdef USB_DEVICE_HS_SUPPORT - if (!udd_is_high_speed()) { - udd_set_setup_payload( - (uint8_t *) udc_config.confdev_hs, - udc_config.confdev_hs->bLength); - } else -#endif - { - udd_set_setup_payload( - (uint8_t *) udc_config.confdev_lsfs, - udc_config.confdev_lsfs->bLength); - } - break; - - case USB_DT_CONFIGURATION: - // Configuration descriptor requested -#ifdef USB_DEVICE_HS_SUPPORT - if (udd_is_high_speed()) { - // HS descriptor - if (conf_num >= udc_config.confdev_hs-> - bNumConfigurations) { - return false; - } - udd_set_setup_payload( - (uint8_t *)udc_config.conf_hs[conf_num].desc, - le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); - } else -#endif - { - // FS descriptor - if (conf_num >= udc_config.confdev_lsfs-> - bNumConfigurations) { - return false; - } - udd_set_setup_payload( - (uint8_t *)udc_config.conf_lsfs[conf_num].desc, - le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); - } - ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = - USB_DT_CONFIGURATION; - break; - -#ifdef USB_DEVICE_HS_SUPPORT - case USB_DT_DEVICE_QUALIFIER: - // Device qualifier descriptor requested - udd_set_setup_payload( (uint8_t *) udc_config.qualifier, - udc_config.qualifier->bLength); - break; - - case USB_DT_OTHER_SPEED_CONFIGURATION: - // Other configuration descriptor requested - if (!udd_is_high_speed()) { - // HS descriptor - if (conf_num >= udc_config.confdev_hs-> - bNumConfigurations) { - return false; - } - udd_set_setup_payload( - (uint8_t *)udc_config.conf_hs[conf_num].desc, - le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); - } else { - // FS descriptor - if (conf_num >= udc_config.confdev_lsfs-> - bNumConfigurations) { - return false; - } - udd_set_setup_payload( - (uint8_t *)udc_config.conf_lsfs[conf_num].desc, - le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); - } - ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = - USB_DT_OTHER_SPEED_CONFIGURATION; - break; -#endif - - case USB_DT_BOS: - // Device BOS descriptor requested - if (udc_config.conf_bos == NULL) { - return false; - } - udd_set_setup_payload( (uint8_t *) udc_config.conf_bos, - udc_config.conf_bos->wTotalLength); - break; - - case USB_DT_STRING: - // String descriptor requested - if (!udc_req_std_dev_get_str_desc()) { - return false; - } - break; - - default: - // Unknown descriptor requested - return false; - } - // if the descriptor is larger than length requested, then reduce it - if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { - udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; - } - return true; -} - -/** - * \brief Standard device request to get configuration number - * - * \return true if success - */ -static bool udc_req_std_dev_get_configuration(void) -{ - if (udd_g_ctrlreq.req.wLength != 1) { - return false; - } - - udd_set_setup_payload(&udc_num_configuration,1); - return true; -} - -/** - * \brief Standard device request to enable a configuration - * - * \return true if success - */ -static bool udc_req_std_dev_set_configuration(void) -{ - uint8_t iface_num; - - // Check request length - if (udd_g_ctrlreq.req.wLength) { - return false; - } - // Authorize configuration only if the address is valid - if (!udd_getaddress()) { - return false; - } - // Check the configuration number requested -#ifdef USB_DEVICE_HS_SUPPORT - if (udd_is_high_speed()) { - // HS descriptor - if ((udd_g_ctrlreq.req.wValue & 0xFF) > - udc_config.confdev_hs->bNumConfigurations) { - return false; - } - } else -#endif - { - // FS descriptor - if ((udd_g_ctrlreq.req.wValue & 0xFF) > - udc_config.confdev_lsfs->bNumConfigurations) { - return false; - } - } - - // Reset current configuration - udc_reset(); - - // Enable new configuration - udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; - if (udc_num_configuration == 0) { - return true; // Default empty configuration requested - } - // Update pointer of the configuration descriptor -#ifdef USB_DEVICE_HS_SUPPORT - if (udd_is_high_speed()) { - // HS descriptor - udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; - } else -#endif - { - // FS descriptor - udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; - } - // Enable all interfaces of the selected configuration - for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; - iface_num++) { - if (!udc_iface_enable(iface_num, 0)) { - return false; - } - } - return true; -} - -/** - * \brief Standard interface request - * to get the alternate setting number of an interface - * - * \return true if success - */ -static bool udc_req_std_iface_get_setting(void) -{ - uint8_t iface_num; - udi_api_t UDC_DESC_STORAGE *udi_api; - - if (udd_g_ctrlreq.req.wLength != 1) { - return false; // Error in request - } - if (!udc_num_configuration) { - return false; // The device is not is configured state yet - } - - // Check the interface number included in the request - iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; - if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { - return false; - } - - // Select first alternate setting of the interface to update udc_ptr_iface - // before call iface->getsetting() - if (!udc_update_iface_desc(iface_num, 0)) { - return false; - } - // Get alternate setting from UDI - udi_api = udc_ptr_conf->udi_apis[iface_num]; - udc_iface_setting = udi_api->getsetting(); - - // Link value to payload pointer of request - udd_set_setup_payload(&udc_iface_setting,1); - return true; -} - -/** - * \brief Standard interface request - * to set an alternate setting of an interface - * - * \return true if success - */ -static bool udc_req_std_iface_set_setting(void) -{ - uint8_t iface_num, setting_num; - - if (udd_g_ctrlreq.req.wLength) { - return false; // Error in request - } - if (!udc_num_configuration) { - return false; // The device is not is configured state yet - } - - iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; - setting_num = udd_g_ctrlreq.req.wValue & 0xFF; - - // Disable current setting - if (!udc_iface_disable(iface_num)) { - return false; - } - - // Enable new setting - return udc_iface_enable(iface_num, setting_num); -} - -/** - * \brief Main routine to manage the standard USB SETUP request - * - * \return true if the request is supported - */ -static bool udc_reqstd(void) -{ - if (Udd_setup_is_in()) { - // GET Standard Requests - if (udd_g_ctrlreq.req.wLength == 0) { - return false; // Error for USB host - } - - if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { - // Standard Get Device request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_GET_STATUS: - return udc_req_std_dev_get_status(); - case USB_REQ_GET_DESCRIPTOR: - return udc_req_std_dev_get_descriptor(); - case USB_REQ_GET_CONFIGURATION: - return udc_req_std_dev_get_configuration(); - default: - break; - } - } - - if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { - // Standard Get Interface request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_GET_INTERFACE: - return udc_req_std_iface_get_setting(); - default: - break; - } - } -#if (0!=USB_DEVICE_MAX_EP) - if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { - // Standard Get Endpoint request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_GET_STATUS: - return udc_req_std_ep_get_status(); - default: - break; - } - } -#endif - } else { - // SET Standard Requests - if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { - // Standard Set Device request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_SET_ADDRESS: - return udc_req_std_dev_set_address(); - case USB_REQ_CLEAR_FEATURE: - return udc_req_std_dev_clear_feature(); - case USB_REQ_SET_FEATURE: - return udc_req_std_dev_set_feature(); - case USB_REQ_SET_CONFIGURATION: - return udc_req_std_dev_set_configuration(); - case USB_REQ_SET_DESCRIPTOR: - /* Not supported (defined as optional by the USB 2.0 spec) */ - break; - default: - break; - } - } - - if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { - // Standard Set Interface request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_SET_INTERFACE: - return udc_req_std_iface_set_setting(); - default: - break; - } - } -#if (0!=USB_DEVICE_MAX_EP) - if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { - // Standard Set Endpoint request - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_CLEAR_FEATURE: - return udc_req_std_ep_clear_feature(); - case USB_REQ_SET_FEATURE: - return udc_req_std_ep_set_feature(); - default: - break; - } - } -#endif - } - return false; -} - -/** - * \brief Send the SETUP interface request to UDI - * - * \return true if the request is supported - */ -static bool udc_req_iface(void) -{ - uint8_t iface_num; - udi_api_t UDC_DESC_STORAGE *udi_api; - - if (0 == udc_num_configuration) { - return false; // The device is not is configured state yet - } - // Check interface number - iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; - if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { - return false; - } - - //* To update udc_ptr_iface with the selected interface in request - // Select first alternate setting of interface to update udc_ptr_iface - // before calling udi_api->getsetting() - if (!udc_update_iface_desc(iface_num, 0)) { - return false; - } - // Select the interface with the current alternate setting - udi_api = udc_ptr_conf->udi_apis[iface_num]; - if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { - return false; - } - - // Send the SETUP request to the UDI corresponding to the interface number - return udi_api->setup(); -} - -/** - * \brief Send the SETUP interface request to UDI - * - * \return true if the request is supported - */ -static bool udc_req_ep(void) -{ - uint8_t iface_num; - udi_api_t UDC_DESC_STORAGE *udi_api; - - if (0 == udc_num_configuration) { - return false; // The device is not is configured state yet - } - // Send this request on all enabled interfaces - iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; - for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; - iface_num++) { - // Select the interface with the current alternate setting - udi_api = udc_ptr_conf->udi_apis[iface_num]; - if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { - return false; - } - - // Send the SETUP request to the UDI - if (udi_api->setup()) { - return true; - } - } - return false; -} - -/** - * \brief Main routine to manage the USB SETUP request. - * - * This function parses a USB SETUP request and submits an appropriate - * response back to the host or, in the case of SETUP OUT requests - * with data, sets up a buffer for receiving the data payload. - * - * The main standard requests defined by the USB 2.0 standard are handled - * internally. The interface requests are sent to UDI, and the specific request - * sent to a specific application callback. - * - * \return true if the request is supported, else the request is stalled by UDD - */ -bool udc_process_setup(void) -{ - // By default no data (receive/send) and no callbacks registered - udd_g_ctrlreq.payload_size = 0; - udd_g_ctrlreq.callback = NULL; - udd_g_ctrlreq.over_under_run = NULL; - - if (Udd_setup_is_in()) { - if (udd_g_ctrlreq.req.wLength == 0) { - return false; // Error from USB host - } - } - - // If standard request then try to decode it in UDC - if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { - if (udc_reqstd()) { - return true; - } - } - - // If interface request then try to decode it in UDI - if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { - if (udc_req_iface()) { - return true; - } - } - - // If endpoint request then try to decode it in UDI - if (Udd_setup_recipient() == USB_REQ_RECIP_ENDPOINT) { - if (udc_req_ep()) { - return true; - } - } - - // Here SETUP request unknown by UDC and UDIs -#ifdef USB_DEVICE_SPECIFIC_REQUEST - // Try to decode it in specific callback - return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... -#else - return false; -#endif -} - -//! @} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/udc.h b/src/HAL/DUE/usb/udc.h deleted file mode 100644 index 8d92eb5..0000000 --- a/src/HAL/DUE/usb/udc.h +++ /dev/null @@ -1,697 +0,0 @@ -/** - * \file - * - * \brief Interface of the USB Device Controller (UDC) - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDC_H_ -#define _UDC_H_ - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "udc_desc.h" -#include "udd.h" - -#if USB_DEVICE_VENDOR_ID == 0 -# error USB_DEVICE_VENDOR_ID cannot be equal to 0 -#endif - -#if USB_DEVICE_PRODUCT_ID == 0 -# error USB_DEVICE_PRODUCT_ID cannot be equal to 0 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \ingroup usb_device_group - * \defgroup udc_group USB Device Controller (UDC) - * - * The UDC provides a high-level abstraction of the usb device. - * You can use these functions to control the main device state - * (start/attach/wakeup). - * - * \section USB_DEVICE_CONF USB Device Custom configuration - * The following USB Device configuration must be included in the conf_usb.h - * file of the application. - * - * USB_DEVICE_VENDOR_ID (Word)
- * Vendor ID provided by USB org (ATMEL 0x03EB). - * - * USB_DEVICE_PRODUCT_ID (Word)
- * Product ID (Referenced in usb_atmel.h). - * - * USB_DEVICE_MAJOR_VERSION (Byte)
- * Major version of the device - * - * USB_DEVICE_MINOR_VERSION (Byte)
- * Minor version of the device - * - * USB_DEVICE_MANUFACTURE_NAME (string)
- * ASCII name for the manufacture - * - * USB_DEVICE_PRODUCT_NAME (string)
- * ASCII name for the product - * - * USB_DEVICE_SERIAL_NAME (string)
- * ASCII name to enable and set a serial number - * - * USB_DEVICE_POWER (Numeric)
- * (unit mA) Maximum device power - * - * USB_DEVICE_ATTR (Byte)
- * USB attributes available: - * - USB_CONFIG_ATTR_SELF_POWERED - * - USB_CONFIG_ATTR_REMOTE_WAKEUP - * Note: if remote wake enabled then defines remotewakeup callbacks, - * see Table 5-2. External API from UDC - Callback - * - * USB_DEVICE_LOW_SPEED (Only defined)
- * Force the USB Device to run in low speed - * - * USB_DEVICE_HS_SUPPORT (Only defined)
- * Authorize the USB Device to run in high speed - * - * USB_DEVICE_MAX_EP (Byte)
- * Define the maximum endpoint number used by the USB Device.
- * This one is already defined in UDI default configuration. - * Ex: - * - When endpoint control 0x00, endpoint 0x01 and - * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 - * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 - * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
- * (configuration not possible on USBB interface) - * @{ - */ - -/** - * \brief Authorizes the VBUS event - * - * \return true, if the VBUS monitoring is possible. - * - * \section udc_vbus_monitoring VBus monitoring used cases - * - * The VBus monitoring is used only for USB SELF Power application. - * - * - By default the USB device is automatically attached when Vbus is high - * or when USB is start for devices without internal Vbus monitoring. - * conf_usb.h file does not contains define USB_DEVICE_ATTACH_AUTO_DISABLE. - * \code //#define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode - * - * - Add custom VBUS monitoring. conf_usb.h file contains define - * USB_DEVICE_ATTACH_AUTO_DISABLE: - * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode - * User C file contains: - * \code - // Authorize VBUS monitoring - if (!udc_include_vbus_monitoring()) { - // Implement custom VBUS monitoring via GPIO or other - } - Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other - { - // Attach USB Device - udc_attach(); - } -\endcode - * - * - Case of battery charging. conf_usb.h file contains define - * USB_DEVICE_ATTACH_AUTO_DISABLE: - * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode - * User C file contains: - * \code - Event VBUS present() // VBUS interrupt or GPIO interrupt or .. - { - // Authorize battery charging, but wait key press to start USB. - } - Event Key press() - { - // Stop batteries charging - // Start USB - udc_attach(); - } -\endcode - */ -static inline bool udc_include_vbus_monitoring(void) -{ - return udd_include_vbus_monitoring(); -} - -/*! \brief Start the USB Device stack - */ -void udc_start(void); - -/*! \brief Stop the USB Device stack - */ -void udc_stop(void); - -/** - * \brief Attach device to the bus when possible - * - * \warning If a VBus control is included in driver, - * then it will attach device when an acceptable Vbus - * level from the host is detected. - */ -static inline void udc_attach(void) -{ - udd_attach(); -} - - -/** - * \brief Detaches the device from the bus - * - * The driver must remove pull-up on USB line D- or D+. - */ -static inline void udc_detach(void) -{ - udd_detach(); -} - - -/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" - * This is authorized only when the remote wakeup feature is enabled by host. - */ -static inline void udc_remotewakeup(void) -{ - udd_send_remotewakeup(); -} - - -/** - * \brief Returns a pointer on the current interface descriptor - * - * \return pointer on the current interface descriptor. - */ -usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); - -//@} - -/** - * \ingroup usb_group - * \defgroup usb_device_group USB Stack Device - * - * This module includes USB Stack Device implementation. - * The stack is divided in three parts: - * - USB Device Controller (UDC) provides USB chapter 9 compliance - * - USB Device Interface (UDI) provides USB Class compliance - * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU - - * Many USB Device applications can be implemented on Atmel MCU. - * Atmel provides many application notes for different applications: - * - AVR4900, provides general information about Device Stack - * - AVR4901, explains how to create a new class - * - AVR4902, explains how to create a composite device - * - AVR49xx, all device classes provided in ASF have an application note - * - * A basic USB knowledge is required to understand the USB Device - * Class application notes (HID,MS,CDC,PHDC,...). - * Then, to create an USB device with - * only one class provided by ASF, refer directly to the application note - * corresponding to this USB class. The USB Device application note for - * New Class and Composite is dedicated to advanced USB users. - * - * @{ - */ - -//! @} - -#ifdef __cplusplus -} -#endif - -/** - * \ingroup udc_group - * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites - * Common prerequisites for all USB devices. - * - * This module is based on USB device stack full interrupt driven, and supporting - * \ref sleepmgr_group sleepmgr. For AVR and SAM3/4 devices the \ref clk_group clock services - * is supported. For SAMD devices the \ref asfdoc_sam0_system_clock_group clock driver is supported. - * - * The following procedure must be executed to setup the project correctly: - * - Specify the clock configuration: - * - XMEGA USB devices need 48MHz clock input.\n - * XMEGA USB devices need CPU frequency higher than 12MHz.\n - * You can use either an internal RC48MHz auto calibrated by Start of Frames - * or an external OSC. - * - UC3 and SAM3/4 devices without USB high speed support need 48MHz clock input.\n - * You must use a PLL and an external OSC. - * - UC3 and SAM3/4 devices with USB high speed support need 12MHz clock input.\n - * You must use an external OSC. - * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. - * - SAMD devices without USB high speed support need 48MHz clock input.\n - * You should use DFLL with USBCRM. - * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. - * (Not mandatory for all boards) - * - Enable interrupts - * - Initialize the clock service - * - * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power - * consumption: - * - Initialize the sleep manager service - * - Activate sleep mode when the application is in IDLE state - * - * \subpage udc_conf_clock. - * - * for AVR and SAM3/4 devices, add to the initialization code: - * \code - sysclk_init(); - irq_initialize_vectors(); - cpu_irq_enable(); - board_init(); - sleepmgr_init(); // Optional -\endcode - * - * For SAMD devices, add to the initialization code: - * \code - system_init(); - irq_initialize_vectors(); - cpu_irq_enable(); - sleepmgr_init(); // Optional -\endcode - * Add to the main IDLE loop: - * \code - sleepmgr_enter_sleep(); // Optional -\endcode - * - */ - -/** - * \ingroup udc_group - * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code - * Common example code for all USB devices. - * - * Content of conf_usb.h: - * \code - #define USB_DEVICE_VENDOR_ID 0x03EB - #define USB_DEVICE_PRODUCT_ID 0xXXXX - #define USB_DEVICE_MAJOR_VERSION 1 - #define USB_DEVICE_MINOR_VERSION 0 - #define USB_DEVICE_POWER 100 - #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED -\endcode - * - * Add to application C-file: - * \code - void usb_init(void) - { - udc_start(); - } -\endcode - */ - -/** - * \ingroup udc_group - * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow - * Common workflow for all USB devices. - * - * -# Ensure that conf_usb.h is available and contains the following configuration - * which is the main USB device configuration: - * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) - #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word - // Product ID (Atmel PID referenced in usb_atmel.h) - #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word - // Major version of the device - #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte - // Minor version of the device - #define USB_DEVICE_MINOR_VERSION 0 // Type Byte - // Maximum device power (mA) - #define USB_DEVICE_POWER 100 // Type 9-bits - // USB attributes to enable features - #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode - * -# Call the USB device stack start function to enable stack and start USB: - * - \code udc_start(); \endcode - * \note In case of USB dual roles (Device and Host) managed through USB OTG connector - * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). - * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. - */ - -/** - * \page udc_conf_clock conf_clock.h examples with USB support - * - * Content of XMEGA conf_clock.h: - * \code - // Configuration based on internal RC: - // USB clock need of 48Mhz - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC - #define CONFIG_OSC_RC32_CAL 48000000UL - #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF - // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) - #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ - #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 - #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 -\endcode - * - * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): - * \code - // Configuration based on 12MHz external OSC: - #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 - #define CONFIG_PLL1_MUL 8 - #define CONFIG_PLL1_DIV 2 - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 - #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) -\endcode - * - * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): - * \code - // Configuration based on 12MHz external OSC: - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 - #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) -\endcode - * - * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): - * \code - // Configuration based on 12MHz external OSC: - #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 - #define CONFIG_PLL1_MUL 8 - #define CONFIG_PLL1_DIV 2 - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 - #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) - // CPU clock need of clock > 25MHz to run with USBC - #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 -\endcode - * - * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): - * \code - // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) - #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL - #define CONFIG_PLL1_MUL 16 - #define CONFIG_PLL1_DIV 2 - // USB Clock Source Options (Fusb = FpllX / USB_div) - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 - #define CONFIG_USBCLK_DIV 2 -\endcode - * - * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): - * \code - // USB Clock Source fixed at UPLL. -\endcode - * - * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): - * \code - // USB Clock Source fixed at UPLL. - #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL - #define CONFIG_USBCLK_DIV 1 -\endcode - * - * Content of conf_clocks.h for SAMD devices (USB): - * \code - // System clock bus configuration - # define CONF_CLOCK_FLASH_WAIT_STATES 2 - - // USB Clock Source fixed at DFLL. - // SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop - # define CONF_CLOCK_DFLL_ENABLE true - # define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY - # define CONF_CLOCK_DFLL_ON_DEMAND true - - // Set this to true to configure the GCLK when running clocks_init. - // If set to false, none of the GCLK generators will be configured in clocks_init(). - # define CONF_CLOCK_CONFIGURE_GCLK true - - // Configure GCLK generator 0 (Main Clock) - # define CONF_CLOCK_GCLK_0_ENABLE true - # define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true - # define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL - # define CONF_CLOCK_GCLK_0_PRESCALER 1 - # define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false -\endcode - */ - -/** - * \page udc_use_case_1 Change USB speed - * - * In this use case, the USB device is used with different USB speeds. - * - * \section udc_use_case_1_setup Setup steps - * - * Prior to implement this use case, be sure to have already - * apply the UDI module "basic use case". - * - * \section udc_use_case_1_usage Usage steps - * - * \subsection udc_use_case_1_usage_code Example code - * Content of conf_usb.h: - * \code - #if // Low speed - #define USB_DEVICE_LOW_SPEED - // #define USB_DEVICE_HS_SUPPORT - - #elif // Full speed - // #define USB_DEVICE_LOW_SPEED - // #define USB_DEVICE_HS_SUPPORT - - #elif // High speed - // #define USB_DEVICE_LOW_SPEED - #define USB_DEVICE_HS_SUPPORT - - #endif -\endcode - * - * \subsection udc_use_case_1_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required for a USB device low speed (1.5Mbit/s): - * - \code #define USB_DEVICE_LOW_SPEED - //#define USB_DEVICE_HS_SUPPORT \endcode - * -# Ensure that conf_usb.h contains the following parameters - * required for a USB device full speed (12Mbit/s): - * - \code //#define USB_DEVICE_LOW_SPEED - //#define USB_DEVICE_HS_SUPPORT \endcode - * -# Ensure that conf_usb.h contains the following parameters - * required for a USB device high speed (480Mbit/s): - * - \code //#define USB_DEVICE_LOW_SPEED - #define USB_DEVICE_HS_SUPPORT \endcode - */ - -/** - * \page udc_use_case_2 Use USB strings - * - * In this use case, the usual USB strings is added in the USB device. - * - * \section udc_use_case_2_setup Setup steps - * Prior to implement this use case, be sure to have already - * apply the UDI module "basic use case". - * - * \section udc_use_case_2_usage Usage steps - * - * \subsection udc_use_case_2_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" - #define USB_DEVICE_PRODUCT_NAME "Product name" - #define USB_DEVICE_SERIAL_NAME "12...EF" -\endcode - * - * \subsection udc_use_case_2_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required to enable different USB strings: - * - \code // Static ASCII name for the manufacture - #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode - * - \code // Static ASCII name for the product - #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode - * - \code // Static ASCII name to enable and set a serial number - #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode - */ - -/** - * \page udc_use_case_3 Use USB remote wakeup feature - * - * In this use case, the USB remote wakeup feature is enabled. - * - * \section udc_use_case_3_setup Setup steps - * Prior to implement this use case, be sure to have already - * apply the UDI module "basic use case". - * - * \section udc_use_case_3_usage Usage steps - * - * \subsection udc_use_case_3_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_ATTR \ - (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) - #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() - extern void my_callback_remotewakeup_enable(void); - #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() - extern void my_callback_remotewakeup_disable(void); -\endcode - * - * Add to application C-file: - * \code - void my_callback_remotewakeup_enable(void) - { - // Enable application wakeup events (e.g. enable GPIO interrupt) - } - void my_callback_remotewakeup_disable(void) - { - // Disable application wakeup events (e.g. disable GPIO interrupt) - } - - void my_interrupt_event(void) - { - udc_remotewakeup(); - } -\endcode - * - * \subsection udc_use_case_3_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required to enable remote wakeup feature: - * - \code // Authorizes the remote wakeup feature - #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode - * - \code // Define callback called when the host enables the remotewakeup feature - #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() - extern void my_callback_remotewakeup_enable(void); \endcode - * - \code // Define callback called when the host disables the remotewakeup feature - #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() - extern void my_callback_remotewakeup_disable(void); \endcode - * -# Send a remote wakeup (USB upstream): - * - \code udc_remotewakeup(); \endcode - */ - -/** - * \page udc_use_case_5 Bus power application recommendations - * - * In this use case, the USB device BUS power feature is enabled. - * This feature requires a correct power consumption management. - * - * \section udc_use_case_5_setup Setup steps - * Prior to implement this use case, be sure to have already - * apply the UDI module "basic use case". - * - * \section udc_use_case_5_usage Usage steps - * - * \subsection udc_use_case_5_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) - #define UDC_SUSPEND_EVENT() user_callback_suspend_action() - extern void user_callback_suspend_action(void) - #define UDC_RESUME_EVENT() user_callback_resume_action() - extern void user_callback_resume_action(void) -\endcode - * - * Add to application C-file: - * \code - void user_callback_suspend_action(void) - { - // Disable hardware component to reduce power consumption - } - void user_callback_resume_action(void) - { - // Re-enable hardware component - } -\endcode - * - * \subsection udc_use_case_5_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters: - * - \code // Authorizes the BUS power feature - #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode - * - \code // Define callback called when the host suspend the USB line - #define UDC_SUSPEND_EVENT() user_callback_suspend_action() - extern void user_callback_suspend_action(void); \endcode - * - \code // Define callback called when the host or device resume the USB line - #define UDC_RESUME_EVENT() user_callback_resume_action() - extern void user_callback_resume_action(void); \endcode - * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): - * - \code void user_callback_suspend_action(void) - { - turn_off_components(); - } \endcode - */ - -/** - * \page udc_use_case_6 USB dynamic serial number - * - * In this use case, the USB serial strings is dynamic. - * For a static serial string refer to \ref udc_use_case_2. - * - * \section udc_use_case_6_setup Setup steps - * Prior to implement this use case, be sure to have already - * apply the UDI module "basic use case". - * - * \section udc_use_case_6_usage Usage steps - * - * \subsection udc_use_case_6_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_SERIAL_NAME - #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number - #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 - extern uint8_t serial_number[]; -\endcode - * - * Add to application C-file: - * \code - uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; - - void init_build_usb_serial_number(void) - { - serial_number[0] = 'A'; - serial_number[1] = 'B'; - ... - serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; - } \endcode - * - * \subsection udc_use_case_6_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required to enable a USB serial number strings dynamically: - * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty - #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer - #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array - extern uint8_t serial_number[]; // Declare external serial array \endcode - * -# Before start USB stack, initialize the serial array - * - \code - uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; - - void init_build_usb_serial_number(void) - { - serial_number[0] = 'A'; - serial_number[1] = 'B'; - ... - serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; - } \endcode - */ - - - -#endif // _UDC_H_ diff --git a/src/HAL/DUE/usb/udc_desc.h b/src/HAL/DUE/usb/udc_desc.h deleted file mode 100644 index 052ca08..0000000 --- a/src/HAL/DUE/usb/udc_desc.h +++ /dev/null @@ -1,135 +0,0 @@ -/** - * \file - * - * \brief Common API for USB Device Interface - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDC_DESC_H_ -#define _UDC_DESC_H_ - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "udi.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \ingroup udc_group - * \defgroup udc_desc_group USB Device Descriptor - * - * @{ - */ - -/** - * \brief Defines the memory's location of USB descriptors - * - * By default the Descriptor is stored in RAM - * (UDC_DESC_STORAGE is defined empty). - * - * If you have need to free RAM space, - * it is possible to put descriptor in flash in following case: - * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) - * - USB Device is not high speed (UDC no need to change USB descriptors) - * - * For UC3 application used "const". - * - * For Mega application used "code". - */ -#define UDC_DESC_STORAGE - // Descriptor storage in internal RAM -#if (defined UDC_DATA_USE_HRAM_SUPPORT) -# if defined(__GNUC__) -# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) -# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) -# elif defined(__ICCAVR32__) -# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 -# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 -# endif -#else -# define UDC_DATA(x) COMPILER_ALIGNED(x) -# define UDC_BSS(x) COMPILER_ALIGNED(x) -#endif - - - -/** - * \brief Configuration descriptor and UDI link for one USB speed - */ -typedef struct { - //! USB configuration descriptor - usb_conf_desc_t UDC_DESC_STORAGE *desc; - //! Array of UDI API pointer - udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; -} udc_config_speed_t; - - -/** - * \brief All information about the USB Device - */ -typedef struct { - //! USB device descriptor for low or full speed - usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; - //! USB configuration descriptor and UDI API pointers for low or full speed - udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; -#ifdef USB_DEVICE_HS_SUPPORT - //! USB device descriptor for high speed - usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; - //! USB device qualifier, only use in high speed mode - usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; - //! USB configuration descriptor and UDI API pointers for high speed - udc_config_speed_t UDC_DESC_STORAGE *conf_hs; -#endif - usb_dev_bos_desc_t UDC_DESC_STORAGE *conf_bos; -} udc_config_t; - -//! Global variables of USB Device Descriptor and UDI links -extern UDC_DESC_STORAGE udc_config_t udc_config; - -//@} - -#ifdef __cplusplus -} -#endif -#endif // _UDC_DESC_H_ diff --git a/src/HAL/DUE/usb/udd.h b/src/HAL/DUE/usb/udd.h deleted file mode 100644 index 319d884..0000000 --- a/src/HAL/DUE/usb/udd.h +++ /dev/null @@ -1,396 +0,0 @@ -/** - * \file - * - * \brief Common API for USB Device Drivers (UDD) - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDD_H_ -#define _UDD_H_ - -#include "usb_protocol.h" -#include "udc_desc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \ingroup usb_device_group - * \defgroup udd_group USB Device Driver (UDD) - * - * The UDD driver provides a low-level abstraction of the device - * controller hardware. Most events coming from the hardware such as - * interrupts, which may cause the UDD to call into the UDC and UDI. - * - * @{ - */ - -//! \brief Endpoint identifier -typedef uint8_t udd_ep_id_t; - -//! \brief Endpoint transfer status -//! Returned in parameters of callback register via udd_ep_run routine. -typedef enum { - UDD_EP_TRANSFER_OK = 0, - UDD_EP_TRANSFER_ABORT = 1, -} udd_ep_status_t; - -/** - * \brief Global variable to give and record information of the setup request management - * - * This global variable allows to decode and response a setup request. - * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. - */ -typedef struct { - //! Data received in USB SETUP packet - //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. - usb_setup_req_t req; - - //! Point to buffer to send or fill with data following SETUP packet - //! This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer) - uint8_t *payload; - - //! Size of buffer to send or fill, and content the number of byte transferred - uint16_t payload_size; - - //! Callback called after reception of ZLP from setup request - void (*callback)(void); - - //! Callback called when the buffer given (.payload) is full or empty. - //! This one return false to abort data transfer, or true with a new buffer in .payload. - bool (*over_under_run)(void); -} udd_ctrl_request_t; -extern udd_ctrl_request_t udd_g_ctrlreq; - -//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer -#define Udd_setup_is_in() \ - (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) - -//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer -#define Udd_setup_is_out() \ - (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) - -//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. -#define Udd_setup_type() \ - (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) - -//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient -#define Udd_setup_recipient() \ - (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) - -/** - * \brief End of halt callback function type. - * Registered by routine udd_ep_wait_stall_clear() - * Callback called when endpoint stall is cleared. - */ -typedef void (*udd_callback_halt_cleared_t)(void); - -/** - * \brief End of transfer callback function type. - * Registered by routine udd_ep_run() - * Callback called by USB interrupt after data transfer or abort (reset,...). - * - * \param status UDD_EP_TRANSFER_OK, if transfer is complete - * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted - * \param n number of data transferred - */ -typedef void (*udd_callback_trans_t) (udd_ep_status_t status, - iram_size_t nb_transferred, udd_ep_id_t ep); - -/** - * \brief Authorizes the VBUS event - * - * \return true, if the VBUS monitoring is possible. - */ -bool udd_include_vbus_monitoring(void); - -/** - * \brief Enables the USB Device mode - */ -void udd_enable(void); - -/** - * \brief Disables the USB Device mode - */ -void udd_disable(void); - -/** - * \brief Attach device to the bus when possible - * - * \warning If a VBus control is included in driver, - * then it will attach device when an acceptable Vbus - * level from the host is detected. - */ -void udd_attach(void); - -/** - * \brief Detaches the device from the bus - * - * The driver must remove pull-up on USB line D- or D+. - */ -void udd_detach(void); - -/** - * \brief Test whether the USB Device Controller is running at high - * speed or not. - * - * \return \c true if the Device is running at high speed mode, otherwise \c false. - */ -bool udd_is_high_speed(void); - -/** - * \brief Changes the USB address of device - * - * \param address New USB address - */ -void udd_set_address(uint8_t address); - -/** - * \brief Returns the USB address of device - * - * \return USB address - */ -uint8_t udd_getaddress(void); - -/** - * \brief Returns the current start of frame number - * - * \return current start of frame number. - */ -uint16_t udd_get_frame_number(void); - -/** - * \brief Returns the current micro start of frame number - * - * \return current micro start of frame number required in high speed mode. - */ -uint16_t udd_get_micro_frame_number(void); - -/*! \brief The USB driver sends a resume signal called Upstream Resume - */ -void udd_send_remotewakeup(void); - -/** - * \brief Load setup payload - * - * \param payload Pointer on payload - * \param payload_size Size of payload - */ -void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); - - -/** - * \name Endpoint Management - * - * The following functions allow drivers to create and remove - * endpoints, as well as set, clear and query their "halted" and - * "wedged" states. - */ -//@{ - -#if (USB_DEVICE_MAX_EP != 0) - -/** - * \brief Configures and enables an endpoint - * - * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). - * \param bmAttributes Attributes of endpoint declared in the descriptor. - * \param MaxEndpointSize Endpoint maximum size - * - * \return \c 1 if the endpoint is enabled, otherwise \c 0. - */ -bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, - uint16_t MaxEndpointSize); - -/** - * \brief Disables an endpoint - * - * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). - */ -void udd_ep_free(udd_ep_id_t ep); - -/** - * \brief Check if the endpoint \a ep is halted. - * - * \param ep The ID of the endpoint to check. - * - * \return \c 1 if \a ep is halted, otherwise \c 0. - */ -bool udd_ep_is_halted(udd_ep_id_t ep); - -/** - * \brief Set the halted state of the endpoint \a ep - * - * After calling this function, any transaction on \a ep will result - * in a STALL handshake being sent. Any pending transactions will be - * performed first, however. - * - * \param ep The ID of the endpoint to be halted - * - * \return \c 1 if \a ep is halted, otherwise \c 0. - */ -bool udd_ep_set_halt(udd_ep_id_t ep); - -/** - * \brief Clear the halted state of the endpoint \a ep - * - * After calling this function, any transaction on \a ep will - * be handled normally, i.e. a STALL handshake will not be sent, and - * the data toggle sequence will start at DATA0. - * - * \param ep The ID of the endpoint to be un-halted - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -bool udd_ep_clear_halt(udd_ep_id_t ep); - -/** - * \brief Registers a callback to call when endpoint halt is cleared - * - * \param ep The ID of the endpoint to use - * \param callback NULL or function to call when endpoint halt is cleared - * - * \warning if the endpoint is not halted then the \a callback is called immediately. - * - * \return \c 1 if the register is accepted, otherwise \c 0. - */ -bool udd_ep_wait_stall_clear(udd_ep_id_t ep, - udd_callback_halt_cleared_t callback); - -/** - * \brief Allows to receive or send data on an endpoint - * - * The driver uses a specific DMA USB to transfer data - * from internal RAM to endpoint, if this one is available. - * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. - * The \a callback returns the transfer status and eventually the number of byte transferred. - * Note: The control endpoint is not authorized. - * - * \param ep The ID of the endpoint to use - * \param b_shortpacket Enabled automatic short packet - * \param buf Buffer on Internal RAM to send or fill. - * It must be align, then use COMPILER_WORD_ALIGNED. - * \param buf_size Buffer size to send or fill - * \param callback NULL or function to call at the end of transfer - * - * \warning About \a b_shortpacket, for IN endpoint it means that a short packet - * (or a Zero Length Packet) will be sent to the USB line to properly close the usb - * transfer at the end of the data transfer. - * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer - * at the end of the data transfer (received short packet). - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, - uint8_t * buf, iram_size_t buf_size, - udd_callback_trans_t callback); -/** - * \brief Aborts transfer on going on endpoint - * - * If a transfer is on going, then it is stopped and - * the callback registered is called to signal the end of transfer. - * Note: The control endpoint is not authorized. - * - * \param ep Endpoint to abort - */ -void udd_ep_abort(udd_ep_id_t ep); - -#endif - -//@} - - -/** - * \name High speed test mode management - * - * The following functions allow the device to jump to a specific test mode required in high speed mode. - */ -//@{ -void udd_test_mode_j(void); -void udd_test_mode_k(void); -void udd_test_mode_se0_nak(void); -void udd_test_mode_packet(void); -//@} - - -/** - * \name UDC callbacks to provide for UDD - * - * The following callbacks are used by UDD. - */ -//@{ - -/** - * \brief Decodes and manages a setup request - * - * The driver call it when a SETUP packet is received. - * The \c udd_g_ctrlreq contains the data of SETUP packet. - * If this callback accepts the setup request then it must - * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. - * - * \return \c 1 if the request is accepted, otherwise \c 0. - */ -extern bool udc_process_setup(void); - -/** - * \brief Reset the UDC - * - * The UDC must reset all configuration. - */ -extern void udc_reset(void); - -/** - * \brief To signal that a SOF is occurred - * - * The UDC must send the signal to all UDIs enabled - */ -extern void udc_sof_notify(void); - -//@} - -//@} - -#ifdef __cplusplus -} -#endif -#endif // _UDD_H_ diff --git a/src/HAL/DUE/usb/udi.h b/src/HAL/DUE/usb/udi.h deleted file mode 100644 index febf03b..0000000 --- a/src/HAL/DUE/usb/udi.h +++ /dev/null @@ -1,133 +0,0 @@ -/** - * \file - * - * \brief Common API for USB Device Interface - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDI_H_ -#define _UDI_H_ - -#include "conf_usb.h" -#include "usb_protocol.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \ingroup usb_device_group - * \defgroup udi_group USB Device Interface (UDI) - * The UDI provides a common API for all classes, - * and this is used by UDC for the main control of USB Device interface. - * @{ - */ - -/** - * \brief UDI API. - * - * The callbacks within this structure are called only by - * USB Device Controller (UDC) - * - * The udc_get_interface_desc() can be use by UDI to know the interface descriptor - * selected by UDC. - */ -typedef struct { - /** - * \brief Enable the interface. - * - * This function is called when the host selects a configuration - * to which this interface belongs through a Set Configuration - * request, and when the host selects an alternate setting of - * this interface through a Set Interface request. - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ - bool (*enable)(void); - - /** - * \brief Disable the interface. - * - * This function is called when this interface is currently - * active, and - * - the host selects any configuration through a Set - * Configuration request, or - * - the host issues a USB reset, or - * - the device is detached from the host (i.e. Vbus is no - * longer present) - */ - void (*disable)(void); - - /** - * \brief Handle a control request directed at an interface. - * - * This function is called when this interface is currently - * active and the host sends a SETUP request - * with this interface as the recipient. - * - * Use udd_g_ctrlreq to decode and response to SETUP request. - * - * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. - */ - bool (*setup)(void); - - /** - * \brief Returns the current setting of the selected interface. - * - * This function is called when UDC when know alternate setting of selected interface. - * - * \return alternate setting of selected interface - */ - uint8_t (*getsetting)(void); - - /** - * \brief To signal that a SOF is occurred - */ - void (*sof_notify)(void); -} udi_api_t; - -//@} - -#ifdef __cplusplus -} -#endif -#endif // _UDI_H_ diff --git a/src/HAL/DUE/usb/udi_cdc.c b/src/HAL/DUE/usb/udi_cdc.c deleted file mode 100644 index 89debe5..0000000 --- a/src/HAL/DUE/usb/udi_cdc.c +++ /dev/null @@ -1,1155 +0,0 @@ -/** - * \file - * - * \brief USB Device Communication Device Class (CDC) interface. - * - * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "usb_protocol_cdc.h" -#include "udd.h" -#include "udc.h" -#include "udi_cdc.h" -#include - -#ifdef UDI_CDC_LOW_RATE -# ifdef USB_DEVICE_HS_SUPPORT -# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) -# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) -# else -# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) -# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE) -# endif -#else -# ifdef USB_DEVICE_HS_SUPPORT -# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) -# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE) -# else -# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) -# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE) -# endif -#endif - -#ifndef UDI_CDC_TX_EMPTY_NOTIFY -# define UDI_CDC_TX_EMPTY_NOTIFY(port) -#endif - -/** - * \ingroup udi_cdc_group - * \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC) - * - * Structures and functions required by UDC. - * - * @{ - */ -bool udi_cdc_comm_enable(void); -void udi_cdc_comm_disable(void); -bool udi_cdc_comm_setup(void); -bool udi_cdc_data_enable(void); -void udi_cdc_data_disable(void); -bool udi_cdc_data_setup(void); -uint8_t udi_cdc_getsetting(void); -void udi_cdc_data_sof_notify(void); -UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = { - .enable = udi_cdc_comm_enable, - .disable = udi_cdc_comm_disable, - .setup = udi_cdc_comm_setup, - .getsetting = udi_cdc_getsetting, -}; -UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = { - .enable = udi_cdc_data_enable, - .disable = udi_cdc_data_disable, - .setup = udi_cdc_data_setup, - .getsetting = udi_cdc_getsetting, - .sof_notify = udi_cdc_data_sof_notify, -}; -//@} - -/** - * \ingroup udi_cdc_group - * \defgroup udi_cdc_group_internal Implementation of UDI CDC - * - * Class internal implementation - * @{ - */ - -/** - * \name Internal routines - */ -//@{ - -/** - * \name Routines to control serial line - */ -//@{ - -/** - * \brief Returns the port number corresponding at current setup request - * - * \return port number - */ -static uint8_t udi_cdc_setup_to_port(void); - -/** - * \brief Sends line coding to application - * - * Called after SETUP request when line coding data is received. - */ -static void udi_cdc_line_coding_received(void); - -/** - * \brief Records new state - * - * \param port Communication port number to manage - * \param b_set State is enabled if true, else disabled - * \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines) - */ -static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask); - -/** - * \brief Check and eventually notify the USB host of new state - * - * \param port Communication port number to manage - * \param ep Port communication endpoint - */ -static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep); - -/** - * \brief Ack sent of serial state message - * Callback called after serial state message sent - * - * \param status UDD_EP_TRANSFER_OK, if transfer finished - * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted - * \param n number of data transferred - */ -static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); - -//@} - -/** - * \name Routines to process data transfer - */ -//@{ - -/** - * \brief Enable the reception of data from the USB host - * - * The value udi_cdc_rx_trans_sel indicate the RX buffer to fill. - * - * \param port Communication port number to manage - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -static bool udi_cdc_rx_start(uint8_t port); - -/** - * \brief Update rx buffer management with a new data - * Callback called after data reception on USB line - * - * \param status UDD_EP_TRANSFER_OK, if transfer finish - * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted - * \param n number of data received - */ -static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); - -/** - * \brief Ack sent of tx buffer - * Callback called after data transfer on USB line - * - * \param status UDD_EP_TRANSFER_OK, if transfer finished - * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted - * \param n number of data transferred - */ -static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep); - -/** - * \brief Send buffer on line or wait a SOF event - * - * \param port Communication port number to manage - */ -static void udi_cdc_tx_send(uint8_t port); - -//@} - -//@} - -/** - * \name Information about configuration of communication line - */ -//@{ -COMPILER_WORD_ALIGNED - static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB]; -static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB]; -static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB]; -COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB]; - -//! Status of CDC COMM interfaces -static volatile uint8_t udi_cdc_nb_comm_enabled = 0; -//@} - -/** - * \name Variables to manage RX/TX transfer requests - * Two buffers for each sense are used to optimize the speed. - */ -//@{ - -//! Status of CDC DATA interfaces -static volatile uint8_t udi_cdc_nb_data_enabled = 0; -static volatile bool udi_cdc_data_running = false; -//! Buffer to receive data -COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS]; -//! Data available in RX buffers -static volatile uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2]; -//! Give the current RX buffer used (rx0 if 0, rx1 if 1) -static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB]; -//! Read position in current RX buffer -static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB]; -//! Signal a transfer on-going -static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB]; - -//! Define a transfer halted -#define UDI_CDC_TRANS_HALTED 2 - -//! Buffer to send data -COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS]; -//! Data available in TX buffers -static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2]; -//! Give current TX buffer used (tx0 if 0, tx1 if 1) -static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB]; -//! Value of SOF during last TX transfer -static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB]; -//! Signal a transfer on-going -static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB]; -//! Signal that both buffer content data to send -static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB]; - -//@} - -bool udi_cdc_comm_enable(void) -{ - uint8_t port; - uint8_t iface_comm_num; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; - udi_cdc_nb_comm_enabled = 0; -#else - if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) { - udi_cdc_nb_comm_enabled = 0; - } - port = udi_cdc_nb_comm_enabled; -#endif - - // Initialize control signal management - udi_cdc_state[port] = CPU_TO_LE16(0); - - uid_cdc_state_msg[port].header.bmRequestType = - USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_RECIP_INTERFACE; - uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE; - uid_cdc_state_msg[port].header.wValue = LE16(0); - - switch (port) { -#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \ - case index: \ - iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~) -#undef UDI_CDC_PORT_TO_IFACE_COMM - default: - iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0; - break; - } - - uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num); - uid_cdc_state_msg[port].header.wLength = LE16(2); - uid_cdc_state_msg[port].value = CPU_TO_LE16(0); - - udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE); - udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS; - udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY; - udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS; - // Call application callback - // to initialize memories or indicate that interface is enabled - UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port])); - if (!UDI_CDC_ENABLE_EXT(port)) { - return false; - } - udi_cdc_nb_comm_enabled++; - return true; -} - -bool udi_cdc_data_enable(void) -{ - uint8_t port; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; - udi_cdc_nb_data_enabled = 0; -#else - if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) { - udi_cdc_nb_data_enabled = 0; - } - port = udi_cdc_nb_data_enabled; -#endif - - // Initialize TX management - udi_cdc_tx_trans_ongoing[port] = false; - udi_cdc_tx_both_buf_to_send[port] = false; - udi_cdc_tx_buf_sel[port] = 0; - udi_cdc_tx_buf_nb[port][0] = 0; - udi_cdc_tx_buf_nb[port][1] = 0; - udi_cdc_tx_sof_num[port] = 0; - udi_cdc_tx_send(port); - - // Initialize RX management - udi_cdc_rx_trans_ongoing[port] = false; - udi_cdc_rx_buf_sel[port] = 0; - udi_cdc_rx_buf_nb[port][0] = 0; - udi_cdc_rx_buf_nb[port][1] = 0; - udi_cdc_rx_pos[port] = 0; - if (!udi_cdc_rx_start(port)) { - return false; - } - udi_cdc_nb_data_enabled++; - if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) { - udi_cdc_data_running = true; - } - return true; -} - -void udi_cdc_comm_disable(void) -{ - Assert(udi_cdc_nb_comm_enabled != 0); - udi_cdc_nb_comm_enabled--; -} - -void udi_cdc_data_disable(void) -{ - uint8_t port; - - Assert(udi_cdc_nb_data_enabled != 0); - udi_cdc_nb_data_enabled--; - port = udi_cdc_nb_data_enabled; - UDI_CDC_DISABLE_EXT(port); - udi_cdc_data_running = false; -} - -bool udi_cdc_comm_setup(void) -{ - uint8_t port = udi_cdc_setup_to_port(); - - if (Udd_setup_is_in()) { - // GET Interface Requests - if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { - // Requests Class Interface Get - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_CDC_GET_LINE_CODING: - // Get configuration of CDC line - if (sizeof(usb_cdc_line_coding_t) != - udd_g_ctrlreq.req.wLength) - return false; // Error for USB host - udd_g_ctrlreq.payload = - (uint8_t *) & - udi_cdc_line_coding[port]; - udd_g_ctrlreq.payload_size = - sizeof(usb_cdc_line_coding_t); - return true; - } - } - } - if (Udd_setup_is_out()) { - // SET Interface Requests - if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { - // Requests Class Interface Set - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_CDC_SET_LINE_CODING: - // Change configuration of CDC line - if (sizeof(usb_cdc_line_coding_t) != - udd_g_ctrlreq.req.wLength) - return false; // Error for USB host - udd_g_ctrlreq.callback = - udi_cdc_line_coding_received; - udd_g_ctrlreq.payload = - (uint8_t *) & - udi_cdc_line_coding[port]; - udd_g_ctrlreq.payload_size = - sizeof(usb_cdc_line_coding_t); - return true; - case USB_REQ_CDC_SET_CONTROL_LINE_STATE: - // According cdc spec 1.1 chapter 6.2.14 - UDI_CDC_SET_DTR_EXT(port, (0 != - (udd_g_ctrlreq.req.wValue - & CDC_CTRL_SIGNAL_DTE_PRESENT))); - UDI_CDC_SET_RTS_EXT(port, (0 != - (udd_g_ctrlreq.req.wValue - & CDC_CTRL_SIGNAL_ACTIVATE_CARRIER))); - return true; - } - } - } - return false; // request Not supported -} - -bool udi_cdc_data_setup(void) -{ - return false; // request Not supported -} - -uint8_t udi_cdc_getsetting(void) -{ - return 0; // CDC don't have multiple alternate setting -} - -void udi_cdc_data_sof_notify(void) -{ - static uint8_t port_notify = 0; - - // A call of udi_cdc_data_sof_notify() is done for each port - udi_cdc_tx_send(port_notify); -#if UDI_CDC_PORT_NB != 1 // To optimize code - port_notify++; - if (port_notify >= UDI_CDC_PORT_NB) { - port_notify = 0; - } -#endif -} - - -// ------------------------ -//------- Internal routines to control serial line - -static uint8_t udi_cdc_setup_to_port(void) -{ - uint8_t port; - - switch (udd_g_ctrlreq.req.wIndex & 0xFF) { -#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \ - case UDI_CDC_COMM_IFACE_NUMBER_##iface: \ - port = iface; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~) -#undef UDI_CDC_IFACE_COMM_TO_PORT - default: - port = 0; - break; - } - return port; -} - -static void udi_cdc_line_coding_received(void) -{ - uint8_t port = udi_cdc_setup_to_port(); - UNUSED(port); - - UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port])); -} - -static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask) -{ - irqflags_t flags; - udd_ep_id_t ep_comm; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - // Update state - flags = cpu_irq_save(); // Protect udi_cdc_state - if (b_set) { - udi_cdc_state[port] |= bit_mask; - } else { - udi_cdc_state[port] &= ~(unsigned)bit_mask; - } - cpu_irq_restore(flags); - - // Send it if possible and state changed - switch (port) { -#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \ - case index: \ - ep_comm = UDI_CDC_COMM_EP_##index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~) -#undef UDI_CDC_PORT_TO_COMM_EP - default: - ep_comm = UDI_CDC_COMM_EP_0; - break; - } - udi_cdc_ctrl_state_notify(port, ep_comm); -} - - -static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep) -{ -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - // Send it if possible and state changed - if ((!udi_cdc_serial_state_msg_ongoing[port]) - && (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) { - // Fill notification message - uid_cdc_state_msg[port].value = udi_cdc_state[port]; - // Send notification message - udi_cdc_serial_state_msg_ongoing[port] = - udd_ep_run(ep, - false, - (uint8_t *) & uid_cdc_state_msg[port], - sizeof(uid_cdc_state_msg[0]), - udi_cdc_serial_state_msg_sent); - } -} - - -static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) -{ - uint8_t port; - UNUSED(n); - UNUSED(status); - - switch (ep) { -#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \ - case UDI_CDC_COMM_EP_##iface: \ - port = iface; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~) -#undef UDI_CDC_GET_PORT_FROM_COMM_EP - default: - port = 0; - break; - } - - udi_cdc_serial_state_msg_ongoing[port] = false; - - // For the irregular signals like break, the incoming ring signal, - // or the overrun error state, this will reset their values to zero - // and again will not send another notification until their state changes. - udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK | - CDC_SERIAL_STATE_RING | - CDC_SERIAL_STATE_FRAMING | - CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); - uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK | - CDC_SERIAL_STATE_RING | - CDC_SERIAL_STATE_FRAMING | - CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN); - // Send it if possible and state changed - udi_cdc_ctrl_state_notify(port, ep); -} - - -// ------------------------ -//------- Internal routines to process data transfer - - -static bool udi_cdc_rx_start(uint8_t port) -{ - irqflags_t flags; - uint8_t buf_sel_trans; - udd_ep_id_t ep; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - flags = cpu_irq_save(); - buf_sel_trans = udi_cdc_rx_buf_sel[port]; - if (udi_cdc_rx_trans_ongoing[port] || - (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { - // Transfer already on-going or current buffer no empty - cpu_irq_restore(flags); - return false; - } - - // Change current buffer - udi_cdc_rx_pos[port] = 0; - udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; - - // Start transfer on RX - udi_cdc_rx_trans_ongoing[port] = true; - cpu_irq_restore(flags); - - if (udi_cdc_multi_is_rx_ready(port)) { - UDI_CDC_RX_NOTIFY(port); - } - // Send the buffer with enable of short packet - switch (port) { -#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ - case index: \ - ep = UDI_CDC_DATA_EP_OUT_##index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) -#undef UDI_CDC_PORT_TO_DATA_EP_OUT - default: - ep = UDI_CDC_DATA_EP_OUT_0; - break; - } - return udd_ep_run(ep, - true, - udi_cdc_rx_buf[port][buf_sel_trans], - UDI_CDC_RX_BUFFERS, - udi_cdc_data_received); -} - - -static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) -{ - uint8_t buf_sel_trans; - uint8_t port; - - switch (ep) { -#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \ - case UDI_CDC_DATA_EP_OUT_##index: \ - port = index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~) -#undef UDI_CDC_DATA_EP_OUT_TO_PORT - default: - port = 0; - break; - } - - if (UDD_EP_TRANSFER_OK != status) { - // Abort reception - return; - } - buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0; - if (!n) { - udd_ep_run( ep, - true, - udi_cdc_rx_buf[port][buf_sel_trans], - UDI_CDC_RX_BUFFERS, - udi_cdc_data_received); - return; - } - udi_cdc_rx_buf_nb[port][buf_sel_trans] = n; - udi_cdc_rx_trans_ongoing[port] = false; - udi_cdc_rx_start(port); -} - - -static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep) -{ - uint8_t port; - UNUSED(n); - - switch (ep) { -#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \ - case UDI_CDC_DATA_EP_IN_##index: \ - port = index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~) -#undef UDI_CDC_DATA_EP_IN_TO_PORT - default: - port = 0; - break; - } - - if (UDD_EP_TRANSFER_OK != status) { - // Abort transfer - return; - } - udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0; - udi_cdc_tx_both_buf_to_send[port] = false; - udi_cdc_tx_trans_ongoing[port] = false; - - if (n != 0) { - UDI_CDC_TX_EMPTY_NOTIFY(port); - } - udi_cdc_tx_send(port); -} - - -static void udi_cdc_tx_send(uint8_t port) -{ - irqflags_t flags; - uint8_t buf_sel_trans; - bool b_short_packet; - udd_ep_id_t ep; - static uint16_t sof_zlp_counter = 0; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - if (udi_cdc_tx_trans_ongoing[port]) { - return; // Already on going or wait next SOF to send next data - } - if (udd_is_high_speed()) { - if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) { - return; // Wait next SOF to send next data - } - }else{ - if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) { - return; // Wait next SOF to send next data - } - } - - flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel - buf_sel_trans = udi_cdc_tx_buf_sel[port]; - if (udi_cdc_tx_buf_nb[port][buf_sel_trans] == 0) { - sof_zlp_counter++; - if (((!udd_is_high_speed()) && (sof_zlp_counter < 100)) - || (udd_is_high_speed() && (sof_zlp_counter < 800))) { - cpu_irq_restore(flags); - return; - } - } - sof_zlp_counter = 0; - - if (!udi_cdc_tx_both_buf_to_send[port]) { - // Send current Buffer - // and switch the current buffer - udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0; - }else{ - // Send the other Buffer - // and no switch the current buffer - buf_sel_trans = (buf_sel_trans==0)?1:0; - } - udi_cdc_tx_trans_ongoing[port] = true; - cpu_irq_restore(flags); - - b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS); - if (b_short_packet) { - if (udd_is_high_speed()) { - udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number(); - }else{ - udi_cdc_tx_sof_num[port] = udd_get_frame_number(); - } - }else{ - udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF - } - - // Send the buffer with enable of short packet - switch (port) { -#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \ - case index: \ - ep = UDI_CDC_DATA_EP_IN_##index; \ - break; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~) -#undef UDI_CDC_PORT_TO_DATA_EP_IN - default: - ep = UDI_CDC_DATA_EP_IN_0; - break; - } - udd_ep_run( ep, - b_short_packet, - udi_cdc_tx_buf[port][buf_sel_trans], - udi_cdc_tx_buf_nb[port][buf_sel_trans], - udi_cdc_data_sent); -} - - -// ------------------------ -//------- Application interface - - -//------- Application interface - -void udi_cdc_ctrl_signal_dcd(bool b_set) -{ - udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD); -} - -void udi_cdc_ctrl_signal_dsr(bool b_set) -{ - udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR); -} - -void udi_cdc_signal_framing_error(void) -{ - udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING); -} - -void udi_cdc_signal_parity_error(void) -{ - udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY); -} - -void udi_cdc_signal_overrun(void) -{ - udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN); -} - -void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set) -{ - udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD); -} - -void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set) -{ - udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR); -} - -void udi_cdc_multi_signal_framing_error(uint8_t port) -{ - udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING); -} - -void udi_cdc_multi_signal_parity_error(uint8_t port) -{ - udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY); -} - -void udi_cdc_multi_signal_overrun(uint8_t port) -{ - udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN); -} - -iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port) -{ - irqflags_t flags; - uint16_t pos; - iram_size_t nb_received; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - flags = cpu_irq_save(); - pos = udi_cdc_rx_pos[port]; - nb_received = udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]] - pos; - cpu_irq_restore(flags); - return nb_received; -} - -iram_size_t udi_cdc_get_nb_received_data(void) -{ - return udi_cdc_multi_get_nb_received_data(0); -} - -bool udi_cdc_multi_is_rx_ready(uint8_t port) -{ - return (udi_cdc_multi_get_nb_received_data(port) > 0); -} - -bool udi_cdc_is_rx_ready(void) -{ - return udi_cdc_multi_is_rx_ready(0); -} - -int udi_cdc_multi_getc(uint8_t port) -{ - irqflags_t flags; - int rx_data = 0; - bool b_databit_9; - uint16_t pos; - uint8_t buf_sel; - bool again; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); - -udi_cdc_getc_process_one_byte: - // Check available data - flags = cpu_irq_save(); - pos = udi_cdc_rx_pos[port]; - buf_sel = udi_cdc_rx_buf_sel[port]; - again = pos >= udi_cdc_rx_buf_nb[port][buf_sel]; - cpu_irq_restore(flags); - while (again) { - if (!udi_cdc_data_running) { - return 0; - } - goto udi_cdc_getc_process_one_byte; - } - - // Read data - rx_data |= udi_cdc_rx_buf[port][buf_sel][pos]; - udi_cdc_rx_pos[port] = pos+1; - - udi_cdc_rx_start(port); - - if (b_databit_9) { - // Receive MSB - b_databit_9 = false; - rx_data = rx_data << 8; - goto udi_cdc_getc_process_one_byte; - } - return rx_data; -} - -int udi_cdc_getc(void) -{ - return udi_cdc_multi_getc(0); -} - -iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size) -{ - irqflags_t flags; - uint8_t *ptr_buf = (uint8_t *)buf; - iram_size_t copy_nb; - uint16_t pos; - uint8_t buf_sel; - bool again; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - -udi_cdc_read_buf_loop_wait: - // Check available data - flags = cpu_irq_save(); - pos = udi_cdc_rx_pos[port]; - buf_sel = udi_cdc_rx_buf_sel[port]; - again = pos >= udi_cdc_rx_buf_nb[port][buf_sel]; - cpu_irq_restore(flags); - while (again) { - if (!udi_cdc_data_running) { - return size; - } - goto udi_cdc_read_buf_loop_wait; - } - - // Read data - copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos; - if (copy_nb>size) { - copy_nb = size; - } - memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb); - udi_cdc_rx_pos[port] += copy_nb; - ptr_buf += copy_nb; - size -= copy_nb; - udi_cdc_rx_start(port); - - if (size) { - goto udi_cdc_read_buf_loop_wait; - } - return 0; -} - -static iram_size_t udi_cdc_multi_read_no_polling(uint8_t port, void* buf, iram_size_t size) -{ - uint8_t *ptr_buf = (uint8_t *)buf; - iram_size_t nb_avail_data; - uint16_t pos; - uint8_t buf_sel; - irqflags_t flags; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - //Data interface not started... exit - if (!udi_cdc_data_running) { - return 0; - } - - //Get number of available data - // Check available data - flags = cpu_irq_save(); // to protect udi_cdc_rx_pos & udi_cdc_rx_buf_sel - pos = udi_cdc_rx_pos[port]; - buf_sel = udi_cdc_rx_buf_sel[port]; - nb_avail_data = udi_cdc_rx_buf_nb[port][buf_sel] - pos; - cpu_irq_restore(flags); - //If the buffer contains less than the requested number of data, - //adjust read size - if(nb_avail_data0) { - memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], size); - flags = cpu_irq_save(); // to protect udi_cdc_rx_pos - udi_cdc_rx_pos[port] += size; - cpu_irq_restore(flags); - - ptr_buf += size; - udi_cdc_rx_start(port); - } - return(nb_avail_data); -} - -iram_size_t udi_cdc_read_no_polling(void* buf, iram_size_t size) -{ - return udi_cdc_multi_read_no_polling(0, buf, size); -} - -iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size) -{ - return udi_cdc_multi_read_buf(0, buf, size); -} - -iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_get_free_tx_buffer(uint8_t port) -{ - irqflags_t flags; - iram_size_t buf_sel_nb, retval; - uint8_t buf_sel; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - flags = cpu_irq_save(); - buf_sel = udi_cdc_tx_buf_sel[port]; - buf_sel_nb = udi_cdc_tx_buf_nb[port][buf_sel]; - if (buf_sel_nb == UDI_CDC_TX_BUFFERS) { - if ((!udi_cdc_tx_trans_ongoing[port]) - && (!udi_cdc_tx_both_buf_to_send[port])) { - /* One buffer is full, but the other buffer is not used. - * (not used = transfer on-going) - * then move to the other buffer to store data */ - udi_cdc_tx_both_buf_to_send[port] = true; - udi_cdc_tx_buf_sel[port] = (buf_sel == 0)? 1 : 0; - buf_sel_nb = 0; - } - } - retval = UDI_CDC_TX_BUFFERS - buf_sel_nb; - cpu_irq_restore(flags); - return retval; -} - -iram_size_t udi_cdc_get_free_tx_buffer(void) -{ - return udi_cdc_multi_get_free_tx_buffer(0); -} - -bool udi_cdc_multi_is_tx_ready(uint8_t port) -{ - return (udi_cdc_multi_get_free_tx_buffer(port) != 0); -} - -bool udi_cdc_is_tx_ready(void) -{ - return udi_cdc_multi_is_tx_ready(0); -} - -int udi_cdc_multi_putc(uint8_t port, int value) -{ - irqflags_t flags; - bool b_databit_9; - uint8_t buf_sel; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits); - -udi_cdc_putc_process_one_byte: - // Check available space - if (!udi_cdc_multi_is_tx_ready(port)) { - if (!udi_cdc_data_running) { - return false; - } - goto udi_cdc_putc_process_one_byte; - } - - // Write value - flags = cpu_irq_save(); - buf_sel = udi_cdc_tx_buf_sel[port]; - udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value; - cpu_irq_restore(flags); - - if (b_databit_9) { - // Send MSB - b_databit_9 = false; - value = value >> 8; - goto udi_cdc_putc_process_one_byte; - } - return true; -} - -int udi_cdc_putc(int value) -{ - return udi_cdc_multi_putc(0, value); -} - -iram_size_t __attribute__((optimize("O0"))) udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size) -{ - irqflags_t flags; - uint8_t buf_sel; - uint16_t buf_nb; - iram_size_t copy_nb; - uint8_t *ptr_buf = (uint8_t *)buf; - -#if UDI_CDC_PORT_NB == 1 // To optimize code - port = 0; -#endif - - if (9 == udi_cdc_line_coding[port].bDataBits) { - size *=2; - } - -udi_cdc_write_buf_loop_wait: - // Check available space - if (!udi_cdc_multi_is_tx_ready(port)) { - if (!udi_cdc_data_running) { - return size; - } - goto udi_cdc_write_buf_loop_wait; - } - - // Write values - flags = cpu_irq_save(); - buf_sel = udi_cdc_tx_buf_sel[port]; - buf_nb = udi_cdc_tx_buf_nb[port][buf_sel]; - copy_nb = UDI_CDC_TX_BUFFERS - buf_nb; - if (copy_nb > size) { - copy_nb = size; - } - memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb); - udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb; - cpu_irq_restore(flags); - - // Update buffer pointer - ptr_buf = ptr_buf + copy_nb; - size -= copy_nb; - - if (size) { - goto udi_cdc_write_buf_loop_wait; - } - - return 0; -} - -iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size) -{ - return udi_cdc_multi_write_buf(0, buf, size); -} - -//@} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/udi_cdc.h b/src/HAL/DUE/usb/udi_cdc.h deleted file mode 100644 index b618450..0000000 --- a/src/HAL/DUE/usb/udi_cdc.h +++ /dev/null @@ -1,810 +0,0 @@ -/** - * \file - * - * \brief USB Device Communication Device Class (CDC) interface definitions. - * - * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDI_CDC_H_ -#define _UDI_CDC_H_ - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "usb_protocol_cdc.h" -#include "udd.h" -#include "udc_desc.h" -#include "udi.h" - -// Check the number of port -#ifndef UDI_CDC_PORT_NB -# define UDI_CDC_PORT_NB 1 -#endif -#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7) -# error UDI_CDC_PORT_NB must be between 1 and 7 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup udi_cdc_group_udc - * @{ - */ - -//! Global structure which contains standard UDI API for UDC -extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm; -extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data; -//@} - -/** - * \ingroup udi_cdc_group - * \defgroup udi_cdc_group_desc USB interface descriptors - * - * The following structures provide predefined USB interface descriptors. - * It must be used to define the final USB descriptors. - */ -//@{ - -/** - * \brief Communication Class interface descriptor - * - * Interface descriptor with associated functional and endpoint - * descriptors for the CDC Communication Class interface. - */ -typedef struct { - //! Standard interface descriptor - usb_iface_desc_t iface; - //! CDC Header functional descriptor - usb_cdc_hdr_desc_t header; - //! CDC Abstract Control Model functional descriptor - usb_cdc_acm_desc_t acm; - //! CDC Union functional descriptor - usb_cdc_union_desc_t union_desc; - //! CDC Call Management functional descriptor - usb_cdc_call_mgmt_desc_t call_mgmt; - //! Notification endpoint descriptor - usb_ep_desc_t ep_notify; -} udi_cdc_comm_desc_t; - - -/** - * \brief Data Class interface descriptor - * - * Interface descriptor with associated endpoint descriptors for the - * CDC Data Class interface. - */ -typedef struct { - //! Standard interface descriptor - usb_iface_desc_t iface; - //! Data IN/OUT endpoint descriptors - usb_ep_desc_t ep_in; - usb_ep_desc_t ep_out; -} udi_cdc_data_desc_t; - - -//! CDC communication endpoints size for all speeds -#define UDI_CDC_COMM_EP_SIZE 64 -//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B) -#define UDI_CDC_DATA_EPS_FS_SIZE 64 -//! CDC data endpoints size for HS speed (512B only) -#define UDI_CDC_DATA_EPS_HS_SIZE 512 - -/** - * \name Content of interface descriptors - * Up to 7 CDC interfaces can be implemented on a USB device. - */ -//@{ -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_0 -#define UDI_CDC_IAD_STRING_ID_0 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_0 -#define UDI_CDC_COMM_STRING_ID_0 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_0 -#define UDI_CDC_DATA_STRING_ID_0 0 -#endif -#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0) -#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0) -#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0) -#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_1 -#define UDI_CDC_IAD_STRING_ID_1 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_1 -#define UDI_CDC_COMM_STRING_ID_1 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_1 -#define UDI_CDC_DATA_STRING_ID_1 0 -#endif -#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1) -#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1) -#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1) -#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_2 -#define UDI_CDC_IAD_STRING_ID_2 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_2 -#define UDI_CDC_COMM_STRING_ID_2 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_2 -#define UDI_CDC_DATA_STRING_ID_2 0 -#endif -#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2) -#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2) -#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2) -#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_3 -#define UDI_CDC_IAD_STRING_ID_3 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_3 -#define UDI_CDC_COMM_STRING_ID_3 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_3 -#define UDI_CDC_DATA_STRING_ID_3 0 -#endif -#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3) -#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3) -#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3) -#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_4 -#define UDI_CDC_IAD_STRING_ID_4 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_4 -#define UDI_CDC_COMM_STRING_ID_4 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_4 -#define UDI_CDC_DATA_STRING_ID_4 0 -#endif -#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4) -#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4) -#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4) -#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_5 -#define UDI_CDC_IAD_STRING_ID_5 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_5 -#define UDI_CDC_COMM_STRING_ID_5 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_5 -#define UDI_CDC_DATA_STRING_ID_5 0 -#endif -#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5) -#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5) -#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5) -#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5) - -//! By default no string associated to these interfaces -#ifndef UDI_CDC_IAD_STRING_ID_6 -#define UDI_CDC_IAD_STRING_ID_6 0 -#endif -#ifndef UDI_CDC_COMM_STRING_ID_6 -#define UDI_CDC_COMM_STRING_ID_6 0 -#endif -#ifndef UDI_CDC_DATA_STRING_ID_6 -#define UDI_CDC_DATA_STRING_ID_6 0 -#endif -#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6) -#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6) -#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6) -#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6) -//@} - - -//! Content of CDC IAD interface descriptor for all speeds -#define UDI_CDC_IAD_DESC(port) { \ - .bLength = sizeof(usb_iad_desc_t),\ - .bDescriptorType = USB_DT_IAD,\ - .bInterfaceCount = 2,\ - .bFunctionClass = CDC_CLASS_COMM,\ - .bFunctionSubClass = CDC_SUBCLASS_ACM,\ - .bFunctionProtocol = CDC_PROTOCOL_V25TER,\ - .bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ - .iFunction = UDI_CDC_IAD_STRING_ID_##port,\ - } - -//! Content of CDC COMM interface descriptor for all speeds -#define UDI_CDC_COMM_DESC(port) { \ - .iface.bLength = sizeof(usb_iface_desc_t),\ - .iface.bDescriptorType = USB_DT_INTERFACE,\ - .iface.bAlternateSetting = 0,\ - .iface.bNumEndpoints = 1,\ - .iface.bInterfaceClass = CDC_CLASS_COMM,\ - .iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\ - .iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\ - .header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\ - .header.bDescriptorType = CDC_CS_INTERFACE,\ - .header.bDescriptorSubtype = CDC_SCS_HEADER,\ - .header.bcdCDC = LE16(0x0110),\ - .call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\ - .call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\ - .call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\ - .call_mgmt.bmCapabilities = \ - CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\ - .acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\ - .acm.bDescriptorType = CDC_CS_INTERFACE,\ - .acm.bDescriptorSubtype = CDC_SCS_ACM,\ - .acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\ - .union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\ - .union_desc.bDescriptorType = CDC_CS_INTERFACE,\ - .union_desc.bDescriptorSubtype= CDC_SCS_UNION,\ - .ep_notify.bLength = sizeof(usb_ep_desc_t),\ - .ep_notify.bDescriptorType = USB_DT_ENDPOINT,\ - .ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\ - .ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\ - .ep_notify.bInterval = 0x10,\ - .ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\ - .iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\ - .call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\ - .union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\ - .union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\ - .iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\ - } - -//! Content of CDC DATA interface descriptors -#define UDI_CDC_DATA_DESC_COMMON \ - .iface.bLength = sizeof(usb_iface_desc_t),\ - .iface.bDescriptorType = USB_DT_INTERFACE,\ - .iface.bAlternateSetting = 0,\ - .iface.bNumEndpoints = 2,\ - .iface.bInterfaceClass = CDC_CLASS_DATA,\ - .iface.bInterfaceSubClass = 0,\ - .iface.bInterfaceProtocol = 0,\ - .ep_in.bLength = sizeof(usb_ep_desc_t),\ - .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ - .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ - .ep_in.bInterval = 0,\ - .ep_out.bLength = sizeof(usb_ep_desc_t),\ - .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ - .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ - .ep_out.bInterval = 0, - -#define UDI_CDC_DATA_DESC_FS(port) { \ - UDI_CDC_DATA_DESC_COMMON \ - .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ - .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\ - .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ - .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ - .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ - .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ - } - -#define UDI_CDC_DATA_DESC_HS(port) { \ - UDI_CDC_DATA_DESC_COMMON \ - .ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ - .ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\ - .ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\ - .ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\ - .iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\ - .iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\ - } - -//@} - -/** - * \ingroup udi_group - * \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC) - * - * Common APIs used by high level application to use this USB class. - * - * These routines are used to transfer and control data - * to/from USB CDC endpoint. - * - * See \ref udi_cdc_quickstart. - * @{ - */ - -/** - * \name Interface for application with single CDC interface support - */ -//@{ - -/** - * \brief Notify a state change of DCD signal - * - * \param b_set DCD is enabled if true, else disabled - */ -void udi_cdc_ctrl_signal_dcd(bool b_set); - -/** - * \brief Notify a state change of DSR signal - * - * \param b_set DSR is enabled if true, else disabled - */ -void udi_cdc_ctrl_signal_dsr(bool b_set); - -/** - * \brief Notify a framing error - */ -void udi_cdc_signal_framing_error(void); - -/** - * \brief Notify a parity error - */ -void udi_cdc_signal_parity_error(void); - -/** - * \brief Notify a overrun - */ -void udi_cdc_signal_overrun(void); - -/** - * \brief Gets the number of byte received - * - * \return the number of data available - */ -iram_size_t udi_cdc_get_nb_received_data(void); - -/** - * \brief This function checks if a character has been received on the CDC line - * - * \return \c 1 if a byte is ready to be read. - */ -bool udi_cdc_is_rx_ready(void); - -/** - * \brief Waits and gets a value on CDC line - * - * \return value read on CDC line - */ -int udi_cdc_getc(void); - -/** - * \brief Reads a RAM buffer on CDC line - * - * \param buf Values read - * \param size Number of value read - * - * \return the number of data remaining - */ -iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size); - -/** - * \brief Non polling reads of a up to 'size' data from CDC line - * - * \param port Communication port number to manage - * \param buf Buffer where to store read data - * \param size Maximum number of data to read (size of buffer) - * - * \return the number of data effectively read - */ -iram_size_t udi_cdc_read_no_polling(void* buf, iram_size_t size); - -/** - * \brief Gets the number of free byte in TX buffer - * - * \return the number of free byte in TX buffer - */ -iram_size_t udi_cdc_get_free_tx_buffer(void); - -/** - * \brief This function checks if a new character sent is possible - * The type int is used to support scanf redirection from compiler LIB. - * - * \return \c 1 if a new character can be sent - */ -bool udi_cdc_is_tx_ready(void); - -/** - * \brief Puts a byte on CDC line - * The type int is used to support printf redirection from compiler LIB. - * - * \param value Value to put - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -int udi_cdc_putc(int value); - -/** - * \brief Writes a RAM buffer on CDC line - * - * \param buf Values to write - * \param size Number of value to write - * - * \return the number of data remaining - */ -iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size); -//@} - -/** - * \name Interface for application with multi CDC interfaces support - */ -//@{ - -/** - * \brief Notify a state change of DCD signal - * - * \param port Communication port number to manage - * \param b_set DCD is enabled if true, else disabled - */ -void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set); - -/** - * \brief Notify a state change of DSR signal - * - * \param port Communication port number to manage - * \param b_set DSR is enabled if true, else disabled - */ -void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set); - -/** - * \brief Notify a framing error - * - * \param port Communication port number to manage - */ -void udi_cdc_multi_signal_framing_error(uint8_t port); - -/** - * \brief Notify a parity error - * - * \param port Communication port number to manage - */ -void udi_cdc_multi_signal_parity_error(uint8_t port); - -/** - * \brief Notify a overrun - * - * \param port Communication port number to manage - */ -void udi_cdc_multi_signal_overrun(uint8_t port); - -/** - * \brief Gets the number of byte received - * - * \param port Communication port number to manage - * - * \return the number of data available - */ -iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port); - -/** - * \brief This function checks if a character has been received on the CDC line - * - * \param port Communication port number to manage - * - * \return \c 1 if a byte is ready to be read. - */ -bool udi_cdc_multi_is_rx_ready(uint8_t port); - -/** - * \brief Waits and gets a value on CDC line - * - * \param port Communication port number to manage - * - * \return value read on CDC line - */ -int udi_cdc_multi_getc(uint8_t port); - -/** - * \brief Reads a RAM buffer on CDC line - * - * \param port Communication port number to manage - * \param buf Values read - * \param size Number of values read - * - * \return the number of data remaining - */ -iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size); - -/** - * \brief Gets the number of free byte in TX buffer - * - * \param port Communication port number to manage - * - * \return the number of free byte in TX buffer - */ -iram_size_t udi_cdc_multi_get_free_tx_buffer(uint8_t port); - -/** - * \brief This function checks if a new character sent is possible - * The type int is used to support scanf redirection from compiler LIB. - * - * \param port Communication port number to manage - * - * \return \c 1 if a new character can be sent - */ -bool udi_cdc_multi_is_tx_ready(uint8_t port); - -/** - * \brief Puts a byte on CDC line - * The type int is used to support printf redirection from compiler LIB. - * - * \param port Communication port number to manage - * \param value Value to put - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -int udi_cdc_multi_putc(uint8_t port, int value); - -/** - * \brief Writes a RAM buffer on CDC line - * - * \param port Communication port number to manage - * \param buf Values to write - * \param size Number of value to write - * - * \return the number of data remaining - */ -iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size); -//@} - -//@} - -/** - * \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC) - * - * This is the quick start guide for the \ref udi_cdc_group - * "USB device interface CDC module (UDI CDC)" with step-by-step instructions on - * how to configure and use the modules in a selection of use cases. - * - * The use cases contain several code fragments. The code fragments in the - * steps for setup can be copied into a custom initialization function, while - * the steps for usage can be copied into, e.g., the main application function. - * - * \section udi_cdc_basic_use_case Basic use case - * In this basic use case, the "USB CDC (Single Interface Device)" module is used - * with only one communication port. - * The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases - * "Advanced use cases". - * - * \section udi_cdc_basic_use_case_setup Setup steps - * \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites - * \copydetails udc_basic_use_case_setup_prereq - * \subsection udi_cdc_basic_use_case_setup_code Example code - * \copydetails udc_basic_use_case_setup_code - * \subsection udi_cdc_basic_use_case_setup_flow Workflow - * \copydetails udc_basic_use_case_setup_flow - * - * \section udi_cdc_basic_use_case_usage Usage steps - * - * \subsection udi_cdc_basic_use_case_usage_code Example code - * Content of conf_usb.h: - * \code - #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() - extern bool my_callback_cdc_enable(void); - #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() - extern void my_callback_cdc_disable(void); - #define UDI_CDC_LOW_RATE - - #define UDI_CDC_DEFAULT_RATE 115200 - #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 - #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE - #define UDI_CDC_DEFAULT_DATABITS 8 - - #include "udi_cdc_conf.h" // At the end of conf_usb.h file -\endcode - * - * Add to application C-file: - * \code - static bool my_flag_autorize_cdc_transfert = false; - bool my_callback_cdc_enable(void) - { - my_flag_autorize_cdc_transfert = true; - return true; - } - void my_callback_cdc_disable(void) - { - my_flag_autorize_cdc_transfert = false; - } - - void task(void) - { - if (my_flag_autorize_cdc_transfert) { - udi_cdc_putc('A'); - udi_cdc_getc(); - } - } -\endcode - * - * \subsection udi_cdc_basic_use_case_setup_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following configuration, - * which is the USB device CDC configuration: - * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode - * \note The USB serial number is mandatory when a CDC interface is used. - * - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable() - extern bool my_callback_cdc_enable(void); \endcode - * \note After the device enumeration (detecting and identifying USB devices), - * the USB host starts the device configuration. When the USB CDC interface - * from the device is accepted by the host, the USB host enables this interface and the - * UDI_CDC_ENABLE_EXT() callback function is called and return true. - * Thus, when this event is received, the data transfer on CDC interface are authorized. - * - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable() - extern void my_callback_cdc_disable(void); \endcode - * \note When the USB device is unplugged or is reset by the USB host, the USB - * interface is disabled and the UDI_CDC_DISABLE_EXT() callback function - * is called. Thus, the data transfer must be stopped on CDC interface. - * - \code #define UDI_CDC_LOW_RATE \endcode - * \note Define it when the transfer CDC Device to Host is a low rate - * (<512000 bauds) to reduce CDC buffers size. - * - \code #define UDI_CDC_DEFAULT_RATE 115200 - #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1 - #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE - #define UDI_CDC_DEFAULT_DATABITS 8 \endcode - * \note Default configuration of communication port at startup. - * -# Send or wait data on CDC line: - * - \code // Waits and gets a value on CDC line - int udi_cdc_getc(void); - // Reads a RAM buffer on CDC line - iram_size_t udi_cdc_read_buf(int *buf, iram_size_t size); - // Puts a byte on CDC line - int udi_cdc_putc(int value); - // Writes a RAM buffer on CDC line - iram_size_t udi_cdc_write_buf(const int *buf, iram_size_t size); \endcode - * - * \section udi_cdc_use_cases Advanced use cases - * For more advanced use of the UDI CDC module, see the following use cases: - * - \subpage udi_cdc_use_case_composite - * - \subpage udc_use_case_1 - * - \subpage udc_use_case_2 - * - \subpage udc_use_case_3 - * - \subpage udc_use_case_4 - * - \subpage udc_use_case_5 - * - \subpage udc_use_case_6 - */ - -/** - * \page udi_cdc_use_case_composite CDC in a composite device - * - * A USB Composite Device is a USB Device which uses more than one USB class. - * In this use case, the "USB CDC (Composite Device)" module is used to - * create a USB composite device. Thus, this USB module can be associated with - * another "Composite Device" module, like "USB HID Mouse (Composite Device)". - * - * Also, you can refer to application note - * - * AVR4902 ASF - USB Composite Device. - * - * \section udi_cdc_use_case_composite_setup Setup steps - * For the setup code of this use case to work, the - * \ref udi_cdc_basic_use_case "basic use case" must be followed. - * - * \section udi_cdc_use_case_composite_usage Usage steps - * - * \subsection udi_cdc_use_case_composite_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_EP_CTRL_SIZE 64 - #define USB_DEVICE_NB_INTERFACE (X+2) - #define USB_DEVICE_MAX_EP (X+3) - - #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX - #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX - #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint - #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 - #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 - - #define UDI_COMPOSITE_DESC_T \ - usb_iad_desc_t udi_cdc_iad; \ - udi_cdc_comm_desc_t udi_cdc_comm; \ - udi_cdc_data_desc_t udi_cdc_data; \ - ... - #define UDI_COMPOSITE_DESC_FS \ - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - ... - #define UDI_COMPOSITE_DESC_HS \ - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - ... - #define UDI_COMPOSITE_API \ - &udi_api_cdc_comm, \ - &udi_api_cdc_data, \ - ... -\endcode - * - * \subsection udi_cdc_use_case_composite_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required for a USB composite device configuration: - * - \code // Endpoint control size, This must be: - // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) - // - 64 for a high speed device - #define USB_DEVICE_EP_CTRL_SIZE 64 - // Total Number of interfaces on this USB device. - // Add 2 for CDC. - #define USB_DEVICE_NB_INTERFACE (X+2) - // Total number of endpoints on this USB device. - // This must include each endpoint for each interface. - // Add 3 for CDC. - #define USB_DEVICE_MAX_EP (X+3) \endcode - * -# Ensure that conf_usb.h contains the description of - * composite device: - * - \code // The endpoint numbers chosen by you for the CDC. - // The endpoint numbers starting from 1. - #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX - #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX - #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint - // The interface index of an interface starting from 0 - #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0 - #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode - * -# Ensure that conf_usb.h contains the following parameters - * required for a USB composite device configuration: - * - \code // USB Interfaces descriptor structure - #define UDI_COMPOSITE_DESC_T \ - ... - usb_iad_desc_t udi_cdc_iad; \ - udi_cdc_comm_desc_t udi_cdc_comm; \ - udi_cdc_data_desc_t udi_cdc_data; \ - ... - // USB Interfaces descriptor value for Full Speed - #define UDI_COMPOSITE_DESC_FS \ - ... - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \ - ... - // USB Interfaces descriptor value for High Speed - #define UDI_COMPOSITE_DESC_HS \ - ... - .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \ - .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \ - .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \ - ... - // USB Interface APIs - #define UDI_COMPOSITE_API \ - ... - &udi_api_cdc_comm, \ - &udi_api_cdc_data, \ - ... \endcode - * - \note The descriptors order given in the four lists above must be the - * same as the order defined by all interface indexes. The interface index - * orders are defined through UDI_X_IFACE_NUMBER defines.\n - * Also, the CDC requires a USB Interface Association Descriptor (IAD) for - * composite device. - */ - -#ifdef __cplusplus -} -#endif -#endif // _UDI_CDC_H_ diff --git a/src/HAL/DUE/usb/udi_cdc_conf.h b/src/HAL/DUE/usb/udi_cdc_conf.h deleted file mode 100644 index e61b8cb..0000000 --- a/src/HAL/DUE/usb/udi_cdc_conf.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * \file - * - * \brief Default CDC configuration for a USB Device with a single interface - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDI_CDC_CONF_H_ -#define _UDI_CDC_CONF_H_ - -#include "usb_protocol_cdc.h" -#include "conf_usb.h" - -#ifndef UDI_CDC_PORT_NB -# define UDI_CDC_PORT_NB 1 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup udi_cdc_group_single_desc - * @{ - */ - -//! Control endpoint size (Endpoint 0) -#define USB_DEVICE_EP_CTRL_SIZE 64 - -#if XMEGA -/** - * \name Endpoint configuration on XMEGA - * The XMEGA supports a IN and OUT endpoint with the same number endpoint, - * thus XMEGA can support up to 7 CDC interfaces. - */ -//@{ -#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint -#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint -//! 2 endpoints numbers used per CDC interface -#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB) -//@} - -#else - -/** - * \name Default endpoint configuration - * The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces. - */ -//@{ -# if UDI_CDC_PORT_NB > 2 -# error USBB, UDP, UDPHS and UOTGHS interfaces have not enough endpoints. -# endif -#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX -#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX -#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint -# if SAM3U - /* For 3U max endpoint size of 4 is 64, use 5 and 6 as bulk tx and rx */ -# define UDI_CDC_DATA_EP_IN_1 (6 | USB_EP_DIR_IN) // TX -# define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX -# define UDI_CDC_COMM_EP_1 (4 | USB_EP_DIR_IN) // Notify -# else -# define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX -# define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX -# define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify -# endif -//! 3 endpoints used per CDC interface -#undef USB_DEVICE_MAX_EP // undefine this definition in header file -#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB) -//@} - -#endif - -/** - * \name Default Interface numbers - */ -//@{ -#define UDI_CDC_COMM_IFACE_NUMBER_0 0 -#define UDI_CDC_DATA_IFACE_NUMBER_0 1 -#define UDI_CDC_COMM_IFACE_NUMBER_1 2 -#define UDI_CDC_DATA_IFACE_NUMBER_1 3 -#define UDI_CDC_COMM_IFACE_NUMBER_2 4 -#define UDI_CDC_DATA_IFACE_NUMBER_2 5 -#define UDI_CDC_COMM_IFACE_NUMBER_3 6 -#define UDI_CDC_DATA_IFACE_NUMBER_3 7 -#define UDI_CDC_COMM_IFACE_NUMBER_4 8 -#define UDI_CDC_DATA_IFACE_NUMBER_4 9 -#define UDI_CDC_COMM_IFACE_NUMBER_5 10 -#define UDI_CDC_DATA_IFACE_NUMBER_5 11 -#define UDI_CDC_COMM_IFACE_NUMBER_6 12 -#define UDI_CDC_DATA_IFACE_NUMBER_6 13 -//@} - -//@} - -#ifdef __cplusplus -} -#endif -#endif // _UDI_CDC_CONF_H_ diff --git a/src/HAL/DUE/usb/udi_cdc_desc.c b/src/HAL/DUE/usb/udi_cdc_desc.c deleted file mode 100644 index 97c334e..0000000 --- a/src/HAL/DUE/usb/udi_cdc_desc.c +++ /dev/null @@ -1,261 +0,0 @@ -/** - * \file - * - * \brief Default descriptors for a USB Device with a single interface CDC - * - * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "conf_usb.h" -#include "udd.h" -#include "udc_desc.h" -#include "udi_cdc.h" - -#if DISABLED(SDSUPPORT) - -/** - * \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface - * - * The following structures provide the USB device descriptors required for - * USB Device with a single interface CDC. - * - * It is ready to use and do not require more definition. - * - * @{ - */ - -//! Two interfaces for a CDC device -#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB) - -#ifdef USB_DEVICE_LPM_SUPPORT -# define USB_VERSION USB_V2_1 -#else -# define USB_VERSION USB_V2_0 -#endif - -//! USB Device Descriptor -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { - .bLength = sizeof(usb_dev_desc_t), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = LE16(USB_VERSION), -#if UDI_CDC_PORT_NB > 1 - .bDeviceClass = 0, -#else - .bDeviceClass = CDC_CLASS_DEVICE, -#endif - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, - .idVendor = LE16(USB_DEVICE_VENDOR_ID), - .idProduct = LE16(USB_DEVICE_PRODUCT_ID), - .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) - | USB_DEVICE_MINOR_VERSION), -#ifdef USB_DEVICE_MANUFACTURE_NAME - .iManufacturer = 1, -#else - .iManufacturer = 0, // No manufacture string -#endif -#ifdef USB_DEVICE_PRODUCT_NAME - .iProduct = 2, -#else - .iProduct = 0, // No product string -#endif -#if (defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER) - .iSerialNumber = 3, -#else - .iSerialNumber = 0, // No serial string -#endif - .bNumConfigurations = 1 -}; - - -#ifdef USB_DEVICE_HS_SUPPORT -//! USB Device Qualifier Descriptor for HS -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { - .bLength = sizeof(usb_dev_qual_desc_t), - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = LE16(USB_VERSION), -#if UDI_CDC_PORT_NB > 1 - .bDeviceClass = 0, -#else - .bDeviceClass = CDC_CLASS_DEVICE, -#endif - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, - .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, - .bNumConfigurations = 1 -}; -#endif - -#ifdef USB_DEVICE_LPM_SUPPORT -//! USB Device Qualifier Descriptor -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE usb_dev_lpm_desc_t udc_device_lpm = { - .bos.bLength = sizeof(usb_dev_bos_desc_t), - .bos.bDescriptorType = USB_DT_BOS, - .bos.wTotalLength = LE16(sizeof(usb_dev_bos_desc_t) + sizeof(usb_dev_capa_ext_desc_t)), - .bos.bNumDeviceCaps = 1, - .capa_ext.bLength = sizeof(usb_dev_capa_ext_desc_t), - .capa_ext.bDescriptorType = USB_DT_DEVICE_CAPABILITY, - .capa_ext.bDevCapabilityType = USB_DC_USB20_EXTENSION, - .capa_ext.bmAttributes = USB_DC_EXT_LPM, -}; -#endif - -//! Structure for USB Device Configuration Descriptor -COMPILER_PACK_SET(1) -typedef struct { - usb_conf_desc_t conf; -#if UDI_CDC_PORT_NB == 1 - udi_cdc_comm_desc_t udi_cdc_comm_0; - udi_cdc_data_desc_t udi_cdc_data_0; -#else -# define UDI_CDC_DESC_STRUCTURE(index, unused) \ - usb_iad_desc_t udi_cdc_iad_##index; \ - udi_cdc_comm_desc_t udi_cdc_comm_##index; \ - udi_cdc_data_desc_t udi_cdc_data_##index; - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~) -# undef UDI_CDC_DESC_STRUCTURE -#endif -} udc_desc_t; -COMPILER_PACK_RESET() - -//! USB Device Configuration Descriptor filled for full and high speed -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { - .conf.bLength = sizeof(usb_conf_desc_t), - .conf.bDescriptorType = USB_DT_CONFIGURATION, - .conf.wTotalLength = LE16(sizeof(udc_desc_t)), - .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, - .conf.bConfigurationValue = 1, - .conf.iConfiguration = 0, - .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, - .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), -#if UDI_CDC_PORT_NB == 1 - .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, - .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS, -#else -# define UDI_CDC_DESC_FS(index, unused) \ - .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\ - .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\ - .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS, - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~) -# undef UDI_CDC_DESC_FS -#endif -}; - -#ifdef USB_DEVICE_HS_SUPPORT -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { - .conf.bLength = sizeof(usb_conf_desc_t), - .conf.bDescriptorType = USB_DT_CONFIGURATION, - .conf.wTotalLength = LE16(sizeof(udc_desc_t)), - .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, - .conf.bConfigurationValue = 1, - .conf.iConfiguration = 0, - .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, - .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), -#if UDI_CDC_PORT_NB == 1 - .udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0, - .udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS, -#else -# define UDI_CDC_DESC_HS(index, unused) \ - .udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \ - .udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \ - .udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS, - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~) -# undef UDI_CDC_DESC_HS -#endif -}; -#endif - -/** - * \name UDC structures which content all USB Device definitions - */ -//@{ - -//! Associate an UDI for each USB interface -UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { -# define UDI_CDC_API(index, unused) \ - &udi_api_cdc_comm, \ - &udi_api_cdc_data, - MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~) -# undef UDI_CDC_API -}; - -//! Add UDI with USB Descriptors FS & HS -UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { { - .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, - .udi_apis = udi_apis, -}}; -#ifdef USB_DEVICE_HS_SUPPORT -UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { { - .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, - .udi_apis = udi_apis, -}}; -#endif - -//! Add all information about USB Device in global structure for UDC -UDC_DESC_STORAGE udc_config_t udc_config = { - .confdev_lsfs = &udc_device_desc, - .conf_lsfs = udc_config_fs, -#ifdef USB_DEVICE_HS_SUPPORT - .confdev_hs = &udc_device_desc, - .qualifier = &udc_device_qual, - .conf_hs = udc_config_hs, -#endif -#ifdef USB_DEVICE_LPM_SUPPORT - .conf_bos = &udc_device_lpm.bos, -#else - .conf_bos = NULL, -#endif -}; - -//@} -//@} - -#endif // SDSUPPORT - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/udi_composite_desc.c b/src/HAL/DUE/usb/udi_composite_desc.c deleted file mode 100644 index da74fbe..0000000 --- a/src/HAL/DUE/usb/udi_composite_desc.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * \file - * - * \brief Descriptors for an USB Composite Device - * - * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "conf_usb.h" -#include "udd.h" -#include "udc_desc.h" - -#if ENABLED(SDSUPPORT) - -/** - * \defgroup udi_group_desc Descriptors for a USB Device - * composite - * - * @{ - */ - -/**INDENT-OFF**/ - -//! USB Device Descriptor -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { - .bLength = sizeof(usb_dev_desc_t), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = LE16(USB_V2_0), - .bDeviceClass = CDC_CLASS_MULTI, - .bDeviceSubClass = CDC_SUBCLASS_ACM, - .bDeviceProtocol = CDC_PROTOCOL_V25TER, - .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, - .idVendor = LE16(USB_DEVICE_VENDOR_ID), - .idProduct = LE16(USB_DEVICE_PRODUCT_ID), - .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) - | USB_DEVICE_MINOR_VERSION), -#ifdef USB_DEVICE_MANUFACTURE_NAME - .iManufacturer = 1, -#else - .iManufacturer = 0, // No manufacture string -#endif -#ifdef USB_DEVICE_PRODUCT_NAME - .iProduct = 2, -#else - .iProduct = 0, // No product string -#endif -#if (defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER) - .iSerialNumber = 3, -#else - .iSerialNumber = 0, // No serial string -#endif - .bNumConfigurations = 1 -}; - - -#ifdef USB_DEVICE_HS_SUPPORT -//! USB Device Qualifier Descriptor for HS -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { - .bLength = sizeof(usb_dev_qual_desc_t), - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - .bcdUSB = LE16(USB_V2_0), - .bDeviceClass = CDC_CLASS_MULTI, - .bDeviceSubClass = CDC_SUBCLASS_ACM, - .bDeviceProtocol = CDC_PROTOCOL_V25TER, - .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, - .bNumConfigurations = 1 -}; -#endif - -//! Structure for USB Device Configuration Descriptor -COMPILER_PACK_SET(1) -typedef struct { - usb_conf_desc_t conf; - UDI_COMPOSITE_DESC_T; -} udc_desc_t; -COMPILER_PACK_RESET() - -//! USB Device Configuration Descriptor filled for FS -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { - .conf.bLength = sizeof(usb_conf_desc_t), - .conf.bDescriptorType = USB_DT_CONFIGURATION, - .conf.wTotalLength = LE16(sizeof(udc_desc_t)), - .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, - .conf.bConfigurationValue = 1, - .conf.iConfiguration = 0, - .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, - .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), - UDI_COMPOSITE_DESC_FS -}; - -#ifdef USB_DEVICE_HS_SUPPORT -//! USB Device Configuration Descriptor filled for HS -COMPILER_WORD_ALIGNED -UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { - .conf.bLength = sizeof(usb_conf_desc_t), - .conf.bDescriptorType = USB_DT_CONFIGURATION, - .conf.wTotalLength = LE16(sizeof(udc_desc_t)), - .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, - .conf.bConfigurationValue = 1, - .conf.iConfiguration = 0, - .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, - .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), - UDI_COMPOSITE_DESC_HS -}; -#endif - - -/** - * \name UDC structures which contains all USB Device definitions - */ -//@{ - -//! Associate an UDI for each USB interface -UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { - UDI_COMPOSITE_API -}; - -//! Add UDI with USB Descriptors FS -UDC_DESC_STORAGE udc_config_speed_t udc_config_lsfs[1] = {{ - .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, - .udi_apis = udi_apis, -}}; - -#ifdef USB_DEVICE_HS_SUPPORT -//! Add UDI with USB Descriptors HS -UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = {{ - .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, - .udi_apis = udi_apis, -}}; -#endif - -//! Add all information about USB Device in global structure for UDC -UDC_DESC_STORAGE udc_config_t udc_config = { - .confdev_lsfs = &udc_device_desc, - .conf_lsfs = udc_config_lsfs, -#ifdef USB_DEVICE_HS_SUPPORT - .confdev_hs = &udc_device_desc, - .qualifier = &udc_device_qual, - .conf_hs = udc_config_hs, -#endif -}; - -//@} -/**INDENT-ON**/ -//@} - -#endif // ARDUINO_ARCH_SAM - -#endif // SDSUPPORT diff --git a/src/HAL/DUE/usb/udi_msc.c b/src/HAL/DUE/usb/udi_msc.c deleted file mode 100644 index dd34048..0000000 --- a/src/HAL/DUE/usb/udi_msc.c +++ /dev/null @@ -1,1132 +0,0 @@ -/** - * \file - * - * \brief USB Device Mass Storage Class (MSC) interface. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "usb_protocol_msc.h" -#include "spc_protocol.h" -#include "sbc_protocol.h" -#include "udd.h" -#include "udc.h" -#include "udi_msc.h" -#include "ctrl_access.h" -#include - -#if ENABLED(SDSUPPORT) - -#ifndef UDI_MSC_NOTIFY_TRANS_EXT -# define UDI_MSC_NOTIFY_TRANS_EXT() -#endif - -/** - * \ingroup udi_msc_group - * \defgroup udi_msc_group_udc Interface with USB Device Core (UDC) - * - * Structures and functions required by UDC. - * - * @{ - */ -bool udi_msc_enable(void); -void udi_msc_disable(void); -bool udi_msc_setup(void); -uint8_t udi_msc_getsetting(void); - -//! Global structure which contains standard UDI API for UDC -UDC_DESC_STORAGE udi_api_t udi_api_msc = { - .enable = udi_msc_enable, - .disable = udi_msc_disable, - .setup = udi_msc_setup, - .getsetting = udi_msc_getsetting, - .sof_notify = NULL, -}; -//@} - - -/** - * \ingroup udi_msc_group - * \defgroup udi_msc_group_internal Implementation of UDI MSC - * - * Class internal implementation - * @{ - */ - -//! Static block size for all memories -#define UDI_MSC_BLOCK_SIZE 512L - -/** - * \name Variables to manage SCSI requests - */ -//@{ - -//! Structure to receive a CBW packet -UDC_BSS(4) static struct usb_msc_cbw udi_msc_cbw; -//! Structure to send a CSW packet -UDC_DATA(4) static struct usb_msc_csw udi_msc_csw = - {.dCSWSignature = CPU_TO_BE32(USB_CSW_SIGNATURE) }; -//! Number of lun -UDC_DATA(4) static uint8_t udi_msc_nb_lun = 0; -//! Structure with current SCSI sense data -UDC_BSS(4) static struct scsi_request_sense_data udi_msc_sense; - -/** - * \name Variables to manage the background read/write SCSI commands - */ -//@{ -//! True if an invalid CBW command has been detected -static bool udi_msc_b_cbw_invalid = false; -//! True if a transfer command must be processed -static bool udi_msc_b_trans_req = false; -//! True if it is a read command, else write command -static bool udi_msc_b_read; -//! Memory address to execute the command -static uint32_t udi_msc_addr; -//! Number of block to transfer -static uint16_t udi_msc_nb_block; -//! Signal end of transfer, if true -volatile bool udi_msc_b_ack_trans = true; -//! Status of transfer, aborted if true -volatile bool udi_msc_b_abort_trans; -//! Signal (re)init of transfer, if true (by reset/reconnect) -volatile bool udi_msc_b_reset_trans = true; -//@} - -//@} - - -/** - * \name Internal routines - */ -//@{ - -/** - * \name Routines to process CBW packet - */ -//@{ - -/** - * \brief Stall CBW request - */ -static void udi_msc_cbw_invalid(void); - -/** - * \brief Stall CSW request - */ -static void udi_msc_csw_invalid(void); - -/** - * \brief Links a callback and buffer on endpoint OUT reception - * - * Called by: - * - enable interface - * - at the end of previous command after sending the CSW - */ -static void udi_msc_cbw_wait(void); - -/** - * \brief Callback called after CBW reception - * Called by UDD when a transfer is finished or aborted - * - * \param status UDD_EP_TRANSFER_OK, if transfer is finished - * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted - * \param nb_received number of data transferred - */ -static void udi_msc_cbw_received(udd_ep_status_t status, - iram_size_t nb_received, udd_ep_id_t ep); - -/** - * \brief Function to check the CBW length and direction - * Call it after SCSI command decode to check integrity of command - * - * \param alloc_len number of bytes that device want transfer - * \param dir_flag Direction of transfer (USB_CBW_DIRECTION_IN/OUT) - * - * \retval true if the command can be processed - */ -static bool udi_msc_cbw_validate(uint32_t alloc_len, uint8_t dir_flag); -//@} - - -/** - * \name Routines to process small data packet - */ -//@{ - -/** - * \brief Sends data on MSC IN endpoint - * Called by SCSI command which must send a data to host followed by a CSW - * - * \param buffer Internal RAM buffer to send - * \param buf_size Size of buffer to send - */ -static void udi_msc_data_send(uint8_t * buffer, uint8_t buf_size); - -/** - * \brief Callback called after data sent - * It start CSW packet process - * - * \param status UDD_EP_TRANSFER_OK, if transfer finish - * \param status UDD_EP_TRANSFER_ABORT, if transfer aborted - * \param nb_sent number of data transferred - */ -static void udi_msc_data_sent(udd_ep_status_t status, iram_size_t nb_sent, - udd_ep_id_t ep); -//@} - - -/** - * \name Routines to process CSW packet - */ -//@{ - -/** - * \brief Build CSW packet and send it - * - * Called at the end of SCSI command - */ -static void udi_msc_csw_process(void); - -/** - * \brief Sends CSW - * - * Called by #udi_msc_csw_process() - * or UDD callback when endpoint halt is cleared - */ -void udi_msc_csw_send(void); - -/** - * \brief Callback called after CSW sent - * It restart CBW reception. - * - * \param status UDD_EP_TRANSFER_OK, if transfer is finished - * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted - * \param nb_sent number of data transferred - */ -static void udi_msc_csw_sent(udd_ep_status_t status, iram_size_t nb_sent, - udd_ep_id_t ep); -//@} - - -/** - * \name Routines manage sense data - */ -//@{ - -/** - * \brief Reinitialize sense data. - */ -static void udi_msc_clear_sense(void); - -/** - * \brief Update sense data with new value to signal a fail - * - * \param sense_key Sense key - * \param add_sense Additional Sense Code - * \param lba LBA corresponding at error - */ -static void udi_msc_sense_fail(uint8_t sense_key, uint16_t add_sense, - uint32_t lba); - -/** - * \brief Update sense data with new value to signal success - */ -static void udi_msc_sense_pass(void); - -/** - * \brief Update sense data to signal that memory is not present - */ -static void udi_msc_sense_fail_not_present(void); - -/** - * \brief Update sense data to signal that memory is busy - */ -static void udi_msc_sense_fail_busy_or_change(void); - -/** - * \brief Update sense data to signal a hardware error on memory - */ -static void udi_msc_sense_fail_hardware(void); - -/** - * \brief Update sense data to signal that memory is protected - */ -static void udi_msc_sense_fail_protected(void); - -/** - * \brief Update sense data to signal that CDB fields are not valid - */ -static void udi_msc_sense_fail_cdb_invalid(void); - -/** - * \brief Update sense data to signal that command is not supported - */ -static void udi_msc_sense_command_invalid(void); -//@} - - -/** - * \name Routines manage SCSI Commands - */ -//@{ - -/** - * \brief Process SPC Request Sense command - * Returns error information about last command - */ -static void udi_msc_spc_requestsense(void); - -/** - * \brief Process SPC Inquiry command - * Returns information (name,version) about disk - */ -static void udi_msc_spc_inquiry(void); - -/** - * \brief Checks state of disk - * - * \retval true if disk is ready, otherwise false and updates sense data - */ -static bool udi_msc_spc_testunitready_global(void); - -/** - * \brief Process test unit ready command - * Returns state of logical unit - */ -static void udi_msc_spc_testunitready(void); - -/** - * \brief Process prevent allow medium removal command - */ -static void udi_msc_spc_prevent_allow_medium_removal(void); - -/** - * \brief Process mode sense command - * - * \param b_sense10 Sense10 SCSI command, if true - * \param b_sense10 Sense6 SCSI command, if false - */ -static void udi_msc_spc_mode_sense(bool b_sense10); - -/** - * \brief Process start stop command - */ -static void udi_msc_sbc_start_stop(void); - -/** - * \brief Process read capacity command - */ -static void udi_msc_sbc_read_capacity(void); - -/** - * \brief Process read10 or write10 command - * - * \param b_read Read transfer, if true, - * \param b_read Write transfer, if false - */ -static void udi_msc_sbc_trans(bool b_read); -//@} - -//@} - - -bool udi_msc_enable(void) -{ - uint8_t lun; - udi_msc_b_trans_req = false; - udi_msc_b_cbw_invalid = false; - udi_msc_b_ack_trans = true; - udi_msc_b_reset_trans = true; - udi_msc_nb_lun = get_nb_lun(); - if (0 == udi_msc_nb_lun) - return false; // No lun available, then not authorize to enable interface - udi_msc_nb_lun--; - // Call application callback - // to initialize memories or signal that interface is enabled - if (!UDI_MSC_ENABLE_EXT()) - return false; - // Load the medium on each LUN - for (lun = 0; lun <= udi_msc_nb_lun; lun ++) { - mem_unload(lun, false); - } - // Start MSC process by CBW reception - udi_msc_cbw_wait(); - return true; -} - - -void udi_msc_disable(void) -{ - udi_msc_b_trans_req = false; - udi_msc_b_ack_trans = true; - udi_msc_b_reset_trans = true; - UDI_MSC_DISABLE_EXT(); -} - - -bool udi_msc_setup(void) -{ - if (Udd_setup_is_in()) { - // Requests Interface GET - if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { - // Requests Class Interface Get - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_MSC_GET_MAX_LUN: - // Give the number of memories available - if (1 != udd_g_ctrlreq.req.wLength) - return false; // Error for USB host - if (0 != udd_g_ctrlreq.req.wValue) - return false; - udd_g_ctrlreq.payload = &udi_msc_nb_lun; - udd_g_ctrlreq.payload_size = 1; - return true; - } - } - } - if (Udd_setup_is_out()) { - // Requests Interface SET - if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { - // Requests Class Interface Set - switch (udd_g_ctrlreq.req.bRequest) { - case USB_REQ_MSC_BULK_RESET: - // Reset MSC interface - if (0 != udd_g_ctrlreq.req.wLength) - return false; - if (0 != udd_g_ctrlreq.req.wValue) - return false; - udi_msc_b_cbw_invalid = false; - udi_msc_b_trans_req = false; - // Abort all tasks (transfer or clear stall wait) on endpoints - udd_ep_abort(UDI_MSC_EP_OUT); - udd_ep_abort(UDI_MSC_EP_IN); - // Restart by CBW wait - udi_msc_cbw_wait(); - return true; - } - } - } - return false; // Not supported request -} - -uint8_t udi_msc_getsetting(void) -{ - return 0; // MSC don't have multiple alternate setting -} - - -// ------------------------ -//------- Routines to process CBW packet - -static void udi_msc_cbw_invalid(void) -{ - if (!udi_msc_b_cbw_invalid) - return; // Don't re-stall endpoint if error reset by setup - udd_ep_set_halt(UDI_MSC_EP_OUT); - // If stall cleared then re-stall it. Only Setup MSC Reset can clear it - udd_ep_wait_stall_clear(UDI_MSC_EP_OUT, udi_msc_cbw_invalid); -} - -static void udi_msc_csw_invalid(void) -{ - if (!udi_msc_b_cbw_invalid) - return; // Don't re-stall endpoint if error reset by setup - udd_ep_set_halt(UDI_MSC_EP_IN); - // If stall cleared then re-stall it. Only Setup MSC Reset can clear it - udd_ep_wait_stall_clear(UDI_MSC_EP_IN, udi_msc_csw_invalid); -} - -static void udi_msc_cbw_wait(void) -{ - // Register buffer and callback on OUT endpoint - if (!udd_ep_run(UDI_MSC_EP_OUT, true, - (uint8_t *) & udi_msc_cbw, - sizeof(udi_msc_cbw), - udi_msc_cbw_received)) { - // OUT endpoint not available (halted), then wait a clear of halt. - udd_ep_wait_stall_clear(UDI_MSC_EP_OUT, udi_msc_cbw_wait); - } -} - - -static void udi_msc_cbw_received(udd_ep_status_t status, - iram_size_t nb_received, udd_ep_id_t ep) -{ - UNUSED(ep); - // Check status of transfer - if (UDD_EP_TRANSFER_OK != status) { - // Transfer aborted - // Now wait MSC setup reset to relaunch CBW reception - return; - } - // Check CBW integrity: - // transfer status/CBW length/CBW signature - if ((sizeof(udi_msc_cbw) != nb_received) - || (udi_msc_cbw.dCBWSignature != - CPU_TO_BE32(USB_CBW_SIGNATURE))) { - // (5.2.1) Devices receiving a CBW with an invalid signature should stall - // further traffic on the Bulk In pipe, and either stall further traffic - // or accept and discard further traffic on the Bulk Out pipe, until - // reset recovery. - udi_msc_b_cbw_invalid = true; - udi_msc_cbw_invalid(); - udi_msc_csw_invalid(); - return; - } - // Check LUN asked - udi_msc_cbw.bCBWLUN &= USB_CBW_LUN_MASK; - if (udi_msc_cbw.bCBWLUN > udi_msc_nb_lun) { - // Bad LUN, then stop command process - udi_msc_sense_fail_cdb_invalid(); - udi_msc_csw_process(); - return; - } - // Prepare CSW residue field with the size requested - udi_msc_csw.dCSWDataResidue = - le32_to_cpu(udi_msc_cbw.dCBWDataTransferLength); - - // Decode opcode - switch (udi_msc_cbw.CDB[0]) { - case SPC_REQUEST_SENSE: - udi_msc_spc_requestsense(); - break; - - case SPC_INQUIRY: - udi_msc_spc_inquiry(); - break; - - case SPC_MODE_SENSE6: - udi_msc_spc_mode_sense(false); - break; - case SPC_MODE_SENSE10: - udi_msc_spc_mode_sense(true); - break; - - case SPC_TEST_UNIT_READY: - udi_msc_spc_testunitready(); - break; - - case SBC_READ_CAPACITY10: - udi_msc_sbc_read_capacity(); - break; - - case SBC_START_STOP_UNIT: - udi_msc_sbc_start_stop(); - break; - - // Accepts request to support plug/plug in case of card reader - case SPC_PREVENT_ALLOW_MEDIUM_REMOVAL: - udi_msc_spc_prevent_allow_medium_removal(); - break; - - // Accepts request to support full format from Windows - case SBC_VERIFY10: - udi_msc_sense_pass(); - udi_msc_csw_process(); - break; - - case SBC_READ10: - udi_msc_sbc_trans(true); - break; - - case SBC_WRITE10: - udi_msc_sbc_trans(false); - break; - - default: - udi_msc_sense_command_invalid(); - udi_msc_csw_process(); - break; - } -} - - -static bool udi_msc_cbw_validate(uint32_t alloc_len, uint8_t dir_flag) -{ - /* - * The following cases should result in a phase error: - * - Case 2: Hn < Di - * - Case 3: Hn < Do - * - Case 7: Hi < Di - * - Case 8: Hi <> Do - * - Case 10: Ho <> Di - * - Case 13: Ho < Do - */ - if (((udi_msc_cbw.bmCBWFlags ^ dir_flag) & USB_CBW_DIRECTION_IN) - || (udi_msc_csw.dCSWDataResidue < alloc_len)) { - udi_msc_sense_fail_cdb_invalid(); - udi_msc_csw_process(); - return false; - } - - /* - * The following cases should result in a stall and nonzero - * residue: - * - Case 4: Hi > Dn - * - Case 5: Hi > Di - * - Case 9: Ho > Dn - * - Case 11: Ho > Do - */ - return true; -} - - -// ------------------------ -//------- Routines to process small data packet - -static void udi_msc_data_send(uint8_t * buffer, uint8_t buf_size) -{ - // Sends data on IN endpoint - if (!udd_ep_run(UDI_MSC_EP_IN, true, - buffer, buf_size, udi_msc_data_sent)) { - // If endpoint not available, then exit process command - udi_msc_sense_fail_hardware(); - udi_msc_csw_process(); - } -} - - -static void udi_msc_data_sent(udd_ep_status_t status, iram_size_t nb_sent, - udd_ep_id_t ep) -{ - UNUSED(ep); - if (UDD_EP_TRANSFER_OK != status) { - // Error protocol - // Now wait MSC setup reset to relaunch CBW reception - return; - } - // Update sense data - udi_msc_sense_pass(); - // Update CSW - udi_msc_csw.dCSWDataResidue -= nb_sent; - udi_msc_csw_process(); -} - - -// ------------------------ -//------- Routines to process CSW packet - -static void udi_msc_csw_process(void) -{ - if (0 != udi_msc_csw.dCSWDataResidue) { - // Residue not NULL - // then STALL next request from USB host on corresponding endpoint - if (udi_msc_cbw.bmCBWFlags & USB_CBW_DIRECTION_IN) - udd_ep_set_halt(UDI_MSC_EP_IN); - else - udd_ep_set_halt(UDI_MSC_EP_OUT); - } - // Prepare and send CSW - udi_msc_csw.dCSWTag = udi_msc_cbw.dCBWTag; - udi_msc_csw.dCSWDataResidue = cpu_to_le32(udi_msc_csw.dCSWDataResidue); - udi_msc_csw_send(); -} - - -void udi_msc_csw_send(void) -{ - // Sends CSW on IN endpoint - if (!udd_ep_run(UDI_MSC_EP_IN, false, - (uint8_t *) & udi_msc_csw, - sizeof(udi_msc_csw), - udi_msc_csw_sent)) { - // Endpoint not available - // then restart CSW sent when endpoint IN STALL will be cleared - udd_ep_wait_stall_clear(UDI_MSC_EP_IN, udi_msc_csw_send); - } -} - - -static void udi_msc_csw_sent(udd_ep_status_t status, iram_size_t nb_sent, - udd_ep_id_t ep) -{ - UNUSED(ep); - UNUSED(status); - UNUSED(nb_sent); - // CSW is sent or not - // In all case, restart process and wait CBW - udi_msc_cbw_wait(); -} - - -// ------------------------ -//------- Routines manage sense data - -static void udi_msc_clear_sense(void) -{ - memset((uint8_t*)&udi_msc_sense, 0, sizeof(struct scsi_request_sense_data)); - udi_msc_sense.valid_reponse_code = SCSI_SENSE_VALID | SCSI_SENSE_CURRENT; - udi_msc_sense.AddSenseLen = SCSI_SENSE_ADDL_LEN(sizeof(udi_msc_sense)); -} - -static void udi_msc_sense_fail(uint8_t sense_key, uint16_t add_sense, - uint32_t lba) -{ - udi_msc_clear_sense(); - udi_msc_csw.bCSWStatus = USB_CSW_STATUS_FAIL; - udi_msc_sense.sense_flag_key = sense_key; - udi_msc_sense.information[0] = lba >> 24; - udi_msc_sense.information[1] = lba >> 16; - udi_msc_sense.information[2] = lba >> 8; - udi_msc_sense.information[3] = lba; - udi_msc_sense.AddSenseCode = add_sense >> 8; - udi_msc_sense.AddSnsCodeQlfr = add_sense; -} - -static void udi_msc_sense_pass(void) -{ - udi_msc_clear_sense(); - udi_msc_csw.bCSWStatus = USB_CSW_STATUS_PASS; -} - - -static void udi_msc_sense_fail_not_present(void) -{ - udi_msc_sense_fail(SCSI_SK_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT, 0); -} - -static void udi_msc_sense_fail_busy_or_change(void) -{ - udi_msc_sense_fail(SCSI_SK_UNIT_ATTENTION, - SCSI_ASC_NOT_READY_TO_READY_CHANGE, 0); -} - -static void udi_msc_sense_fail_hardware(void) -{ - udi_msc_sense_fail(SCSI_SK_HARDWARE_ERROR, - SCSI_ASC_NO_ADDITIONAL_SENSE_INFO, 0); -} - -static void udi_msc_sense_fail_protected(void) -{ - udi_msc_sense_fail(SCSI_SK_DATA_PROTECT, SCSI_ASC_WRITE_PROTECTED, 0); -} - -static void udi_msc_sense_fail_cdb_invalid(void) -{ - udi_msc_sense_fail(SCSI_SK_ILLEGAL_REQUEST, - SCSI_ASC_INVALID_FIELD_IN_CDB, 0); -} - -static void udi_msc_sense_command_invalid(void) -{ - udi_msc_sense_fail(SCSI_SK_ILLEGAL_REQUEST, - SCSI_ASC_INVALID_COMMAND_OPERATION_CODE, 0); -} - - -// ------------------------ -//------- Routines manage SCSI Commands - -static void udi_msc_spc_requestsense(void) -{ - uint8_t length = udi_msc_cbw.CDB[4]; - - // Can't send more than sense data length - if (length > sizeof(udi_msc_sense)) - length = sizeof(udi_msc_sense); - - if (!udi_msc_cbw_validate(length, USB_CBW_DIRECTION_IN)) - return; - // Send sense data - udi_msc_data_send((uint8_t*)&udi_msc_sense, length); -} - - -static void udi_msc_spc_inquiry(void) -{ - uint8_t length, i; - UDC_DATA(4) - // Constant inquiry data for all LUNs - static struct scsi_inquiry_data udi_msc_inquiry_data = { - .pq_pdt = SCSI_INQ_PQ_CONNECTED | SCSI_INQ_DT_DIR_ACCESS, - .version = SCSI_INQ_VER_SPC, - .flags3 = SCSI_INQ_RSP_SPC2, - .addl_len = SCSI_INQ_ADDL_LEN(sizeof(struct scsi_inquiry_data)), - .vendor_id = {UDI_MSC_GLOBAL_VENDOR_ID}, - .product_rev = {UDI_MSC_GLOBAL_PRODUCT_VERSION}, - }; - - length = udi_msc_cbw.CDB[4]; - - // Can't send more than inquiry data length - if (length > sizeof(udi_msc_inquiry_data)) - length = sizeof(udi_msc_inquiry_data); - - if (!udi_msc_cbw_validate(length, USB_CBW_DIRECTION_IN)) - return; - if ((0 != (udi_msc_cbw.CDB[1] & (SCSI_INQ_REQ_EVPD | SCSI_INQ_REQ_CMDT))) - || (0 != udi_msc_cbw.CDB[2])) { - // CMDT and EPVD bits are not at 0 - // PAGE or OPERATION CODE fields are not empty - // = No standard inquiry asked - udi_msc_sense_fail_cdb_invalid(); // Command is unsupported - udi_msc_csw_process(); - return; - } - - udi_msc_inquiry_data.flags1 = mem_removal(udi_msc_cbw.bCBWLUN) ? - SCSI_INQ_RMB : 0; - - //* Fill product ID field - // Copy name in product id field - memcpy(udi_msc_inquiry_data.product_id, - mem_name(udi_msc_cbw.bCBWLUN)+1, // To remove first '"' - sizeof(udi_msc_inquiry_data.product_id)); - - // Search end of name '/0' or '"' - i = 0; - while (sizeof(udi_msc_inquiry_data.product_id) != i) { - if ((0 == udi_msc_inquiry_data.product_id[i]) - || ('"' == udi_msc_inquiry_data.product_id[i])) { - break; - } - i++; - } - // Padding with space char - while (sizeof(udi_msc_inquiry_data.product_id) != i) { - udi_msc_inquiry_data.product_id[i] = ' '; - i++; - } - - // Send inquiry data - udi_msc_data_send((uint8_t *) & udi_msc_inquiry_data, length); -} - - -static bool udi_msc_spc_testunitready_global(void) -{ - switch (mem_test_unit_ready(udi_msc_cbw.bCBWLUN)) { - case CTRL_GOOD: - return true; // Don't change sense data - case CTRL_BUSY: - udi_msc_sense_fail_busy_or_change(); - break; - case CTRL_NO_PRESENT: - udi_msc_sense_fail_not_present(); - break; - case CTRL_FAIL: - default: - udi_msc_sense_fail_hardware(); - break; - } - return false; -} - - -static void udi_msc_spc_testunitready(void) -{ - if (udi_msc_spc_testunitready_global()) { - // LUN ready, then update sense data with status pass - udi_msc_sense_pass(); - } - // Send status in CSW packet - udi_msc_csw_process(); -} - - -static void udi_msc_spc_mode_sense(bool b_sense10) -{ - // Union of all mode sense structures - union sense_6_10 { - struct { - struct scsi_mode_param_header6 header; - struct spc_control_page_info_execpt sense_data; - } s6; - struct { - struct scsi_mode_param_header10 header; - struct spc_control_page_info_execpt sense_data; - } s10; - }; - - uint8_t data_sense_lgt; - uint8_t mode; - uint8_t request_lgt; - uint8_t wp; - struct spc_control_page_info_execpt *ptr_mode; - UDC_BSS(4) static union sense_6_10 sense; - - // Clear all fields - memset(&sense, 0, sizeof(sense)); - - // Initialize process - if (b_sense10) { - request_lgt = udi_msc_cbw.CDB[8]; - ptr_mode = &sense.s10.sense_data; - data_sense_lgt = sizeof(struct scsi_mode_param_header10); - } else { - request_lgt = udi_msc_cbw.CDB[4]; - ptr_mode = &sense.s6.sense_data; - data_sense_lgt = sizeof(struct scsi_mode_param_header6); - } - - // No Block descriptor - - // Fill page(s) - mode = udi_msc_cbw.CDB[2] & SCSI_MS_MODE_ALL; - if ((SCSI_MS_MODE_INFEXP == mode) - || (SCSI_MS_MODE_ALL == mode)) { - // Informational exceptions control page (from SPC) - ptr_mode->page_code = - SCSI_MS_MODE_INFEXP; - ptr_mode->page_length = - SPC_MP_INFEXP_PAGE_LENGTH; - ptr_mode->mrie = - SPC_MP_INFEXP_MRIE_NO_SENSE; - data_sense_lgt += sizeof(struct spc_control_page_info_execpt); - } - // Can't send more than mode sense data length - if (request_lgt > data_sense_lgt) - request_lgt = data_sense_lgt; - if (!udi_msc_cbw_validate(request_lgt, USB_CBW_DIRECTION_IN)) - return; - - // Fill mode parameter header length - wp = (mem_wr_protect(udi_msc_cbw.bCBWLUN)) ? SCSI_MS_SBC_WP : 0; - - if (b_sense10) { - sense.s10.header.mode_data_length = - cpu_to_be16((data_sense_lgt - 2)); - //sense.s10.header.medium_type = 0; - sense.s10.header.device_specific_parameter = wp; - //sense.s10.header.block_descriptor_length = 0; - } else { - sense.s6.header.mode_data_length = data_sense_lgt - 1; - //sense.s6.header.medium_type = 0; - sense.s6.header.device_specific_parameter = wp; - //sense.s6.header.block_descriptor_length = 0; - } - - // Send mode sense data - udi_msc_data_send((uint8_t *) & sense, request_lgt); -} - - -static void udi_msc_spc_prevent_allow_medium_removal(void) -{ - uint8_t prevent = udi_msc_cbw.CDB[4]; - if (0 == prevent) { - udi_msc_sense_pass(); - } else { - udi_msc_sense_fail_cdb_invalid(); // Command is unsupported - } - udi_msc_csw_process(); -} - - -static void udi_msc_sbc_start_stop(void) -{ - bool start = 0x1 & udi_msc_cbw.CDB[4]; - bool loej = 0x2 & udi_msc_cbw.CDB[4]; - if (loej) { - mem_unload(udi_msc_cbw.bCBWLUN, !start); - } - udi_msc_sense_pass(); - udi_msc_csw_process(); -} - - -static void udi_msc_sbc_read_capacity(void) -{ - UDC_BSS(4) static struct sbc_read_capacity10_data udi_msc_capacity; - - if (!udi_msc_cbw_validate(sizeof(udi_msc_capacity), - USB_CBW_DIRECTION_IN)) - return; - - // Get capacity of LUN - switch (mem_read_capacity(udi_msc_cbw.bCBWLUN, - &udi_msc_capacity.max_lba)) { - case CTRL_GOOD: - break; - case CTRL_BUSY: - udi_msc_sense_fail_busy_or_change(); - udi_msc_csw_process(); - return; - case CTRL_NO_PRESENT: - udi_msc_sense_fail_not_present(); - udi_msc_csw_process(); - return; - default: - udi_msc_sense_fail_hardware(); - udi_msc_csw_process(); - return; - } - - // Format capacity data - udi_msc_capacity.block_len = CPU_TO_BE32(UDI_MSC_BLOCK_SIZE); - udi_msc_capacity.max_lba = cpu_to_be32(udi_msc_capacity.max_lba); - // Send the corresponding sense data - udi_msc_data_send((uint8_t *) & udi_msc_capacity, - sizeof(udi_msc_capacity)); -} - - -static void udi_msc_sbc_trans(bool b_read) -{ - uint32_t trans_size; - - if (!b_read) { - // Write operation then check Write Protect - if (mem_wr_protect(udi_msc_cbw.bCBWLUN)) { - // Write not authorized - udi_msc_sense_fail_protected(); - udi_msc_csw_process(); - return; - } - } - // Read/Write command fields (address and number of block) - MSB0(udi_msc_addr) = udi_msc_cbw.CDB[2]; - MSB1(udi_msc_addr) = udi_msc_cbw.CDB[3]; - MSB2(udi_msc_addr) = udi_msc_cbw.CDB[4]; - MSB3(udi_msc_addr) = udi_msc_cbw.CDB[5]; - MSB(udi_msc_nb_block) = udi_msc_cbw.CDB[7]; - LSB(udi_msc_nb_block) = udi_msc_cbw.CDB[8]; - - // Compute number of byte to transfer and valid it - trans_size = (uint32_t) udi_msc_nb_block *UDI_MSC_BLOCK_SIZE; - if (!udi_msc_cbw_validate(trans_size, - (b_read) ? USB_CBW_DIRECTION_IN : - USB_CBW_DIRECTION_OUT)) - return; - - // Record transfer request to do it in a task and not under interrupt - udi_msc_b_read = b_read; - udi_msc_b_trans_req = true; - UDI_MSC_NOTIFY_TRANS_EXT(); -} - - -bool udi_msc_process_trans(void) -{ - Ctrl_status status; - - if (!udi_msc_b_trans_req) - return false; // No Transfer request to do - udi_msc_b_trans_req = false; - udi_msc_b_reset_trans = false; - - // Start transfer - if (udi_msc_b_read) { - status = memory_2_usb(udi_msc_cbw.bCBWLUN, udi_msc_addr, - udi_msc_nb_block); - } else { - status = usb_2_memory(udi_msc_cbw.bCBWLUN, udi_msc_addr, - udi_msc_nb_block); - } - - // Check if transfer is aborted by reset - if (udi_msc_b_reset_trans) { - udi_msc_b_reset_trans = false; - return true; - } - - // Check status of transfer - switch (status) { - case CTRL_GOOD: - udi_msc_sense_pass(); - break; - case CTRL_BUSY: - udi_msc_sense_fail_busy_or_change(); - break; - case CTRL_NO_PRESENT: - udi_msc_sense_fail_not_present(); - break; - default: - case CTRL_FAIL: - udi_msc_sense_fail_hardware(); - break; - } - // Send status of transfer in CSW packet - udi_msc_csw_process(); - return true; -} - - -static void udi_msc_trans_ack(udd_ep_status_t status, iram_size_t n, - udd_ep_id_t ep) -{ - UNUSED(ep); - UNUSED(n); - // Update variable to signal the end of transfer - udi_msc_b_abort_trans = (UDD_EP_TRANSFER_OK != status) ? true : false; - udi_msc_b_ack_trans = true; -} - - -bool udi_msc_trans_block(bool b_read, uint8_t * block, iram_size_t block_size, - void (*callback) (udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)) -{ - if (!udi_msc_b_ack_trans) - return false; // No possible, transfer on going - - // Start transfer Internal RAM<->USB line - udi_msc_b_ack_trans = false; - if (!udd_ep_run((b_read) ? UDI_MSC_EP_IN : UDI_MSC_EP_OUT, - false, - block, - block_size, - (NULL == callback) ? udi_msc_trans_ack : - callback)) { - udi_msc_b_ack_trans = true; - return false; - } - if (NULL == callback) { - while (!udi_msc_b_ack_trans); - if (udi_msc_b_abort_trans) { - return false; - } - udi_msc_csw.dCSWDataResidue -= block_size; - return (!udi_msc_b_abort_trans); - } - udi_msc_csw.dCSWDataResidue -= block_size; - return true; -} - -//@} - -#endif // SDSUPPORT - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/udi_msc.h b/src/HAL/DUE/usb/udi_msc.h deleted file mode 100644 index 730dbc8..0000000 --- a/src/HAL/DUE/usb/udi_msc.h +++ /dev/null @@ -1,376 +0,0 @@ -/** - * \file - * - * \brief USB Device Mass Storage Class (MSC) interface definitions. - * - * Copyright (c) 2009-2016 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _UDI_MSC_H_ -#define _UDI_MSC_H_ - -#include "conf_usb.h" -#include "usb_protocol.h" -#include "usb_protocol_msc.h" -#include "udd.h" -#include "udc_desc.h" -#include "udi.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup udi_msc_group_udc - * @{ - */ -//! Global structure which contains standard UDI interface for UDC -extern UDC_DESC_STORAGE udi_api_t udi_api_msc; -//@} - -/** - * \ingroup udi_msc_group - * \defgroup udi_msc_group USB interface descriptors - * - * The following structures provide predefined USB interface descriptors. - * It must be used to define the final USB descriptors. - */ -//@{ - -//! Interface descriptor structure for MSC -typedef struct { - usb_iface_desc_t iface; - usb_ep_desc_t ep_in; - usb_ep_desc_t ep_out; -} udi_msc_desc_t; - -//! By default no string associated to this interface -#ifndef UDI_MSC_STRING_ID -#define UDI_MSC_STRING_ID 0 -#endif - -//! MSC endpoints size for full speed -#define UDI_MSC_EPS_SIZE_FS 64 -//! MSC endpoints size for high speed -#define UDI_MSC_EPS_SIZE_HS 512 - -//! Content of MSC interface descriptor for all speeds -#define UDI_MSC_DESC \ - .iface.bLength = sizeof(usb_iface_desc_t),\ - .iface.bDescriptorType = USB_DT_INTERFACE,\ - .iface.bInterfaceNumber = UDI_MSC_IFACE_NUMBER,\ - .iface.bAlternateSetting = 0,\ - .iface.bNumEndpoints = 2,\ - .iface.bInterfaceClass = MSC_CLASS,\ - .iface.bInterfaceSubClass = MSC_SUBCLASS_TRANSPARENT,\ - .iface.bInterfaceProtocol = MSC_PROTOCOL_BULK,\ - .iface.iInterface = UDI_MSC_STRING_ID,\ - .ep_in.bLength = sizeof(usb_ep_desc_t),\ - .ep_in.bDescriptorType = USB_DT_ENDPOINT,\ - .ep_in.bEndpointAddress = UDI_MSC_EP_IN,\ - .ep_in.bmAttributes = USB_EP_TYPE_BULK,\ - .ep_in.bInterval = 0,\ - .ep_out.bLength = sizeof(usb_ep_desc_t),\ - .ep_out.bDescriptorType = USB_DT_ENDPOINT,\ - .ep_out.bEndpointAddress = UDI_MSC_EP_OUT,\ - .ep_out.bmAttributes = USB_EP_TYPE_BULK,\ - .ep_out.bInterval = 0, - -//! Content of MSC interface descriptor for full speed only -#define UDI_MSC_DESC_FS {\ - UDI_MSC_DESC \ - .ep_in.wMaxPacketSize = LE16(UDI_MSC_EPS_SIZE_FS),\ - .ep_out.wMaxPacketSize = LE16(UDI_MSC_EPS_SIZE_FS),\ - } - -//! Content of MSC interface descriptor for high speed only -#define UDI_MSC_DESC_HS {\ - UDI_MSC_DESC \ - .ep_in.wMaxPacketSize = LE16(UDI_MSC_EPS_SIZE_HS),\ - .ep_out.wMaxPacketSize = LE16(UDI_MSC_EPS_SIZE_HS),\ - } -//@} - - -/** - * \ingroup udi_group - * \defgroup udi_msc_group USB Device Interface (UDI) for Mass Storage Class (MSC) - * - * Common APIs used by high level application to use this USB class. - * - * These routines are used by memory to transfer its data - * to/from USB MSC endpoints. - * - * See \ref udi_msc_quickstart. - * @{ - */ - -/** - * \brief Process the background read/write commands - * - * Routine called by the main loop - */ -bool udi_msc_process_trans(void); - -/** - * \brief Transfers data to/from USB MSC endpoints - * - * - * \param b_read Memory to USB, if true - * \param block Buffer on Internal RAM to send or fill - * \param block_size Buffer size to send or fill - * \param callback Function to call at the end of transfer. - * If NULL then the routine exit when transfer is finish. - * - * \return \c 1 if function was successfully done, otherwise \c 0. - */ -bool udi_msc_trans_block(bool b_read, uint8_t * block, iram_size_t block_size, - void (*callback) (udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)); -//@} - -#ifdef __cplusplus -} -#endif - - -/** - * \page udi_msc_quickstart Quick start guide for USB device Mass Storage module (UDI MSC) - * - * This is the quick start guide for the \ref udi_msc_group - * "USB device interface MSC module (UDI MSC)" with step-by-step instructions on - * how to configure and use the modules in a selection of use cases. - * - * The use cases contain several code fragments. The code fragments in the - * steps for setup can be copied into a custom initialization function, while - * the steps for usage can be copied into, e.g., the main application function. - * - * \section udi_msc_basic_use_case Basic use case - * In this basic use case, the "USB MSC (Single Interface Device)" module is used. - * The "USB MSC (Composite Device)" module usage is described in \ref udi_msc_use_cases - * "Advanced use cases". - * - * \section udi_msc_basic_use_case_setup Setup steps - * \subsection udi_msc_basic_use_case_setup_prereq Prerequisites - * \copydetails udc_basic_use_case_setup_prereq - * \subsection udi_msc_basic_use_case_setup_code Example code - * \copydetails udc_basic_use_case_setup_code - * \subsection udi_msc_basic_use_case_setup_flow Workflow - * \copydetails udc_basic_use_case_setup_flow - * - * \section udi_msc_basic_use_case_usage Usage steps - * - * \subsection udi_msc_basic_use_case_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for MSC - #define UDI_MSC_GLOBAL_VENDOR_ID \ - 'A', 'T', 'M', 'E', 'L', ' ', ' ', ' ' - #define UDI_MSC_GLOBAL_PRODUCT_VERSION \ - '1', '.', '0', '0' - #define UDI_MSC_ENABLE_EXT() my_callback_msc_enable() - extern bool my_callback_msc_enable(void); - #define UDI_MSC_DISABLE_EXT() my_callback_msc_disable() - extern void my_callback_msc_disable(void); - #include "udi_msc_conf.h" // At the end of conf_usb.h file -\endcode - * - * Add to application C-file: - * \code - static bool my_flag_autorize_msc_transfert = false; - bool my_callback_msc_enable(void) - { - my_flag_autorize_msc_transfert = true; - return true; - } - void my_callback_msc_disable(void) - { - my_flag_autorize_msc_transfert = false; - } - - void task(void) - { - udi_msc_process_trans(); - } -\endcode - * - * \subsection udi_msc_basic_use_case_setup_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following configuration, - * which is the USB device MSC configuration: - * - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for MSC \endcode - * \note The USB serial number is mandatory when a MSC interface is used. - * - \code //! Vendor name and Product version of MSC interface - #define UDI_MSC_GLOBAL_VENDOR_ID \ - 'A', 'T', 'M', 'E', 'L', ' ', ' ', ' ' - #define UDI_MSC_GLOBAL_PRODUCT_VERSION \ - '1', '.', '0', '0' \endcode - * \note The USB MSC interface requires a vendor ID (8 ASCII characters) - * and a product version (4 ASCII characters). - * - \code #define UDI_MSC_ENABLE_EXT() my_callback_msc_enable() - extern bool my_callback_msc_enable(void); \endcode - * \note After the device enumeration (detecting and identifying USB devices), - * the USB host starts the device configuration. When the USB MSC interface - * from the device is accepted by the host, the USB host enables this interface and the - * UDI_MSC_ENABLE_EXT() callback function is called and return true. - * Thus, when this event is received, the tasks which call - * udi_msc_process_trans() must be enabled. - * - \code #define UDI_MSC_DISABLE_EXT() my_callback_msc_disable() - extern void my_callback_msc_disable(void); \endcode - * \note When the USB device is unplugged or is reset by the USB host, the USB - * interface is disabled and the UDI_MSC_DISABLE_EXT() callback function - * is called. Thus, it is recommended to disable the task which is called udi_msc_process_trans(). - * -# The MSC is automatically linked with memory control access component - * which provides the memories interfaces. However, the memory data transfers - * must be done outside USB interrupt routine. This is done in the MSC process - * ("udi_msc_process_trans()") called by main loop: - * - \code * void task(void) { - udi_msc_process_trans(); - } \endcode - * -# The MSC speed depends on task periodicity. To get the best speed - * the notification callback "UDI_MSC_NOTIFY_TRANS_EXT" can be used to wakeup - * this task (Example, through a mutex): - * - \code #define UDI_MSC_NOTIFY_TRANS_EXT() msc_notify_trans() - void msc_notify_trans(void) { - wakeup_my_task(); - } \endcode - * - * \section udi_msc_use_cases Advanced use cases - * For more advanced use of the UDI MSC module, see the following use cases: - * - \subpage udi_msc_use_case_composite - * - \subpage udc_use_case_1 - * - \subpage udc_use_case_2 - * - \subpage udc_use_case_3 - * - \subpage udc_use_case_5 - * - \subpage udc_use_case_6 - */ - -/** - * \page udi_msc_use_case_composite MSC in a composite device - * - * A USB Composite Device is a USB Device which uses more than one USB class. - * In this use case, the "USB MSC (Composite Device)" module is used to - * create a USB composite device. Thus, this USB module can be associated with - * another "Composite Device" module, like "USB HID Mouse (Composite Device)". - * - * Also, you can refer to application note - * - * AVR4902 ASF - USB Composite Device. - * - * \section udi_msc_use_case_composite_setup Setup steps - * For the setup code of this use case to work, the - * \ref udi_msc_basic_use_case "basic use case" must be followed. - * - * \section udi_msc_use_case_composite_usage Usage steps - * - * \subsection udi_msc_use_case_composite_usage_code Example code - * Content of conf_usb.h: - * \code - #define USB_DEVICE_EP_CTRL_SIZE 64 - #define USB_DEVICE_NB_INTERFACE (X+1) - #define USB_DEVICE_MAX_EP (X+2) - - #define UDI_MSC_EP_IN (X | USB_EP_DIR_IN) - #define UDI_MSC_EP_OUT (Y | USB_EP_DIR_OUT) - #define UDI_MSC_IFACE_NUMBER X - - #define UDI_COMPOSITE_DESC_T \ - udi_msc_desc_t udi_msc; \ - ... - #define UDI_COMPOSITE_DESC_FS \ - .udi_msc = UDI_MSC_DESC, \ - ... - #define UDI_COMPOSITE_DESC_HS \ - .udi_msc = UDI_MSC_DESC, \ - ... - #define UDI_COMPOSITE_API \ - &udi_api_msc, \ - ... -\endcode - * - * \subsection udi_msc_use_case_composite_usage_flow Workflow - * -# Ensure that conf_usb.h is available and contains the following parameters - * required for a USB composite device configuration: - * - \code // Endpoint control size, This must be: - // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) - // - 64 for a high speed device - #define USB_DEVICE_EP_CTRL_SIZE 64 - // Total Number of interfaces on this USB device. - // Add 1 for MSC. - #define USB_DEVICE_NB_INTERFACE (X+1) - // Total number of endpoints on this USB device. - // This must include each endpoint for each interface. - // Add 2 for MSC. - #define USB_DEVICE_MAX_EP (X+2) \endcode - * -# Ensure that conf_usb.h contains the description of - * composite device: - * - \code // The endpoint numbers chosen by you for the MSC. - // The endpoint numbers starting from 1. - #define UDI_MSC_EP_IN (X | USB_EP_DIR_IN) - #define UDI_MSC_EP_OUT (Y | USB_EP_DIR_OUT) - // The interface index of an interface starting from 0 - #define UDI_MSC_IFACE_NUMBER X \endcode - * -# Ensure that conf_usb.h contains the following parameters - * required for a USB composite device configuration: - * - \code // USB Interfaces descriptor structure - #define UDI_COMPOSITE_DESC_T \ - ... - udi_msc_desc_t udi_msc; \ - ... - // USB Interfaces descriptor value for Full Speed - #define UDI_COMPOSITE_DESC_FS \ - ... - .udi_msc = UDI_MSC_DESC_FS, \ - ... - // USB Interfaces descriptor value for High Speed - #define UDI_COMPOSITE_DESC_HS \ - ... - .udi_msc = UDI_MSC_DESC_HS, \ - ... - // USB Interface APIs - #define UDI_COMPOSITE_API \ - ... - &udi_api_msc, \ - ... \endcode - * - \note The descriptors order given in the four lists above must be the - * same as the order defined by all interface indexes. The interface index - * orders are defined through UDI_X_IFACE_NUMBER defines. - */ - -#endif // _UDI_MSC_H_ diff --git a/src/HAL/DUE/usb/uotghs_device_due.c b/src/HAL/DUE/usb/uotghs_device_due.c deleted file mode 100644 index c7e8f8d..0000000 --- a/src/HAL/DUE/usb/uotghs_device_due.c +++ /dev/null @@ -1,2074 +0,0 @@ -/** - * \file - * - * \brief USB Device Driver for UOTGHS. Compliant with common UDD driver. - * - * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -/* - * Support and FAQ: visit Atmel Support - */ - -#ifdef ARDUINO_ARCH_SAM - -#include "compiler.h" -#include "uotghs_device_due.h" - -#include "conf_usb.h" -#include "sysclk.h" -#include "udd.h" -#include "uotghs_otg.h" -#include - -#ifndef UDD_NO_SLEEP_MGR -# include "sleep.h" -# include "sleepmgr.h" -#endif - -#if !(SAM3XA) -# error The current UOTGHS Device Driver supports only SAM3X and SAM3A. -#endif -#ifndef UDD_USB_INT_FUN -# define UDD_USB_INT_FUN UOTGHS_Handler -#endif - -#ifndef UDD_USB_INT_LEVEL -# define UDD_USB_INT_LEVEL 5 // By default USB interrupt have low priority -#endif - -#define UDD_EP_USED(ep) (USB_DEVICE_MAX_EP >= ep) - -#if ( (UDD_EP_USED( 1) && Is_udd_endpoint_dma_supported( 1)) \ - ||(UDD_EP_USED( 2) && Is_udd_endpoint_dma_supported( 2)) \ - ||(UDD_EP_USED( 3) && Is_udd_endpoint_dma_supported( 3)) \ - ||(UDD_EP_USED( 4) && Is_udd_endpoint_dma_supported( 4)) \ - ||(UDD_EP_USED( 5) && Is_udd_endpoint_dma_supported( 5)) \ - ||(UDD_EP_USED( 6) && Is_udd_endpoint_dma_supported( 6)) \ - ||(UDD_EP_USED( 7) && Is_udd_endpoint_dma_supported( 7)) \ - ||(UDD_EP_USED( 8) && Is_udd_endpoint_dma_supported( 8)) \ - ||(UDD_EP_USED( 9) && Is_udd_endpoint_dma_supported( 9)) \ - ||(UDD_EP_USED(10) && Is_udd_endpoint_dma_supported(10)) \ - ||(UDD_EP_USED(11) && Is_udd_endpoint_dma_supported(11)) \ - ||(UDD_EP_USED(12) && Is_udd_endpoint_dma_supported(12)) \ - ||(UDD_EP_USED(13) && Is_udd_endpoint_dma_supported(13)) \ - ||(UDD_EP_USED(14) && Is_udd_endpoint_dma_supported(14)) \ - ||(UDD_EP_USED(15) && Is_udd_endpoint_dma_supported(15)) \ - ) -# define UDD_EP_DMA_SUPPORTED -#endif - -#if ( (UDD_EP_USED( 1) && !Is_udd_endpoint_dma_supported( 1)) \ - ||(UDD_EP_USED( 2) && !Is_udd_endpoint_dma_supported( 2)) \ - ||(UDD_EP_USED( 3) && !Is_udd_endpoint_dma_supported( 3)) \ - ||(UDD_EP_USED( 4) && !Is_udd_endpoint_dma_supported( 4)) \ - ||(UDD_EP_USED( 5) && !Is_udd_endpoint_dma_supported( 5)) \ - ||(UDD_EP_USED( 6) && !Is_udd_endpoint_dma_supported( 6)) \ - ||(UDD_EP_USED( 7) && !Is_udd_endpoint_dma_supported( 7)) \ - ||(UDD_EP_USED( 8) && !Is_udd_endpoint_dma_supported( 8)) \ - ||(UDD_EP_USED( 9) && !Is_udd_endpoint_dma_supported( 9)) \ - ||(UDD_EP_USED(10) && !Is_udd_endpoint_dma_supported(10)) \ - ||(UDD_EP_USED(11) && !Is_udd_endpoint_dma_supported(11)) \ - ||(UDD_EP_USED(12) && !Is_udd_endpoint_dma_supported(12)) \ - ||(UDD_EP_USED(13) && !Is_udd_endpoint_dma_supported(13)) \ - ||(UDD_EP_USED(14) && !Is_udd_endpoint_dma_supported(14)) \ - ||(UDD_EP_USED(15) && !Is_udd_endpoint_dma_supported(15)) \ - ) -# define UDD_EP_FIFO_SUPPORTED -#endif - -// for debug text -//#define dbg_print printf -#define dbg_print(...) - -/** - * \ingroup udd_group - * \defgroup udd_udphs_group USB On-The-Go High-Speed Port for device mode (UOTGHS) - * - * \section UOTGHS_CONF UOTGHS Custom configuration - * The following UOTGHS driver configuration must be included in the conf_usb.h - * file of the application. - * - * UDD_USB_INT_LEVEL
- * Option to change the interrupt priority (0 to 15) by default 5 (recommended). - * - * UDD_USB_INT_FUN
- * Option to fit interrupt function to what defined in exception table. - * - * UDD_ISOCHRONOUS_NB_BANK(ep)
- * Feature to reduce or increase isochronous endpoints buffering (1 to 3). - * Default value 2. - * - * UDD_BULK_NB_BANK(ep)
- * Feature to reduce or increase bulk endpoints buffering (1 to 2). - * Default value 2. - * - * UDD_INTERRUPT_NB_BANK(ep)
- * Feature to reduce or increase interrupt endpoints buffering (1 to 2). - * Default value 1. - * - * \section Callbacks management - * The USB driver is fully managed by interrupt and does not request periodique - * task. Thereby, the USB events use callbacks to transfer the information. - * The callbacks are declared in static during compilation or in variable during - * code execution. - * - * Static declarations defined in conf_usb.h: - * - UDC_VBUS_EVENT(bool b_present)
- * To signal Vbus level change - * - UDC_SUSPEND_EVENT()
- * Called when USB bus enter in suspend mode - * - UDC_RESUME_EVENT()
- * Called when USB bus is wakeup - * - UDC_SOF_EVENT()
- * Called for each received SOF, Note: Each 1ms in HS/FS mode only. - * - * Dynamic callbacks, called "endpoint job" , are registered - * in udd_ep_job_t structure via the following functions: - * - udd_ep_run()
- * To call it when a transfer is finish - * - udd_ep_wait_stall_clear()
- * To call it when a endpoint halt is disabled - * - * \section Power mode management - * The Sleep modes authorized : - * - in USB IDLE state, the UOTGHS needs of USB clock and authorizes up to sleep mode WFI. - * - in USB SUSPEND state, the UOTGHS no needs USB clock and authorizes up to sleep mode WAIT. - * @{ - */ - -// Check USB Device configuration -#ifndef USB_DEVICE_EP_CTRL_SIZE -# error USB_DEVICE_EP_CTRL_SIZE not defined -#endif -#ifndef USB_DEVICE_MAX_EP -# error USB_DEVICE_MAX_EP not defined -#endif - -// Note: USB_DEVICE_MAX_EP does not include control endpoint -#if USB_DEVICE_MAX_EP > (UDD_MAX_PEP_NB-1) -# error USB_DEVICE_MAX_EP is too high and not supported by this part -#endif - -#define UDD_EP_ISO_NBANK_ERROR(ep) \ - ( (UDD_ISOCHRONOUS_NB_BANK(ep) < 1) \ - || (UDD_ISOCHRONOUS_NB_BANK(ep) > 3) ) -#define UDD_EP_BULK_NBANK_ERROR(ep) \ - ( (UDD_BULK_NB_BANK(ep) < 1) || (UDD_BULK_NB_BANK(ep) > 2) ) -#define UDD_EP_INT_NBANK_ERROR(ep) \ - ( (UDD_INTERRUPT_NB_BANK(ep) < 1) || (UDD_INTERRUPT_NB_BANK(ep) > 2) ) - -#define UDD_EP_ISO_NB_BANK_ERROR(ep) \ - (UDD_EP_USED(ep) && UDD_EP_ISO_NBANK_ERROR(ep)) -#define UDD_EP_BULK_NB_BANK_ERROR(ep) \ - (UDD_EP_USED(ep) && UDD_EP_ISO_NBANK_ERROR(ep)) -#define UDD_EP_INT_NB_BANK_ERROR(ep) \ - (UDD_EP_USED(ep) && UDD_EP_ISO_NBANK_ERROR(ep)) - -#define UDD_EP_NB_BANK_ERROR(ep, type) \ - (ATPASTE3(UDD_EP_, type, _NB_BANK_ERROR(ep))) - -#define UDD_ISO_NB_BANK_ERROR \ - ( UDD_EP_NB_BANK_ERROR( 1, ISO) \ - || UDD_EP_NB_BANK_ERROR( 2, ISO) \ - || UDD_EP_NB_BANK_ERROR( 3, ISO) \ - || UDD_EP_NB_BANK_ERROR( 4, ISO) \ - || UDD_EP_NB_BANK_ERROR( 5, ISO) \ - || UDD_EP_NB_BANK_ERROR( 6, ISO) \ - || UDD_EP_NB_BANK_ERROR( 7, ISO) \ - || UDD_EP_NB_BANK_ERROR( 8, ISO) \ - || UDD_EP_NB_BANK_ERROR( 9, ISO) \ - || UDD_EP_NB_BANK_ERROR(10, ISO) \ - || UDD_EP_NB_BANK_ERROR(11, ISO) \ - || UDD_EP_NB_BANK_ERROR(12, ISO) \ - || UDD_EP_NB_BANK_ERROR(13, ISO) \ - || UDD_EP_NB_BANK_ERROR(14, ISO) \ - || UDD_EP_NB_BANK_ERROR(15, ISO) ) -#define UDD_BULK_NB_BANK_ERROR \ - ( UDD_EP_NB_BANK_ERROR( 1, BULK) \ - || UDD_EP_NB_BANK_ERROR( 2, BULK) \ - || UDD_EP_NB_BANK_ERROR( 3, BULK) \ - || UDD_EP_NB_BANK_ERROR( 4, BULK) \ - || UDD_EP_NB_BANK_ERROR( 5, BULK) \ - || UDD_EP_NB_BANK_ERROR( 6, BULK) \ - || UDD_EP_NB_BANK_ERROR( 7, BULK) \ - || UDD_EP_NB_BANK_ERROR( 8, BULK) \ - || UDD_EP_NB_BANK_ERROR( 9, BULK) \ - || UDD_EP_NB_BANK_ERROR(10, BULK) \ - || UDD_EP_NB_BANK_ERROR(11, BULK) \ - || UDD_EP_NB_BANK_ERROR(12, BULK) \ - || UDD_EP_NB_BANK_ERROR(13, BULK) \ - || UDD_EP_NB_BANK_ERROR(14, BULK) \ - || UDD_EP_NB_BANK_ERROR(15, BULK) ) -#define UDD_INTERRUPT_NB_BANK_ERROR \ - ( UDD_EP_NB_BANK_ERROR( 1, INT) \ - || UDD_EP_NB_BANK_ERROR( 2, INT) \ - || UDD_EP_NB_BANK_ERROR( 3, INT) \ - || UDD_EP_NB_BANK_ERROR( 4, INT) \ - || UDD_EP_NB_BANK_ERROR( 5, INT) \ - || UDD_EP_NB_BANK_ERROR( 6, INT) \ - || UDD_EP_NB_BANK_ERROR( 7, INT) \ - || UDD_EP_NB_BANK_ERROR( 8, INT) \ - || UDD_EP_NB_BANK_ERROR( 9, INT) \ - || UDD_EP_NB_BANK_ERROR(10, INT) \ - || UDD_EP_NB_BANK_ERROR(11, INT) \ - || UDD_EP_NB_BANK_ERROR(12, INT) \ - || UDD_EP_NB_BANK_ERROR(13, INT) \ - || UDD_EP_NB_BANK_ERROR(14, INT) \ - || UDD_EP_NB_BANK_ERROR(15, INT) ) - -#ifndef UDD_ISOCHRONOUS_NB_BANK -# define UDD_ISOCHRONOUS_NB_BANK(ep) 2 -#else -# if UDD_ISO_NB_BANK_ERROR -# error UDD_ISOCHRONOUS_NB_BANK(ep) must be define within 1 to 3. -# endif -#endif - -#ifndef UDD_BULK_NB_BANK -# define UDD_BULK_NB_BANK(ep) 2 -#else -# if UDD_BULK_NB_BANK_ERROR -# error UDD_BULK_NB_BANK must be define with 1 or 2. -# endif -#endif - -#ifndef UDD_INTERRUPT_NB_BANK -# define UDD_INTERRUPT_NB_BANK(ep) 1 -#else -# if UDD_INTERRUPT_NB_BANK_ERROR -# error UDD_INTERRUPT_NB_BANK must be define with 1 or 2. -# endif -#endif - - -/** - * \name Power management routine. - */ -//@{ - -#ifndef UDD_NO_SLEEP_MGR - -//! Definition of sleep levels -#define UOTGHS_SLEEP_MODE_USB_SUSPEND SLEEPMGR_WAIT_FAST -#define UOTGHS_SLEEP_MODE_USB_IDLE SLEEPMGR_SLEEP_WFI - -//! State of USB line -static bool udd_b_idle; -//! State of sleep manager -static bool udd_b_sleep_initialized = false; - - -/*! \brief Authorize or not the CPU powerdown mode - * - * \param b_enable true to authorize idle mode - */ -static void udd_sleep_mode(bool b_idle) -{ - if (!b_idle && udd_b_idle) { - dbg_print("_S "); - sleepmgr_unlock_mode(UOTGHS_SLEEP_MODE_USB_IDLE); - } - if (b_idle && !udd_b_idle) { - dbg_print("_W "); - sleepmgr_lock_mode(UOTGHS_SLEEP_MODE_USB_IDLE); - } - udd_b_idle = b_idle; -} -#else - -static void udd_sleep_mode(bool b_idle) -{ - b_idle = b_idle; -} - -#endif // UDD_NO_SLEEP_MGR - -//@} - - -/** - * \name Control endpoint low level management routine. - * - * This function performs control endpoint management. - * It handle the SETUP/DATA/HANDSHAKE phases of a control transaction. - */ -//@{ - -//! Global variable to give and record information about setup request management -COMPILER_WORD_ALIGNED udd_ctrl_request_t udd_g_ctrlreq; - -//! Bit definitions about endpoint control state machine for udd_ep_control_state -typedef enum { - UDD_EPCTRL_SETUP = 0, //!< Wait a SETUP packet - UDD_EPCTRL_DATA_OUT = 1, //!< Wait a OUT data packet - UDD_EPCTRL_DATA_IN = 2, //!< Wait a IN data packet - UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP = 3, //!< Wait a IN ZLP packet - UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet - UDD_EPCTRL_STALL_REQ = 5, //!< STALL enabled on IN & OUT packet -} udd_ctrl_ep_state_t; - -//! State of the endpoint control management -static udd_ctrl_ep_state_t udd_ep_control_state; - -//! Total number of data received/sent during data packet phase with previous payload buffers -static uint16_t udd_ctrl_prev_payload_buf_cnt; - -//! Number of data received/sent to/from udd_g_ctrlreq.payload buffer -static uint16_t udd_ctrl_payload_buf_cnt; - -/** - * \brief Reset control endpoint - * - * Called after a USB line reset or when UDD is enabled - */ -static void udd_reset_ep_ctrl(void); - -/** - * \brief Reset control endpoint management - * - * Called after a USB line reset or at the end of SETUP request (after ZLP) - */ -static void udd_ctrl_init(void); - -//! \brief Managed reception of SETUP packet on control endpoint -static void udd_ctrl_setup_received(void); - -//! \brief Managed reception of IN packet on control endpoint -static void udd_ctrl_in_sent(void); - -//! \brief Managed reception of OUT packet on control endpoint -static void udd_ctrl_out_received(void); - -//! \brief Managed underflow event of IN packet on control endpoint -static void udd_ctrl_underflow(void); - -//! \brief Managed overflow event of OUT packet on control endpoint -static void udd_ctrl_overflow(void); - -//! \brief Managed stall event of IN/OUT packet on control endpoint -static void udd_ctrl_stall_data(void); - -//! \brief Send a ZLP IN on control endpoint -static void udd_ctrl_send_zlp_in(void); - -//! \brief Send a ZLP OUT on control endpoint -static void udd_ctrl_send_zlp_out(void); - -//! \brief Call callback associated to setup request -static void udd_ctrl_endofrequest(void); - - -/** - * \brief Main interrupt routine for control endpoint - * - * This switches control endpoint events to correct sub function. - * - * \return \c 1 if an event about control endpoint is occurred, otherwise \c 0. - */ -static bool udd_ctrl_interrupt(void); - -//@} - - -/** - * \name Management of bulk/interrupt/isochronous endpoints - * - * The UDD manages the data transfer on endpoints: - * - Start data transfer on endpoint with USB Device DMA - * - Send a ZLP packet if requested - * - Call callback registered to signal end of transfer - * The transfer abort and stall feature are supported. - */ -//@{ -#if (0!=USB_DEVICE_MAX_EP) - -//! Structure definition about job registered on an endpoint -typedef struct { - union { - //! Callback to call at the end of transfer - udd_callback_trans_t call_trans; - - //! Callback to call when the endpoint halt is cleared - udd_callback_halt_cleared_t call_nohalt; - }; - //! Buffer located in internal RAM to send or fill during job - uint8_t *buf; - //! Size of buffer to send or fill - iram_size_t buf_size; - //!< Size of data transferred - iram_size_t buf_cnt; - //!< Size of data loaded (or prepared for DMA) last time - iram_size_t buf_load; - //! A job is registered on this endpoint - uint8_t busy:1; - //! A short packet is requested for this job on endpoint IN - uint8_t b_shortpacket:1; - //! A stall has been requested but not executed - uint8_t stall_requested:1; -} udd_ep_job_t; - - -//! Array to register a job on bulk/interrupt/isochronous endpoint -static udd_ep_job_t udd_ep_job[USB_DEVICE_MAX_EP]; - -//! \brief Reset all job table -static void udd_ep_job_table_reset(void); - -//! \brief Abort all endpoint jobs on going -static void udd_ep_job_table_kill(void); - -#ifdef UDD_EP_FIFO_SUPPORTED - /** - * \brief Fill banks and send them - * - * \param ep endpoint number of job to abort - */ - static void udd_ep_in_sent(udd_ep_id_t ep); - - /** - * \brief Store received banks - * - * \param ep endpoint number of job to abort - */ - static void udd_ep_out_received(udd_ep_id_t ep); -#endif - -/** - * \brief Abort endpoint job on going - * - * \param ep endpoint number of job to abort - */ -static void udd_ep_abort_job(udd_ep_id_t ep); - -/** - * \brief Call the callback associated to the job which is finished - * - * \param ptr_job job to complete - * \param b_abort if true then the job has been aborted - */ -static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort, uint8_t ep_num); - -#ifdef UDD_EP_DMA_SUPPORTED - /** - * \brief Start the next transfer if necessary or complete the job associated. - * - * \param ep endpoint number without direction flag - */ - static void udd_ep_trans_done(udd_ep_id_t ep); -#endif - -/** - * \brief Main interrupt routine for bulk/interrupt/isochronous endpoints - * - * This switches endpoint events to correct sub function. - * - * \return \c 1 if an event about bulk/interrupt/isochronous endpoints has occurred, otherwise \c 0. - */ -static bool udd_ep_interrupt(void); - -#endif // (0!=USB_DEVICE_MAX_EP) -//@} - - -// ------------------------ -//--- INTERNAL ROUTINES TO MANAGED GLOBAL EVENTS - -/** - * \internal - * \brief Function called by UOTGHS interrupt to manage USB Device interrupts - * - * USB Device interrupt events are splited in three parts: - * - USB line events (SOF, reset, suspend, resume, wakeup) - * - control endpoint events (setup reception, end of data transfer, underflow, overflow, stall) - * - bulk/interrupt/isochronous endpoints events (end of data transfer) - * - * Note: - * Here, the global interrupt mask is not clear when an USB interrupt is enabled - * because this one can not be occurred during the USB ISR (=during INTX is masked). - * See Technical reference $3.8.3 Masking interrupt requests in peripheral modules. - */ -#ifdef UHD_ENABLE -void udd_interrupt(void); -void udd_interrupt(void) -#else -ISR(UDD_USB_INT_FUN) -#endif -{ - /* For fast wakeup clocks restore - * In WAIT mode, clocks are switched to FASTRC. - * After wakeup clocks should be restored, before that ISR should not - * be served. - */ - if (!pmc_is_wakeup_clocks_restored() && !Is_udd_suspend()) { - cpu_irq_disable(); - return; - } - - if (Is_udd_sof()) { - udd_ack_sof(); - if (Is_udd_full_speed_mode()) { - udc_sof_notify(); - } -#ifdef UDC_SOF_EVENT - UDC_SOF_EVENT(); -#endif - goto udd_interrupt_sof_end; - } - - if (Is_udd_msof()) { - udd_ack_msof(); - udc_sof_notify(); - goto udd_interrupt_sof_end; - } - - dbg_print("%c ", udd_is_high_speed() ? 'H' : 'F'); - - if (udd_ctrl_interrupt()) { - goto udd_interrupt_end; // Interrupt acked by control endpoint managed - } - -#if (0 != USB_DEVICE_MAX_EP) - if (udd_ep_interrupt()) { - goto udd_interrupt_end; // Interrupt acked by bulk/interrupt/isochronous endpoint managed - } -#endif - - // USB bus reset detection - if (Is_udd_reset()) { - udd_ack_reset(); - dbg_print("RST "); - // Abort all jobs on-going -#if (USB_DEVICE_MAX_EP != 0) - udd_ep_job_table_kill(); -#endif - // Reset USB Device Stack Core - udc_reset(); - // Reset endpoint control - udd_reset_ep_ctrl(); - // Reset endpoint control management - udd_ctrl_init(); - goto udd_interrupt_end; - } - - if (Is_udd_suspend_interrupt_enabled() && Is_udd_suspend()) { - otg_unfreeze_clock(); - // The suspend interrupt is automatic acked when a wakeup occur - udd_disable_suspend_interrupt(); - udd_enable_wake_up_interrupt(); - otg_freeze_clock(); // Mandatory to exit of sleep mode after a wakeup event - udd_sleep_mode(false); // Enter in SUSPEND mode -#ifdef UDC_SUSPEND_EVENT - UDC_SUSPEND_EVENT(); -#endif - goto udd_interrupt_end; - } - - if (Is_udd_wake_up_interrupt_enabled() && Is_udd_wake_up()) { - // Ack wakeup interrupt and enable suspend interrupt - otg_unfreeze_clock(); - // Check USB clock ready after suspend and eventually sleep USB clock - while (!Is_otg_clock_usable()) { - if (Is_udd_suspend()) { - break; // In case of USB state change in HS - } - }; - // The wakeup interrupt is automatic acked when a suspend occur - udd_disable_wake_up_interrupt(); - udd_enable_suspend_interrupt(); - udd_sleep_mode(true); // Enter in IDLE mode -#ifdef UDC_RESUME_EVENT - UDC_RESUME_EVENT(); -#endif - goto udd_interrupt_end; - } - - if (Is_otg_vbus_transition()) { - dbg_print("VBus "); - // Ack Vbus transition and send status to high level - otg_unfreeze_clock(); - otg_ack_vbus_transition(); - otg_freeze_clock(); -#ifndef USB_DEVICE_ATTACH_AUTO_DISABLE - if (Is_otg_vbus_high()) { - udd_attach(); - } else { - udd_detach(); - } -#endif -#ifdef UDC_VBUS_EVENT - UDC_VBUS_EVENT(Is_otg_vbus_high()); -#endif - goto udd_interrupt_end; - } -udd_interrupt_end: - dbg_print("\n\r"); -udd_interrupt_sof_end: - return; -} - - -bool udd_include_vbus_monitoring(void) -{ - return true; -} - - -void udd_enable(void) -{ - irqflags_t flags; - - flags = cpu_irq_save(); - -#ifdef UHD_ENABLE - // DUAL ROLE INITIALIZATION - if (otg_dual_enable()) { - // The current mode has been started by otg_dual_enable() - cpu_irq_restore(flags); - return; - } -#else - // SINGLE DEVICE MODE INITIALIZATION - pmc_enable_periph_clk(ID_UOTGHS); - sysclk_enable_usb(); - - // Here, only the device mode is possible, then link UOTGHS interrupt to UDD interrupt - NVIC_SetPriority((IRQn_Type) ID_UOTGHS, UDD_USB_INT_LEVEL); - NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS); - - // Always authorize asynchrone USB interrupts to exit of sleep mode - // For SAM USB wake up device except BACKUP mode - pmc_set_fast_startup_input(PMC_FSMR_USBAL); -#endif - -#if (defined USB_ID_GPIO) && (defined UHD_ENABLE) - // Check that the device mode is selected by ID pin - if (!Is_otg_id_device()) { - cpu_irq_restore(flags); - return; // Device is not the current mode - } -#else - // ID pin not used then force device mode - otg_disable_id_pin(); - otg_force_device_mode(); -#endif - // Enable USB hardware - otg_enable_pad(); - otg_enable(); - - // Set the USB speed requested by configuration file -#ifdef USB_DEVICE_LOW_SPEED - udd_low_speed_enable(); -#else - udd_low_speed_disable(); -# ifdef USB_DEVICE_HS_SUPPORT - udd_high_speed_enable(); -# else - udd_high_speed_disable(); -# endif -#endif // USB_DEVICE_LOW_SPEED - - // Check USB clock - otg_unfreeze_clock(); - while (!Is_otg_clock_usable()); - - // Reset internal variables -#if (0!=USB_DEVICE_MAX_EP) - udd_ep_job_table_reset(); -#endif - - otg_ack_vbus_transition(); - // Force Vbus interrupt in case of Vbus always with a high level - // This is possible with a short timing between a Host mode stop/start. - if (Is_otg_vbus_high()) { - otg_raise_vbus_transition(); - } - otg_enable_vbus_interrupt(); - otg_freeze_clock(); - -#ifndef UDD_NO_SLEEP_MGR - if (!udd_b_sleep_initialized) { - udd_b_sleep_initialized = true; - // Initialize the sleep mode authorized for the USB suspend mode - udd_b_idle = false; - sleepmgr_lock_mode(UOTGHS_SLEEP_MODE_USB_SUSPEND); - } else { - udd_sleep_mode(false); // Enter idle mode - } -#endif - - cpu_irq_restore(flags); -} - - -void udd_disable(void) -{ - irqflags_t flags; - -#ifdef UHD_ENABLE -# ifdef USB_ID_GPIO - if (Is_otg_id_host()) { - // Freeze clock to switch mode - otg_freeze_clock(); - udd_detach(); - otg_disable(); - return; // Host mode running, ignore UDD disable - } -# else - if (Is_otg_host_mode_forced()) { - return; // Host mode running, ignore UDD disable - } -# endif -#endif - - flags = cpu_irq_save(); - otg_unfreeze_clock(); - udd_detach(); -#ifndef UDD_NO_SLEEP_MGR - if (udd_b_sleep_initialized) { - udd_b_sleep_initialized = false; - sleepmgr_unlock_mode(UOTGHS_SLEEP_MODE_USB_SUSPEND); - } -#endif - -#ifndef UHD_ENABLE - otg_disable(); - otg_disable_pad(); - sysclk_disable_usb(); - pmc_disable_periph_clk(ID_UOTGHS); - // Else the USB clock disable is done by UHC which manage USB dual role -#endif - cpu_irq_restore(flags); -} - - -void udd_attach(void) -{ - irqflags_t flags; - flags = cpu_irq_save(); - - // At startup the USB bus state is unknown, - // therefore the state is considered IDLE to not miss any USB event - udd_sleep_mode(true); - otg_unfreeze_clock(); - - // This section of clock check can be improved with a check of - // USB clock source via sysclk() - // Check USB clock because the source can be a PLL - while (!Is_otg_clock_usable()); - - // Authorize attach if Vbus is present - udd_attach_device(); - - // Enable USB line events - udd_enable_reset_interrupt(); - udd_enable_suspend_interrupt(); - udd_enable_wake_up_interrupt(); - udd_enable_sof_interrupt(); -#ifdef USB_DEVICE_HS_SUPPORT - udd_enable_msof_interrupt(); -#endif - // Reset following interrupts flag - udd_ack_reset(); - udd_ack_sof(); - udd_ack_msof(); - - // The first suspend interrupt must be forced - // The first suspend interrupt is not detected else raise it - udd_raise_suspend(); - - udd_ack_wake_up(); - otg_freeze_clock(); - cpu_irq_restore(flags); -} - - -void udd_detach(void) -{ - otg_unfreeze_clock(); - - // Detach device from the bus - udd_detach_device(); - otg_freeze_clock(); - udd_sleep_mode(false); -} - - -bool udd_is_high_speed(void) -{ -#ifdef USB_DEVICE_HS_SUPPORT - return !Is_udd_full_speed_mode(); -#else - return false; -#endif -} - - -void udd_set_address(uint8_t address) -{ - udd_disable_address(); - udd_configure_address(address); - udd_enable_address(); -} - - -uint8_t udd_getaddress(void) -{ - return udd_get_configured_address(); -} - - -uint16_t udd_get_frame_number(void) -{ - return udd_frame_number(); -} - -uint16_t udd_get_micro_frame_number(void) -{ - return udd_micro_frame_number(); -} - -void udd_send_remotewakeup(void) -{ -#ifndef UDD_NO_SLEEP_MGR - if (!udd_b_idle) -#endif - { - udd_sleep_mode(true); // Enter in IDLE mode - otg_unfreeze_clock(); - udd_initiate_remote_wake_up(); - } -} - - -void udd_set_setup_payload(uint8_t *payload, uint16_t payload_size) -{ - udd_g_ctrlreq.payload = payload; - udd_g_ctrlreq.payload_size = payload_size; -} - - -#if (0 != USB_DEVICE_MAX_EP) -bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, - uint16_t MaxEndpointSize) -{ - bool b_dir_in; - uint16_t ep_allocated; - uint8_t nb_bank, bank, i; - - b_dir_in = ep & USB_EP_DIR_IN; - ep = ep & USB_EP_ADDR_MASK; - - if (ep > USB_DEVICE_MAX_EP) { - return false; - } - if (Is_udd_endpoint_enabled(ep)) { - return false; - } - dbg_print("alloc(%x, %d) ", ep, MaxEndpointSize); - - // Bank choice - switch (bmAttributes & USB_EP_TYPE_MASK) { - case USB_EP_TYPE_ISOCHRONOUS: - nb_bank = UDD_ISOCHRONOUS_NB_BANK(ep); - break; - case USB_EP_TYPE_INTERRUPT: - nb_bank = UDD_INTERRUPT_NB_BANK(ep); - break; - case USB_EP_TYPE_BULK: - nb_bank = UDD_BULK_NB_BANK(ep); - break; - default: - Assert(false); - return false; - } - switch (nb_bank) { - case 1: - bank = UOTGHS_DEVEPTCFG_EPBK_1_BANK >> - UOTGHS_DEVEPTCFG_EPBK_Pos; - break; - case 2: - bank = UOTGHS_DEVEPTCFG_EPBK_2_BANK >> - UOTGHS_DEVEPTCFG_EPBK_Pos; - break; - case 3: - bank = UOTGHS_DEVEPTCFG_EPBK_3_BANK >> - UOTGHS_DEVEPTCFG_EPBK_Pos; - break; - default: - Assert(false); - return false; - } - - // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 - Assert(MaxEndpointSize < 1024); - Assert((MaxEndpointSize == 1023) - || !(MaxEndpointSize & (MaxEndpointSize - 1))); - Assert(MaxEndpointSize >= 8); - - // Set configuration of new endpoint - udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0), - MaxEndpointSize, bank); - ep_allocated = 1 << ep; - - // Unalloc endpoints superior - for (i = USB_DEVICE_MAX_EP; i > ep; i--) { - if (Is_udd_endpoint_enabled(i)) { - ep_allocated |= 1 << i; - udd_disable_endpoint(i); - udd_unallocate_memory(i); - } - } - - // Realloc/Enable endpoints - for (i = ep; i <= USB_DEVICE_MAX_EP; i++) { - if (ep_allocated & (1 << i)) { - udd_ep_job_t *ptr_job = &udd_ep_job[i - 1]; - bool b_restart = ptr_job->busy; - // Restart running job because - // memory window slides up and its data is lost - ptr_job->busy = false; - // Re-allocate memory - udd_allocate_memory(i); - udd_enable_endpoint(i); - if (!Is_udd_endpoint_configured(i)) { - dbg_print("ErrRealloc%d ", i); - if (NULL == ptr_job->call_trans) { - return false; - } - if (Is_udd_endpoint_in(i)) { - i |= USB_EP_DIR_IN; - } - ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, - ptr_job->buf_cnt, i); - return false; - } - udd_enable_endpoint_bank_autoswitch(i); - if (b_restart) { - // Re-run the job remaining part -# ifdef UDD_EP_FIFO_SUPPORTED - if (!Is_udd_endpoint_dma_supported(i) - && !Is_udd_endpoint_in(i)) { - ptr_job->buf_cnt -= ptr_job->buf_load; - } -# else - ptr_job->buf_cnt -= ptr_job->buf_load; -# endif - b_restart = udd_ep_run(Is_udd_endpoint_in(i) ? - (i | USB_EP_DIR_IN) : i, - ptr_job->b_shortpacket, - &ptr_job->buf[ptr_job->buf_cnt], - ptr_job->buf_size - - ptr_job->buf_cnt, - ptr_job->call_trans); - if (!b_restart) { - dbg_print("ErrReRun%d ", i); - return false; - } - } - } - } - return true; -} - - -void udd_ep_free(udd_ep_id_t ep) -{ - uint8_t ep_index = ep & USB_EP_ADDR_MASK; - if (USB_DEVICE_MAX_EP < ep_index) { - return; - } - udd_disable_endpoint(ep_index); - udd_unallocate_memory(ep_index); - udd_ep_abort_job(ep); - udd_ep_job[ep_index - 1].stall_requested = false; -} - - -bool udd_ep_is_halted(udd_ep_id_t ep) -{ - uint8_t ep_index = ep & USB_EP_ADDR_MASK; - return Is_udd_endpoint_stall_requested(ep_index); -} - - -bool udd_ep_set_halt(udd_ep_id_t ep) -{ - uint8_t ep_index = ep & USB_EP_ADDR_MASK; - udd_ep_job_t *ptr_job = &udd_ep_job[ep_index - 1]; - irqflags_t flags; - - if (USB_DEVICE_MAX_EP < ep_index) { - return false; - } - - if (Is_udd_endpoint_stall_requested(ep_index) // Endpoint stalled - || ptr_job->stall_requested) { // Endpoint stall is requested - return true; // Already STALL - } - - if (ptr_job->busy == true) { - return false; // Job on going, stall impossible - } - - flags = cpu_irq_save(); - if ((ep & USB_EP_DIR_IN) && (0 != udd_nb_busy_bank(ep_index))) { - // Delay the stall after the end of IN transfer on USB line - ptr_job->stall_requested = true; -#ifdef UDD_EP_FIFO_SUPPORTED - udd_disable_in_send_interrupt(ep_index); - udd_enable_endpoint_bank_autoswitch(ep_index); -#endif - udd_enable_bank_interrupt(ep_index); - udd_enable_endpoint_interrupt(ep_index); - cpu_irq_restore(flags); - return true; - } - // Stall endpoint immediately - udd_disable_endpoint_bank_autoswitch(ep_index); - udd_ack_stall(ep_index); - udd_enable_stall_handshake(ep_index); - cpu_irq_restore(flags); - return true; -} - - -bool udd_ep_clear_halt(udd_ep_id_t ep) -{ - uint8_t ep_index = ep & USB_EP_ADDR_MASK; - udd_ep_job_t *ptr_job = &udd_ep_job[ep_index - 1]; - bool b_stall_cleared = false; - - if (USB_DEVICE_MAX_EP < ep_index) - return false; - - if (ptr_job->stall_requested) { - // Endpoint stall has been requested but not done - // Remove stall request - ptr_job->stall_requested = false; - udd_disable_bank_interrupt(ep_index); - udd_disable_endpoint_interrupt(ep_index); - b_stall_cleared = true; - } - if (Is_udd_endpoint_stall_requested(ep_index)) { - if (Is_udd_stall(ep_index)) { - udd_ack_stall(ep_index); - // A packet has been stalled - // then reset datatoggle - udd_reset_data_toggle(ep_index); - } - // Disable stall - udd_disable_stall_handshake(ep_index); - udd_enable_endpoint_bank_autoswitch(ep_index); - b_stall_cleared = true; - } - if (b_stall_cleared) { - // If a job is register on clear halt action - // then execute callback - if (ptr_job->busy == true) { - ptr_job->busy = false; - ptr_job->call_nohalt(); - } - } - return true; -} - - -bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, - uint8_t * buf, iram_size_t buf_size, - udd_callback_trans_t callback) -{ -#ifdef UDD_EP_FIFO_SUPPORTED - bool b_dir_in = Is_udd_endpoint_in(ep & USB_EP_ADDR_MASK); -#endif - udd_ep_job_t *ptr_job; - irqflags_t flags; - - ep &= USB_EP_ADDR_MASK; - if (USB_DEVICE_MAX_EP < ep) { - return false; - } - - // Get job about endpoint - ptr_job = &udd_ep_job[ep - 1]; - - if ((!Is_udd_endpoint_enabled(ep)) - || Is_udd_endpoint_stall_requested(ep) - || ptr_job->stall_requested) { - return false; // Endpoint is halted - } - - flags = cpu_irq_save(); - if (ptr_job->busy == true) { - cpu_irq_restore(flags); - return false; // Job already on going - } - ptr_job->busy = true; - cpu_irq_restore(flags); - - // No job running. Let's setup a new one. - ptr_job->buf = buf; - ptr_job->buf_size = buf_size; - ptr_job->buf_cnt = 0; - ptr_job->buf_load = 0; - ptr_job->call_trans = callback; - ptr_job->b_shortpacket = b_shortpacket || (buf_size == 0); - -#ifdef UDD_EP_FIFO_SUPPORTED - // No DMA support - if (!Is_udd_endpoint_dma_supported(ep)) { - dbg_print("ex%x.%c%d\n\r", ep, b_dir_in ? 'i':'o', buf_size); - flags = cpu_irq_save(); - udd_enable_endpoint_interrupt(ep); - if (b_dir_in) { - udd_disable_endpoint_bank_autoswitch(ep); - udd_enable_in_send_interrupt(ep); - } else { - udd_disable_endpoint_bank_autoswitch(ep); - udd_enable_out_received_interrupt(ep); - } - cpu_irq_restore(flags); - return true; - } -#endif // UDD_EP_FIFO_SUPPORTED - -#ifdef UDD_EP_DMA_SUPPORTED - // Request first DMA transfer - dbg_print("(exDMA%x) ", ep); - udd_ep_trans_done(ep); - return true; -#endif -} - - -void udd_ep_abort(udd_ep_id_t ep) -{ - uint8_t ep_index = ep & USB_EP_ADDR_MASK; - -#ifdef UDD_EP_FIFO_SUPPORTED - if (!Is_udd_endpoint_dma_supported(ep_index)) { - // Disable interrupts - udd_disable_endpoint_interrupt(ep_index); - udd_disable_out_received_interrupt(ep_index); - udd_disable_in_send_interrupt(ep_index); - } else -#endif - { - // Stop DMA transfer - udd_disable_endpoint_dma_interrupt(ep_index); - udd_endpoint_dma_set_control(ep_index, 0); - } - udd_disable_endpoint_interrupt(ep_index); - // Kill IN banks - if (ep & USB_EP_DIR_IN) { - while(udd_nb_busy_bank(ep_index)) { - udd_kill_last_in_bank(ep_index); - while(Is_udd_kill_last(ep_index)); - } - } - udd_ep_abort_job(ep); -} - - -bool udd_ep_wait_stall_clear(udd_ep_id_t ep, - udd_callback_halt_cleared_t callback) -{ - udd_ep_job_t *ptr_job; - - ep &= USB_EP_ADDR_MASK; - if (USB_DEVICE_MAX_EP < ep) { - return false; - } - - ptr_job = &udd_ep_job[ep - 1]; - - if (!Is_udd_endpoint_enabled(ep)) { - return false; // Endpoint not enabled - } - - // Wait clear halt endpoint - if (ptr_job->busy == true) { - return false; // Job already on going - } - - if (Is_udd_endpoint_stall_requested(ep) - || ptr_job->stall_requested) { - // Endpoint halted then registers the callback - ptr_job->busy = true; - ptr_job->call_nohalt = callback; - } else { - // endpoint not halted then call directly callback - callback(); - } - return true; -} -#endif // (0 != USB_DEVICE_MAX_EP) - - -#ifdef USB_DEVICE_HS_SUPPORT - -void udd_test_mode_j(void) -{ - udd_enable_hs_test_mode(); - udd_enable_hs_test_mode_j(); -} - - -void udd_test_mode_k(void) -{ - udd_enable_hs_test_mode(); - udd_enable_hs_test_mode_k(); -} - - -void udd_test_mode_se0_nak(void) -{ - udd_enable_hs_test_mode(); -} - - -void udd_test_mode_packet(void) -{ - uint8_t i; - uint8_t *ptr_dest; - const uint8_t *ptr_src; - - const uint8_t test_packet[] = { - // 00000000 * 9 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 01010101 * 8 - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - // 01110111 * 8 - 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, - // 0, {111111S * 15}, 111111 - 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, - // S, 111111S, {0111111S * 7} - 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, - // 00111111, {S0111111 * 9}, S0 - 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E - }; - - // Reconfigure control endpoint to bulk IN endpoint - udd_disable_endpoint(0); - udd_configure_endpoint(0, USB_EP_TYPE_BULK, 1, - 64, UOTGHS_DEVEPTCFG_EPBK_1_BANK); - udd_allocate_memory(0); - udd_enable_endpoint(0); - - udd_enable_hs_test_mode(); - udd_enable_hs_test_mode_packet(); - - // Send packet on endpoint 0 - ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); - ptr_src = test_packet; - - for (i = 0; i < sizeof(test_packet); i++) { - *ptr_dest++ = *ptr_src++; - } - udd_ack_fifocon(0); -} -#endif // USB_DEVICE_HS_SUPPORT - - - -// ------------------------ -//--- INTERNAL ROUTINES TO MANAGED THE CONTROL ENDPOINT - -static void udd_reset_ep_ctrl(void) -{ - irqflags_t flags; - - // Reset USB address to 0 - udd_configure_address(0); - udd_enable_address(); - - // Alloc and configure control endpoint - udd_configure_endpoint(0, - USB_EP_TYPE_CONTROL, - 0, - USB_DEVICE_EP_CTRL_SIZE, - UOTGHS_DEVEPTCFG_EPBK_1_BANK); - - udd_allocate_memory(0); - udd_enable_endpoint(0); - flags = cpu_irq_save(); - udd_enable_setup_received_interrupt(0); - udd_enable_out_received_interrupt(0); - udd_enable_endpoint_interrupt(0); - cpu_irq_restore(flags); -} - -static void udd_ctrl_init(void) -{ - irqflags_t flags; - flags = cpu_irq_save(); - - // In case of abort of IN Data Phase: - // No need to abort IN transfer (rise TXINI), - // because it is automatically done by hardware when a Setup packet is received. - // But the interrupt must be disabled to don't generate interrupt TXINI - // after SETUP reception. - udd_disable_in_send_interrupt(0); - cpu_irq_restore(flags); - - // In case of OUT ZLP event is no processed before Setup event occurs - udd_ack_out_received(0); - - udd_g_ctrlreq.callback = NULL; - udd_g_ctrlreq.over_under_run = NULL; - udd_g_ctrlreq.payload_size = 0; - udd_ep_control_state = UDD_EPCTRL_SETUP; -} - - -static void udd_ctrl_setup_received(void) -{ - irqflags_t flags; - uint8_t i; - - if (UDD_EPCTRL_SETUP != udd_ep_control_state) { - // May be a hidden DATA or ZLP phase or protocol abort - udd_ctrl_endofrequest(); - - // Reinitializes control endpoint management - udd_ctrl_init(); - } - // Fill setup request structure - if (8 != udd_byte_count(0)) { - udd_ctrl_stall_data(); - udd_ack_setup_received(0); - return; // Error data number doesn't correspond to SETUP packet - } - uint8_t *ptr = (uint8_t *) & udd_get_endpoint_fifo_access(0,8); - for (i = 0; i < 8; i++) { - ((uint8_t*) &udd_g_ctrlreq.req)[i] = *ptr++; - } - // Manage LSB/MSB to fit with CPU usage - udd_g_ctrlreq.req.wValue = le16_to_cpu(udd_g_ctrlreq.req.wValue); - udd_g_ctrlreq.req.wIndex = le16_to_cpu(udd_g_ctrlreq.req.wIndex); - udd_g_ctrlreq.req.wLength = le16_to_cpu(udd_g_ctrlreq.req.wLength); - - // Decode setup request - if (udc_process_setup() == false) { - // Setup request unknown then stall it - udd_ctrl_stall_data(); - udd_ack_setup_received(0); - return; - } - udd_ack_setup_received(0); - - if (Udd_setup_is_in()) { - // IN data phase requested - udd_ctrl_prev_payload_buf_cnt = 0; - udd_ctrl_payload_buf_cnt = 0; - udd_ep_control_state = UDD_EPCTRL_DATA_IN; - udd_ctrl_in_sent(); // Send first data transfer - } else { - if (0 == udd_g_ctrlreq.req.wLength) { - // No data phase requested - // Send IN ZLP to ACK setup request - udd_ctrl_send_zlp_in(); - return; - } - // OUT data phase requested - udd_ctrl_prev_payload_buf_cnt = 0; - udd_ctrl_payload_buf_cnt = 0; - udd_ep_control_state = UDD_EPCTRL_DATA_OUT; - // To detect a protocol error, enable nak interrupt on data IN phase - udd_ack_nak_in(0); - flags = cpu_irq_save(); - udd_enable_nak_in_interrupt(0); - cpu_irq_restore(flags); - } -} - - -static void udd_ctrl_in_sent(void) -{ - static bool b_shortpacket = false; - uint16_t nb_remain; - uint8_t i; - uint8_t *ptr_dest, *ptr_src; - irqflags_t flags; - - flags = cpu_irq_save(); - udd_disable_in_send_interrupt(0); - cpu_irq_restore(flags); - - if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { - // ZLP on IN is sent, then valid end of setup request - udd_ctrl_endofrequest(); - // Reinitializes control endpoint management - udd_ctrl_init(); - return; - } - Assert(udd_ep_control_state == UDD_EPCTRL_DATA_IN); - - nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_buf_cnt; - if (0 == nb_remain) { - // All content of current buffer payload are sent - // Update number of total data sending by previous playlaod buffer - udd_ctrl_prev_payload_buf_cnt += udd_ctrl_payload_buf_cnt; - if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_buf_cnt) - || b_shortpacket) { - // All data requested are transferred or a short packet has been sent - // then it is the end of data phase. - // Generate an OUT ZLP for handshake phase. - udd_ctrl_send_zlp_out(); - return; - } - // Need of new buffer because the data phase is not complete - if ((!udd_g_ctrlreq.over_under_run) - || (!udd_g_ctrlreq.over_under_run())) { - // Underrun then send zlp on IN - // Here nb_remain=0 and allows to send a IN ZLP - } else { - // A new payload buffer is given - udd_ctrl_payload_buf_cnt = 0; - nb_remain = udd_g_ctrlreq.payload_size; - } - } - // Continue transfer and send next data - if (nb_remain >= USB_DEVICE_EP_CTRL_SIZE) { - nb_remain = USB_DEVICE_EP_CTRL_SIZE; - b_shortpacket = false; - } else { - b_shortpacket = true; - } - // Fill buffer of endpoint control - ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); - ptr_src = udd_g_ctrlreq.payload + udd_ctrl_payload_buf_cnt; - // Critical section - // Only in case of DATA IN phase abort without USB Reset signal after. - // The IN data don't must be written in endpoint 0 DPRAM during - // a next setup reception in same endpoint 0 DPRAM. - // Thereby, an OUT ZLP reception must check before IN data write - // and if no OUT ZLP is received the data must be written quickly (800µs) - // before an eventually ZLP OUT and SETUP reception - flags = cpu_irq_save(); - if (Is_udd_out_received(0)) { - // IN DATA phase aborted by OUT ZLP - cpu_irq_restore(flags); - udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; - return; // Exit of IN DATA phase - } - // Write quickly the IN data - for (i = 0; i < nb_remain; i++) { - *ptr_dest++ = *ptr_src++; - } - udd_ctrl_payload_buf_cnt += nb_remain; - - // Validate and send the data available in the control endpoint buffer - udd_ack_in_send(0); - udd_enable_in_send_interrupt(0); - // In case of abort of DATA IN phase, no need to enable nak OUT interrupt - // because OUT endpoint is already free and ZLP OUT accepted. - cpu_irq_restore(flags); -} - - -static void udd_ctrl_out_received(void) -{ - irqflags_t flags; - uint8_t i; - uint16_t nb_data; - - if (UDD_EPCTRL_DATA_OUT != udd_ep_control_state) { - if ((UDD_EPCTRL_DATA_IN == udd_ep_control_state) - || (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == - udd_ep_control_state)) { - // End of SETUP request: - // - Data IN Phase aborted, - // - or last Data IN Phase hidden by ZLP OUT sending quiclky, - // - or ZLP OUT received normally. - udd_ctrl_endofrequest(); - } else { - // Protocol error during SETUP request - udd_ctrl_stall_data(); - } - // Reinitializes control endpoint management - udd_ctrl_init(); - return; - } - // Read data received during OUT phase - nb_data = udd_byte_count(0); - if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_buf_cnt + nb_data)) { - // Payload buffer too small - nb_data = udd_g_ctrlreq.payload_size - udd_ctrl_payload_buf_cnt; - } - uint8_t *ptr_src = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); - uint8_t *ptr_dest = udd_g_ctrlreq.payload + udd_ctrl_payload_buf_cnt; - for (i = 0; i < nb_data; i++) { - *ptr_dest++ = *ptr_src++; - } - udd_ctrl_payload_buf_cnt += nb_data; - - if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) - || (udd_g_ctrlreq.req.wLength <= - (udd_ctrl_prev_payload_buf_cnt + - udd_ctrl_payload_buf_cnt))) { - // End of reception because it is a short packet - // Before send ZLP, call intermediate callback - // in case of data receiv generate a stall - udd_g_ctrlreq.payload_size = udd_ctrl_payload_buf_cnt; - if (NULL != udd_g_ctrlreq.over_under_run) { - if (!udd_g_ctrlreq.over_under_run()) { - // Stall ZLP - udd_ctrl_stall_data(); - // Ack reception of OUT to replace NAK by a STALL - udd_ack_out_received(0); - return; - } - } - // Send IN ZLP to ACK setup request - udd_ack_out_received(0); - udd_ctrl_send_zlp_in(); - return; - } - - if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_buf_cnt) { - // Overrun then request a new payload buffer - if (!udd_g_ctrlreq.over_under_run) { - // No callback available to request a new payload buffer - udd_ctrl_stall_data(); - // Ack reception of OUT to replace NAK by a STALL - udd_ack_out_received(0); - return; - } - if (!udd_g_ctrlreq.over_under_run()) { - // No new payload buffer delivered - udd_ctrl_stall_data(); - // Ack reception of OUT to replace NAK by a STALL - udd_ack_out_received(0); - return; - } - // New payload buffer available - // Update number of total data received - udd_ctrl_prev_payload_buf_cnt += udd_ctrl_payload_buf_cnt; - // Reinit reception on payload buffer - udd_ctrl_payload_buf_cnt = 0; - } - // Free buffer of control endpoint to authorize next reception - udd_ack_out_received(0); - // To detect a protocol error, enable nak interrupt on data IN phase - udd_ack_nak_in(0); - flags = cpu_irq_save(); - udd_enable_nak_in_interrupt(0); - cpu_irq_restore(flags); -} - - -static void udd_ctrl_underflow(void) -{ - if (Is_udd_out_received(0)) - return; // Underflow ignored if OUT data is received - - if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { - // Host want to stop OUT transaction - // then stop to wait OUT data phase and wait IN ZLP handshake - udd_ctrl_send_zlp_in(); - } else if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { - // A OUT handshake is waiting by device, - // but host want extra IN data then stall extra IN data - udd_enable_stall_handshake(0); - } -} - - -static void udd_ctrl_overflow(void) -{ - if (Is_udd_in_send(0)) - return; // Overflow ignored if IN data is received - - // The case of UDD_EPCTRL_DATA_IN is not managed - // because the OUT endpoint is already free and OUT ZLP accepted - - if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { - // A IN handshake is waiting by device, - // but host want extra OUT data then stall extra OUT data - udd_enable_stall_handshake(0); - } -} - - -static void udd_ctrl_stall_data(void) -{ - // Stall all packets on IN & OUT control endpoint - udd_ep_control_state = UDD_EPCTRL_STALL_REQ; - udd_enable_stall_handshake(0); -} - - -static void udd_ctrl_send_zlp_in(void) -{ - irqflags_t flags; - - udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP; - - // Validate and send empty IN packet on control endpoint - flags = cpu_irq_save(); - // Send ZLP on IN endpoint - udd_ack_in_send(0); - udd_enable_in_send_interrupt(0); - // To detect a protocol error, enable nak interrupt on data OUT phase - udd_ack_nak_out(0); - udd_enable_nak_out_interrupt(0); - cpu_irq_restore(flags); -} - - -static void udd_ctrl_send_zlp_out(void) -{ - irqflags_t flags; - - udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; - // No action is necessary to accept OUT ZLP - // because the buffer of control endpoint is already free - - // To detect a protocol error, enable nak interrupt on data IN phase - flags = cpu_irq_save(); - udd_ack_nak_in(0); - udd_enable_nak_in_interrupt(0); - cpu_irq_restore(flags); -} - - -static void udd_ctrl_endofrequest(void) -{ - // If a callback is registered then call it - if (udd_g_ctrlreq.callback) { - udd_g_ctrlreq.callback(); - } -} - - -static bool udd_ctrl_interrupt(void) -{ - - if (!Is_udd_endpoint_interrupt(0)) { - return false; // No interrupt events on control endpoint - } - - dbg_print("0: "); - - // By default disable overflow and underflow interrupt - udd_disable_nak_in_interrupt(0); - udd_disable_nak_out_interrupt(0); - - // Search event on control endpoint - if (Is_udd_setup_received(0)) { - dbg_print("stup "); - // SETUP packet received - udd_ctrl_setup_received(); - return true; - } - if (Is_udd_in_send(0) && Is_udd_in_send_interrupt_enabled(0)) { - dbg_print("in "); - // IN packet sent - udd_ctrl_in_sent(); - return true; - } - if (Is_udd_out_received(0)) { - dbg_print("out "); - // OUT packet received - udd_ctrl_out_received(); - return true; - } - if (Is_udd_nak_out(0)) { - dbg_print("nako "); - // Overflow on OUT packet - udd_ack_nak_out(0); - udd_ctrl_overflow(); - return true; - } - if (Is_udd_nak_in(0)) { - dbg_print("naki "); - // Underflow on IN packet - udd_ack_nak_in(0); - udd_ctrl_underflow(); - return true; - } - dbg_print("n%x ", UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], 0)); - return false; -} - - -// ------------------------ -//--- INTERNAL ROUTINES TO MANAGED THE BULK/INTERRUPT/ISOCHRONOUS ENDPOINTS - -#if (0 != USB_DEVICE_MAX_EP) - -static void udd_ep_job_table_reset(void) -{ - uint8_t i; - for (i = 0; i < USB_DEVICE_MAX_EP; i++) { - udd_ep_job[i].busy = false; - udd_ep_job[i].stall_requested = false; - } -} - - -static void udd_ep_job_table_kill(void) -{ - uint8_t i; - - // For each endpoint, kill job - for (i = 0; i < USB_DEVICE_MAX_EP; i++) { - udd_ep_finish_job(&udd_ep_job[i], true, i + 1); - } -} - - -static void udd_ep_abort_job(udd_ep_id_t ep) -{ - ep &= USB_EP_ADDR_MASK; - - // Abort job on endpoint - udd_ep_finish_job(&udd_ep_job[ep - 1], true, ep); -} - - -static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort, uint8_t ep_num) -{ - if (ptr_job->busy == false) { - return; // No on-going job - } - dbg_print("(JobE%x:%d) ", (ptr_job-udd_ep_job)+1, b_abort); - ptr_job->busy = false; - if (NULL == ptr_job->call_trans) { - return; // No callback linked to job - } - if (Is_udd_endpoint_in(ep_num)) { - ep_num |= USB_EP_DIR_IN; - } - ptr_job->call_trans((b_abort) ? UDD_EP_TRANSFER_ABORT : - UDD_EP_TRANSFER_OK, ptr_job->buf_size, ep_num); -} - -#ifdef UDD_EP_DMA_SUPPORTED -static void udd_ep_trans_done(udd_ep_id_t ep) -{ - uint32_t udd_dma_ctrl = 0; - udd_ep_job_t *ptr_job; - iram_size_t next_trans; - irqflags_t flags; - - // Get job corresponding at endpoint - ptr_job = &udd_ep_job[ep - 1]; - - if (!ptr_job->busy) { - return; // No job is running, then ignore it (system error) - } - - if (ptr_job->buf_cnt != ptr_job->buf_size) { - // Need to send or receiv other data - next_trans = ptr_job->buf_size - ptr_job->buf_cnt; - - if (UDD_ENDPOINT_MAX_TRANS < next_trans) { - // The USB hardware support a maximum - // transfer size of UDD_ENDPOINT_MAX_TRANS Bytes - next_trans = UDD_ENDPOINT_MAX_TRANS; - - // Set 0 to transfer the maximum - udd_dma_ctrl = UOTGHS_DEVDMACONTROL_BUFF_LENGTH(0); - } else { - udd_dma_ctrl = UOTGHS_DEVDMACONTROL_BUFF_LENGTH(next_trans); - } - if (Is_udd_endpoint_in(ep)) { - if (0 != (next_trans % udd_get_endpoint_size(ep))) { - // Enable short packet option - // else the DMA transfer is accepted - // and interrupt DMA valid but nothing is sent. - udd_dma_ctrl |= UOTGHS_DEVDMACONTROL_END_B_EN; - // No need to request another ZLP - ptr_job->b_shortpacket = false; - } - } else { - if ((USB_EP_TYPE_ISOCHRONOUS != udd_get_endpoint_type(ep)) - || (next_trans <= (iram_size_t) udd_get_endpoint_size(ep))) { - - // Enable short packet reception - udd_dma_ctrl |= UOTGHS_DEVDMACONTROL_END_TR_IT - | UOTGHS_DEVDMACONTROL_END_TR_EN; - } - } - - // Start USB DMA to fill or read fifo of the selected endpoint - udd_endpoint_dma_set_addr(ep, (uint32_t) & ptr_job->buf[ptr_job->buf_cnt]); - udd_dma_ctrl |= UOTGHS_DEVDMACONTROL_END_BUFFIT | - UOTGHS_DEVDMACONTROL_CHANN_ENB; - - - // Disable IRQs to have a short sequence - // between read of EOT_STA and DMA enable - flags = cpu_irq_save(); - if (!(udd_endpoint_dma_get_status(ep) - & UOTGHS_DEVDMASTATUS_END_TR_ST)) { - dbg_print("dmaS%x ", ep); - udd_endpoint_dma_set_control(ep, udd_dma_ctrl); - ptr_job->buf_cnt += next_trans; - ptr_job->buf_load = next_trans; - udd_enable_endpoint_dma_interrupt(ep); - cpu_irq_restore(flags); - return; - } - cpu_irq_restore(flags); - - // Here a ZLP has been received - // and the DMA transfer must be not started. - // It is the end of transfer - ptr_job->buf_size = ptr_job->buf_cnt; - } - if (Is_udd_endpoint_in(ep)) { - if (ptr_job->b_shortpacket) { - dbg_print("zlpS%x ", ep); - // Need to send a ZLP (No possible with USB DMA) - // enable interrupt to wait a free bank to sent ZLP - udd_ack_in_send(ep); - if (Is_udd_write_enabled(ep)) { - // Force interrupt in case of ep already free - udd_raise_in_send(ep); - } - udd_enable_in_send_interrupt(ep); - udd_enable_endpoint_interrupt(ep); - return; - } - } - dbg_print("dmaE "); - // Call callback to signal end of transfer - udd_ep_finish_job(ptr_job, false, ep); -} -#endif - -#ifdef UDD_EP_FIFO_SUPPORTED -static void udd_ep_in_sent(udd_ep_id_t ep) -{ - udd_ep_job_t *ptr_job = &udd_ep_job[ep - 1]; - uint8_t *ptr_src = &ptr_job->buf[ptr_job->buf_cnt]; - uint8_t *ptr_dst = (uint8_t *) & udd_get_endpoint_fifo_access(ep, 8); - uint32_t pkt_size = udd_get_endpoint_size(ep); - uint32_t nb_data = 0, i; - uint32_t nb_remain; - irqflags_t flags; - - // All transfer done, including ZLP, Finish Job - if (ptr_job->buf_cnt >= ptr_job->buf_size && !ptr_job->b_shortpacket) { - flags = cpu_irq_save(); - udd_disable_in_send_interrupt(ep); - udd_disable_endpoint_interrupt(ep); - cpu_irq_restore(flags); - - ptr_job->buf_size = ptr_job->buf_cnt; // buf_size is passed to callback as XFR count - udd_ep_finish_job(ptr_job, false, ep); - return; - } else { - // ACK TXINI - udd_ack_in_send(ep); - // Fill FIFO - ptr_dst = (uint8_t *) & udd_get_endpoint_fifo_access(ep, 8); - ptr_src = &ptr_job->buf[ptr_job->buf_cnt]; - nb_remain = ptr_job->buf_size - ptr_job->buf_cnt; - // Fill a bank even if no data (ZLP) - nb_data = min(nb_remain, pkt_size); - // Modify job information - ptr_job->buf_cnt += nb_data; - ptr_job->buf_load = nb_data; - - // Copy buffer to FIFO - for (i = 0; i < nb_data; i++) { - *ptr_dst++ = *ptr_src++; - } - // Switch to next bank - udd_ack_fifocon(ep); - // ZLP? - if (nb_data < pkt_size) { - ptr_job->b_shortpacket = false; - } - } -} - -static void udd_ep_out_received(udd_ep_id_t ep) -{ - udd_ep_job_t *ptr_job = &udd_ep_job[ep - 1]; - uint32_t nb_data = 0, i; - uint32_t nb_remain = ptr_job->buf_size - ptr_job->buf_cnt; - uint32_t pkt_size = udd_get_endpoint_size(ep); - uint8_t *ptr_src = (uint8_t *) & udd_get_endpoint_fifo_access(ep, 8); - uint8_t *ptr_dst = &ptr_job->buf[ptr_job->buf_cnt]; - bool b_full = false, b_short = false; - - // Clear RX OUT - udd_ack_out_received(ep); - - // Read byte count - nb_data = udd_byte_count(ep); - if (nb_data < pkt_size) { - b_short = true; - } - //dbg_print("o%d ", ep); - //dbg_print("%d ", nb_data); - // Copy data if there is - if (nb_data > 0) { - if (nb_data >= nb_remain) { - nb_data = nb_remain; - b_full = true; - } - // Modify job information - ptr_job->buf_cnt += nb_data; - ptr_job->buf_load = nb_data; - // Copy FIFO to buffer - for (i = 0; i < nb_data; i++) { - *ptr_dst++ = *ptr_src++; - } - } - // Clear FIFO Status - udd_ack_fifocon(ep); - // Finish job on error or short packet - if (b_full || b_short) { - //dbg_print("EoO%d\n\r", ep); - udd_disable_out_received_interrupt(ep); - udd_disable_endpoint_interrupt(ep); - ptr_job->buf_size = ptr_job->buf_cnt; // buf_size is passed to callback as XFR count - udd_ep_finish_job(ptr_job, false, ep); - } -} -#endif // #ifdef UDD_EP_FIFO_SUPPORTED - -static bool udd_ep_interrupt(void) -{ - udd_ep_id_t ep; - udd_ep_job_t *ptr_job; - - // For each endpoint different of control endpoint (0) - for (ep = 1; ep <= USB_DEVICE_MAX_EP; ep++) { - // Get job corresponding at endpoint - ptr_job = &udd_ep_job[ep - 1]; - -#ifdef UDD_EP_DMA_SUPPORTED - // Check DMA event - if (Is_udd_endpoint_dma_interrupt_enabled(ep) - && Is_udd_endpoint_dma_interrupt(ep)) { - uint32_t nb_remaining; - if (udd_endpoint_dma_get_status(ep) - & UOTGHS_DEVDMASTATUS_CHANN_ENB) { - return true; // Ignore EOT_STA interrupt - } - dbg_print("dma%x: ", ep); - udd_disable_endpoint_dma_interrupt(ep); - // Save number of data no transferred - nb_remaining = (udd_endpoint_dma_get_status(ep) & - UOTGHS_DEVDMASTATUS_BUFF_COUNT_Msk) - >> UOTGHS_DEVDMASTATUS_BUFF_COUNT_Pos; - if (nb_remaining) { - // Transfer no complete (short packet or ZLP) then: - // Update number of data transferred - ptr_job->buf_cnt -= nb_remaining; - // Set transfer complete to stop the transfer - ptr_job->buf_size = ptr_job->buf_cnt; - } - udd_ep_trans_done(ep); - return true; - } -#endif -#ifdef UDD_EP_FIFO_SUPPORTED - // Check RXRDY and TXEMPTY event for none DMA endpoints - if (!Is_udd_endpoint_dma_supported(ep) - && Is_udd_endpoint_interrupt_enabled(ep)) { - dbg_print("ep%x: ", ep); - // RXOUT: Full packet received - if (Is_udd_out_received(ep) - && Is_udd_out_received_interrupt_enabled(ep)) { - dbg_print("Out "); - udd_ep_out_received(ep); - return true; - } - // TXIN: packet sent - if (Is_udd_in_send(ep) - && Is_udd_in_send_interrupt_enabled(ep)) { - dbg_print("In "); - udd_ep_in_sent(ep); - return true; - } - // Errors: Abort? - if (Is_udd_overflow(ep) - || Is_udd_underflow(ep) - || Is_udd_crc_error(ep)) { - dbg_print("Err "); - udd_ep_abort(ep); - return true; - } - } -#endif // UDD_EP_FIFO_SUPPORTED - // Check empty bank interrupt event - if (Is_udd_endpoint_interrupt_enabled(ep)) { - dbg_print("bg%x: ", ep); - if (Is_udd_in_send_interrupt_enabled(ep) - && Is_udd_in_send(ep)) { - dbg_print("I "); - udd_disable_in_send_interrupt(ep); - // One bank is free then send a ZLP - udd_ack_in_send(ep); - udd_ack_fifocon(ep); - udd_ep_finish_job(ptr_job, false, ep); - return true; - } - if (Is_udd_bank_interrupt_enabled(ep) - && (0 == udd_nb_busy_bank(ep))) { - dbg_print("EoT "); - // End of background transfer on IN endpoint - udd_disable_bank_interrupt(ep); - udd_disable_endpoint_interrupt(ep); - - Assert(ptr_job->stall_requested); - // A stall has been requested during background transfer - ptr_job->stall_requested = false; - udd_disable_endpoint_bank_autoswitch(ep); - udd_enable_stall_handshake(ep); - udd_reset_data_toggle(ep); - return true; - } - } - } - return false; -} -#endif // (0 != USB_DEVICE_MAX_EP) - -//@} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/uotghs_device_due.h b/src/HAL/DUE/usb/uotghs_device_due.h deleted file mode 100644 index 6df26d6..0000000 --- a/src/HAL/DUE/usb/uotghs_device_due.h +++ /dev/null @@ -1,664 +0,0 @@ -/** - * \file - * - * \brief USB Device Driver for UOTGHS. Compliant with common UDD driver. - * - * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef UOTGHS_DEVICE_DUE_H_INCLUDED -#define UOTGHS_DEVICE_DUE_H_INCLUDED - -//#include "compiler.h" - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -extern "C" { -#endif -/**INDENT-ON**/ -/// @endcond - -//! \ingroup udd_group -//! \defgroup udd_udphs_group USB On-The-Go High-Speed Port for device mode (UOTGHS) -//! UOTGHS low-level driver for USB device mode -//! -//! @{ - -#ifndef UOTGHS_DEVEPTCFG_EPDIR_Pos -// Bit pos is not defined in SAM header file but we need it. -# define UOTGHS_DEVEPTCFG_EPDIR_Pos 8 -#endif - -//! @name UOTGHS Device IP properties -//! These macros give access to IP properties -//! @{ - //! Get maximal number of endpoints -#define udd_get_endpoint_max_nbr() (9) -#define UDD_MAX_PEP_NB (udd_get_endpoint_max_nbr() + 1) - //! Get maximal number of banks of endpoints -#define udd_get_endpoint_bank_max_nbr(ep) ((ep == 0) ? 1 : (( ep <= 2) ? 3 : 2)) - //! Get maximal size of endpoint (3X, 1024/64) -#define udd_get_endpoint_size_max(ep) (((ep) == 0) ? 64 : 1024) - //! Get DMA support of endpoints -#define Is_udd_endpoint_dma_supported(ep) ((((ep) >= 1) && ((ep) <= 6)) ? true : false) - //! Get High Band Width support of endpoints -#define Is_udd_endpoint_high_bw_supported(ep) (((ep) >= 2) ? true : false) -//! @} - -//! @name UOTGHS Device speeds management -//! @{ - //! Enable/disable device low-speed mode -#define udd_low_speed_enable() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS)) -#define udd_low_speed_disable() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS)) - //! Test if device low-speed mode is forced -#define Is_udd_low_speed_enable() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_LS)) - -#ifdef UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED - //! Enable high speed mode -# define udd_high_speed_enable() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 0)) - //! Disable high speed mode -# define udd_high_speed_disable() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 3)) - //! Test if controller is in full speed mode -# define Is_udd_full_speed_mode() (Rd_bitfield(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk) == UOTGHS_SR_SPEED_FULL_SPEED) -#else -# define udd_high_speed_enable() do { } while (0) -# define udd_high_speed_disable() do { } while (0) -# define Is_udd_full_speed_mode() true -#endif -//! @} - -//! @name UOTGHS Device HS test mode management -//! @{ -#ifdef UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED - //! Enable high speed test mode -# define udd_enable_hs_test_mode() (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_SPDCONF_Msk, 2)) -# define udd_enable_hs_test_mode_j() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTJ)) -# define udd_enable_hs_test_mode_k() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTK)) -# define udd_enable_hs_test_mode_packet() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_TSTPCKT)) -#endif -//! @} - -//! @name UOTGHS Device vbus management -//! @{ -#define udd_enable_vbus_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define udd_disable_vbus_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define Is_udd_vbus_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define Is_udd_vbus_high() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUS)) -#define Is_udd_vbus_low() (!Is_udd_vbus_high()) -#define udd_ack_vbus_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC) -#define udd_raise_vbus_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS) -#define Is_udd_vbus_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSTI)) -//! @} - - -//! @name UOTGHS device attach control -//! These macros manage the UOTGHS Device attach. -//! @{ - //! Detaches from USB bus -#define udd_detach_device() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_DETACH)) - //! Attaches to USB bus -#define udd_attach_device() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_DETACH)) - //! Test if the device is detached -#define Is_udd_detached() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_DETACH)) -//! @} - - -//! @name UOTGHS device bus events control -//! These macros manage the UOTGHS Device bus events. -//! @{ - -//! Initiates a remote wake-up event -//! @{ -#define udd_initiate_remote_wake_up() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_RMWKUP)) -#define Is_udd_pending_remote_wake_up() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_RMWKUP)) -//! @} - -//! Manage upstream resume event (=remote wakeup) -//! The USB driver sends a resume signal called "Upstream Resume" -//! @{ -#define udd_enable_remote_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_UPRSMES) -#define udd_disable_remote_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_UPRSMEC) -#define Is_udd_remote_wake_up_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_UPRSME)) -#define udd_ack_remote_wake_up_start() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_UPRSMC) -#define udd_raise_remote_wake_up_start() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_UPRSMS) -#define Is_udd_remote_wake_up_start() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_UPRSM)) -//! @} - -//! Manage downstream resume event (=remote wakeup from host) -//! The USB controller detects a valid "End of Resume" signal initiated by the host -//! @{ -#define udd_enable_resume_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSMES) -#define udd_disable_resume_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSMEC) -#define Is_udd_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSME)) -#define udd_ack_resume() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSMC) -#define udd_raise_resume() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSMS) -#define Is_udd_resume() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_EORSM)) -//! @} - -//! Manage wake-up event (=usb line activity) -//! The USB controller is reactivated by a filtered non-idle signal from the lines -//! @{ -#define udd_enable_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES) -#define udd_disable_wake_up_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_WAKEUPEC) -#define Is_udd_wake_up_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_WAKEUPE)) -#define udd_ack_wake_up() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_WAKEUPC) -#define udd_raise_wake_up() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_WAKEUPS) -#define Is_udd_wake_up() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_WAKEUP)) -//! @} - -//! Manage reset event -//! Set when a USB "End of Reset" has been detected -//! @{ -#define udd_enable_reset_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSTES) -#define udd_disable_reset_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSTEC) -#define Is_udd_reset_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSTE)) -#define udd_ack_reset() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSTC) -#define udd_raise_reset() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSTS) -#define Is_udd_reset() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_EORST)) -//! @} - -//! Manage start of frame event -//! @{ -#define udd_enable_sof_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_SOFES) -#define udd_disable_sof_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SOFEC) -#define Is_udd_sof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SOFE)) -#define udd_ack_sof() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_SOFC) -#define udd_raise_sof() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SOFS) -#define Is_udd_sof() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_SOF)) -#define udd_frame_number() (Rd_bitfield(UOTGHS->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNUM_Msk)) -#define Is_udd_frame_number_crc_error() (Tst_bits(UOTGHS->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNCERR)) -//! @} - -//! Manage Micro start of frame event (High Speed Only) -//! @{ -#define udd_enable_msof_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_MSOFES) -#define udd_disable_msof_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_MSOFEC) -#define Is_udd_msof_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_MSOFE)) -#define udd_ack_msof() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVIMR_MSOFE) -#define udd_raise_msof() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_MSOFS) -#define Is_udd_msof() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_MSOF)) -#define udd_micro_frame_number() \ - (Rd_bitfield(UOTGHS->UOTGHS_DEVFNUM, (UOTGHS_DEVFNUM_FNUM_Msk|UOTGHS_DEVFNUM_MFNUM_Msk))) -//! @} - -//! Manage suspend event -//! @{ -#define udd_enable_suspend_interrupt() (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_SUSPES) -#define udd_disable_suspend_interrupt() (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC) -#define Is_udd_suspend_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SUSPE)) -#define udd_ack_suspend() (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVICR_SUSPC) -#define udd_raise_suspend() (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SUSPS) -#define Is_udd_suspend() (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_SUSP)) -//! @} - -//! @} - -//! @name UOTGHS device address control -//! These macros manage the UOTGHS Device address. -//! @{ - //! enables USB device address -#define udd_enable_address() (Set_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN)) - //! disables USB device address -#define udd_disable_address() (Clr_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN)) -#define Is_udd_address_enabled() (Tst_bits(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN)) - //! configures the USB device address -#define udd_configure_address(addr) (Wr_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_UADD_Msk, addr)) - //! gets the currently configured USB device address -#define udd_get_configured_address() (Rd_bitfield(UOTGHS->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_UADD_Msk)) -//! @} - - -//! @name UOTGHS Device endpoint drivers -//! These macros manage the common features of the endpoints. -//! @{ - -//! Generic macro for UOTGHS registers that can be arrayed -//! @{ -#define UOTGHS_ARRAY(reg,index) ((&(UOTGHS->reg))[(index)]) -//! @} - -//! @name UOTGHS Device endpoint configuration -//! @{ - //! enables the selected endpoint -#define udd_enable_endpoint(ep) (Set_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep))) - //! disables the selected endpoint -#define udd_disable_endpoint(ep) (Clr_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep))) - //! tests if the selected endpoint is enabled -#define Is_udd_endpoint_enabled(ep) (Tst_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep))) - //! resets the selected endpoint -#define udd_reset_endpoint(ep) \ - do { \ - Set_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \ - Clr_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \ - } while (0) - //! Tests if the selected endpoint is being reset -#define Is_udd_resetting_endpoint(ep) (Tst_bits(UOTGHS->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep))) - - //! Configures the selected endpoint type -#define udd_configure_endpoint_type(ep, type) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk, type)) - //! Gets the configured selected endpoint type -#define udd_get_endpoint_type(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk)) - //! Enables the bank autoswitch for the selected endpoint -#define udd_enable_endpoint_bank_autoswitch(ep) (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) - //! Disables the bank autoswitch for the selected endpoint -#define udd_disable_endpoint_bank_autoswitch(ep) (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) -#define Is_udd_endpoint_bank_autoswitch_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW)) - //! Configures the selected endpoint direction -#define udd_configure_endpoint_direction(ep, dir) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR, dir)) - //! Gets the configured selected endpoint direction -#define udd_get_endpoint_direction(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR)) -#define Is_udd_endpoint_in(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR)) - //! Bounds given integer size to allowed range and rounds it up to the nearest - //! available greater size, then applies register format of UOTGHS controller - //! for endpoint size bit-field. -#undef udd_format_endpoint_size -#define udd_format_endpoint_size(size) (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3) - //! Configures the selected endpoint size -#define udd_configure_endpoint_size(ep, size) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk, udd_format_endpoint_size(size))) - //! Gets the configured selected endpoint size -#define udd_get_endpoint_size(ep) (8 << Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk)) - //! Configures the selected endpoint number of banks -#define udd_configure_endpoint_bank(ep, bank) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk, bank)) - //! Gets the configured selected endpoint number of banks -#define udd_get_endpoint_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk)+1) - //! Allocates the configuration selected endpoint in DPRAM memory -#define udd_allocate_memory(ep) (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) - //! un-allocates the configuration selected endpoint in DPRAM memory -#define udd_unallocate_memory(ep) (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) -#define Is_udd_memory_allocated(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC)) - - //! Configures selected endpoint in one step -#define udd_configure_endpoint(ep, type, dir, size, bank) (\ - Wr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk |\ - UOTGHS_DEVEPTCFG_EPDIR |\ - UOTGHS_DEVEPTCFG_EPSIZE_Msk |\ - UOTGHS_DEVEPTCFG_EPBK_Msk , \ - (((uint32_t)(type) << UOTGHS_DEVEPTCFG_EPTYPE_Pos) & UOTGHS_DEVEPTCFG_EPTYPE_Msk) |\ - (((uint32_t)(dir ) << UOTGHS_DEVEPTCFG_EPDIR_Pos ) & UOTGHS_DEVEPTCFG_EPDIR) |\ - ( (uint32_t)udd_format_endpoint_size(size) << UOTGHS_DEVEPTCFG_EPSIZE_Pos) |\ - (((uint32_t)(bank) << UOTGHS_DEVEPTCFG_EPBK_Pos) & UOTGHS_DEVEPTCFG_EPBK_Msk))\ -) - //! Tests if current endpoint is configured -#define Is_udd_endpoint_configured(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CFGOK)) - //! Returns the control direction -#define udd_control_direction() (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], EP_CONTROL), UOTGHS_DEVEPTISR_CTRLDIR)) - - //! Resets the data toggle sequence -#define udd_reset_data_toggle(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RSTDTS) - //! Tests if the data toggle sequence is being reset -#define Is_udd_data_toggle_reset(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RSTDT)) - //! Returns data toggle -#define udd_data_toggle(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_DTSEQ_Msk)) -//! @} - - -//! @name UOTGHS Device control endpoint -//! These macros control the endpoints. -//! @{ - -//! @name UOTGHS Device control endpoint interrupts -//! These macros control the endpoints interrupts. -//! @{ - //! Enables the selected endpoint interrupt -#define udd_enable_endpoint_interrupt(ep) (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_PEP_0 << (ep)) - //! Disables the selected endpoint interrupt -#define udd_disable_endpoint_interrupt(ep) (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_PEP_0 << (ep)) - //! Tests if the selected endpoint interrupt is enabled -#define Is_udd_endpoint_interrupt_enabled(ep) (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_PEP_0 << (ep))) - //! Tests if an interrupt is triggered by the selected endpoint -#define Is_udd_endpoint_interrupt(ep) (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_PEP_0 << (ep))) - //! Returns the lowest endpoint number generating an endpoint interrupt or MAX_PEP_NB if none -#define udd_get_interrupt_endpoint_number() (ctz(((UOTGHS->UOTGHS_DEVISR >> UOTGHS_DEVISR_PEP_Pos) & \ - (UOTGHS->UOTGHS_DEVIMR >> UOTGHS_DEVIMR_PEP_Pos)) | \ - (1 << MAX_PEP_NB))) -#define UOTGHS_DEVISR_PEP_Pos 12 -#define UOTGHS_DEVIMR_PEP_Pos 12 -//! @} - -//! @name UOTGHS Device control endpoint errors -//! These macros control the endpoint errors. -//! @{ - //! Enables the STALL handshake -#define udd_enable_stall_handshake(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLRQS) - //! Disables the STALL handshake -#define udd_disable_stall_handshake(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLRQC) - //! Tests if STALL handshake request is running -#define Is_udd_endpoint_stall_requested(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLRQ)) - //! Tests if STALL sent -#define Is_udd_stall(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_STALLEDI)) - //! ACKs STALL sent -#define udd_ack_stall(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_STALLEDIC) - //! Raises STALL sent -#define udd_raise_stall(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_STALLEDIS) - //! Enables STALL sent interrupt -#define udd_enable_stall_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLEDES) - //! Disables STALL sent interrupt -#define udd_disable_stall_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLEDEC) - //! Tests if STALL sent interrupt is enabled -#define Is_udd_stall_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLEDE)) - - //! Tests if NAK OUT received -#define Is_udd_nak_out(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKOUTI)) - //! ACKs NAK OUT received -#define udd_ack_nak_out(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKOUTIC) - //! Raises NAK OUT received -#define udd_raise_nak_out(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKOUTIS) - //! Enables NAK OUT interrupt -#define udd_enable_nak_out_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKOUTES) - //! Disables NAK OUT interrupt -#define udd_disable_nak_out_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKOUTEC) - //! Tests if NAK OUT interrupt is enabled -#define Is_udd_nak_out_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKOUTE)) - - //! Tests if NAK IN received -#define Is_udd_nak_in(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKINI)) - //! ACKs NAK IN received -#define udd_ack_nak_in(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKINIC) - //! Raises NAK IN received -#define udd_raise_nak_in(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKINIS) - //! Enables NAK IN interrupt -#define udd_enable_nak_in_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKINES) - //! Disables NAK IN interrupt -#define udd_disable_nak_in_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKINEC) - //! Tests if NAK IN interrupt is enabled -#define Is_udd_nak_in_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKINE)) - - //! ACKs endpoint isochronous overflow interrupt -#define udd_ack_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_OVERFIC) - //! Raises endpoint isochronous overflow interrupt -#define udd_raise_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_OVERFIS) - //! Tests if an overflow occurs -#define Is_udd_overflow(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_OVERFI)) - //! Enables overflow interrupt -#define udd_enable_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_OVERFES) - //! Disables overflow interrupt -#define udd_disable_overflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_OVERFEC) - //! Tests if overflow interrupt is enabled -#define Is_udd_overflow_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_OVERFE)) - - //! ACKs endpoint isochronous underflow interrupt -#define udd_ack_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_UNDERFIC) - //! Raises endpoint isochronous underflow interrupt -#define udd_raise_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_UNDERFIS) - //! Tests if an underflow occurs -#define Is_udd_underflow(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_UNDERFI)) - //! Enables underflow interrupt -#define udd_enable_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_UNDERFES) - //! Disables underflow interrupt -#define udd_disable_underflow_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_UNDERFEC) - //! Tests if underflow interrupt is enabled -#define Is_udd_underflow_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_UNDERFE)) - - //! Tests if CRC ERROR ISO OUT detected -#define Is_udd_crc_error(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CRCERRI)) - //! ACKs CRC ERROR ISO OUT detected -#define udd_ack_crc_error(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_CRCERRIC) - //! Raises CRC ERROR ISO OUT detected -#define udd_raise_crc_error(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_CRCERRIS) - //! Enables CRC ERROR ISO OUT detected interrupt -#define udd_enable_crc_error_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_CRCERRES) - //! Disables CRC ERROR ISO OUT detected interrupt -#define udd_disable_crc_error_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_CRCERREC) - //! Tests if CRC ERROR ISO OUT detected interrupt is enabled -#define Is_udd_crc_error_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_CRCERRE)) -//! @} - -//! @name UOTGHS Device control endpoint transfer -//! These macros control the endpoint transfer. -//! @{ - - //! Tests if endpoint read allowed -#define Is_udd_read_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL)) - //! Tests if endpoint write allowed -#define Is_udd_write_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL)) - - //! Returns the byte count -#define udd_byte_count(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_BYCT_Msk)) - //! Clears FIFOCON bit -#define udd_ack_fifocon(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_FIFOCONC) - //! Tests if FIFOCON bit set -#define Is_udd_fifocon(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_FIFOCON)) - - //! Returns the number of busy banks -#define udd_nb_busy_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NBUSYBK_Msk)) - //! Returns the number of the current bank -#define udd_current_bank(ep) (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CURRBK_Msk)) - //! Kills last bank -#define udd_kill_last_in_bank(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_KILLBKS) -#define Is_udd_kill_last(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK)) - //! Tests if last bank killed -#define Is_udd_last_in_bank_killed(ep) (!Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK)) - //! Forces all banks full (OUT) or free (IN) interrupt -#define udd_force_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS) - //! Unforces all banks full (OUT) or free (IN) interrupt -#define udd_unforce_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS) - //! Enables all banks full (OUT) or free (IN) interrupt -#define udd_enable_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NBUSYBKES) - //! Disables all banks full (OUT) or free (IN) interrupt -#define udd_disable_bank_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NBUSYBKEC) - //! Tests if all banks full (OUT) or free (IN) interrupt enabled -#define Is_udd_bank_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NBUSYBKE)) - - //! Tests if SHORT PACKET received -#define Is_udd_short_packet(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_SHORTPACKET)) - //! ACKs SHORT PACKET received -#define udd_ack_short_packet(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_SHORTPACKETC) - //! Raises SHORT PACKET received -#define udd_raise_short_packet(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_SHORTPACKETS) - //! Enables SHORT PACKET received interrupt -#define udd_enable_short_packet_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_SHORTPACKETES) - //! Disables SHORT PACKET received interrupt -#define udd_disable_short_packet_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_SHORTPACKETEC) - //! Tests if SHORT PACKET received interrupt is enabled -#define Is_udd_short_packet_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_SHORTPACKETE)) - - //! Tests if SETUP received -#define Is_udd_setup_received(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXSTPI)) - //! ACKs SETUP received -#define udd_ack_setup_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXSTPIC) - //! Raises SETUP received -#define udd_raise_setup_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXSTPIS) - //! Enables SETUP received interrupt -#define udd_enable_setup_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXSTPES) - //! Disables SETUP received interrupt -#define udd_disable_setup_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXSTPEC) - //! Tests if SETUP received interrupt is enabled -#define Is_udd_setup_received_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXSTPE)) - - //! Tests if OUT received -#define Is_udd_out_received(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXOUTI)) - //! ACKs OUT received -#define udd_ack_out_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXOUTIC) - //! Raises OUT received -#define udd_raise_out_received(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXOUTIS) - //! Enables OUT received interrupt -#define udd_enable_out_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXOUTES) - //! Disables OUT received interrupt -#define udd_disable_out_received_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXOUTEC) - //! Tests if OUT received interrupt is enabled -#define Is_udd_out_received_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXOUTE)) - - //! Tests if IN sending -#define Is_udd_in_send(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_TXINI)) - //! ACKs IN sending -#define udd_ack_in_send(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_TXINIC) - //! Raises IN sending -#define udd_raise_in_send(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_TXINIS) - //! Enables IN sending interrupt -#define udd_enable_in_send_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_TXINES) - //! Disables IN sending interrupt -#define udd_disable_in_send_interrupt(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_TXINEC) - //! Tests if IN sending interrupt is enabled -#define Is_udd_in_send_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_TXINE)) - - - //! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected endpoint. - //! @param ep Endpoint of which to access FIFO data register - //! @param scale Data scale in bits: 64, 32, 16 or 8 - //! @return Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register - //! @warning It is up to the user of this macro to make sure that all accesses - //! are aligned with their natural boundaries except 64-bit accesses which - //! require only 32-bit alignment. - //! @warning It is up to the user of this macro to make sure that used HSB - //! addresses are identical to the DPRAM internal pointer modulo 32 bits. -#define udd_get_endpoint_fifo_access(ep, scale) \ - (((volatile TPASTE2(U, scale) (*)[0x8000 / ((scale) / 8)])UOTGHS_RAM_ADDR)[(ep)]) - -//! @name UOTGHS endpoint DMA drivers -//! These macros manage the common features of the endpoint DMA channels. -//! @{ - - //! Maximum transfer size on USB DMA -#define UDD_ENDPOINT_MAX_TRANS 0x10000 - //! Enables the disabling of HDMA requests by endpoint interrupts -#define udd_enable_endpoint_int_dis_hdma_req(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0](ep) = UOTGHS_DEVEPTIER_EPDISHDMAS) - //! Disables the disabling of HDMA requests by endpoint interrupts -#define udd_disable_endpoint_int_dis_hdma_req(ep) (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0](ep) = UOTGHS_DEVEPTIDR_EPDISHDMAC) - //! Tests if the disabling of HDMA requests by endpoint interrupts is enabled -#define Is_udd_endpoint_int_dis_hdma_req_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0](ep), UOTGHS_DEVEPTIMR_EPDISHDMA)) - - //! Raises the selected endpoint DMA channel interrupt -#define udd_raise_endpoint_dma_interrupt(ep) (UOTGHS->UOTGHS_DEVIFR = UOTGHS_DEVIFR_DMA_1 << ((ep) - 1)) - //! Raises the selected endpoint DMA channel interrupt -#define udd_clear_endpoint_dma_interrupt(ep) (UOTGHS->UOTGHS_DEVICR = UOTGHS_DEVISR_DMA_1 << ((ep) - 1)) - //! Tests if an interrupt is triggered by the selected endpoint DMA channel -#define Is_udd_endpoint_dma_interrupt(ep) (Tst_bits(UOTGHS->UOTGHS_DEVISR, UOTGHS_DEVISR_DMA_1 << ((ep) - 1))) - //! Enables the selected endpoint DMA channel interrupt -#define udd_enable_endpoint_dma_interrupt(ep) (UOTGHS->UOTGHS_DEVIER = UOTGHS_DEVIER_DMA_1 << ((ep) - 1)) - //! Disables the selected endpoint DMA channel interrupt -#define udd_disable_endpoint_dma_interrupt(ep) (UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_DMA_1 << ((ep) - 1)) - //! Tests if the selected endpoint DMA channel interrupt is enabled -#define Is_udd_endpoint_dma_interrupt_enabled(ep) (Tst_bits(UOTGHS->UOTGHS_DEVIMR, UOTGHS_DEVIMR_DMA_1 << ((ep) - 1))) - - //! Access points to the UOTGHS device DMA memory map with arrayed registers - //! @{ - //! Structure for DMA next descriptor register -typedef struct { - uint32_t *NXT_DSC_ADD; -} uotghs_dma_nextdesc_t; - //! Structure for DMA control register -typedef struct { - uint32_t CHANN_ENB:1, - LDNXT_DSC:1, - END_TR_EN:1, - END_B_EN:1, - END_TR_IT:1, - END_BUFFIT:1, - DESC_LD_IT:1, - BUST_LCK:1, - reserved:8, - BUFF_LENGTH:16; -} uotghs_dma_control_t; - //! Structure for DMA status register -typedef struct { - uint32_t CHANN_ENB:1, - CHANN_ACT:1, - reserved0:2, - END_TR_ST:1, - END_BF_ST:1, - DESC_LDST:1, - reserved1:9, - BUFF_COUNT:16; -} uotghs_dma_status_t; - //! Structure for DMA descriptor -typedef struct { - union { - uint32_t nextdesc; - uotghs_dma_nextdesc_t NEXTDESC; - }; - uint32_t addr; - union { - uint32_t control; - uotghs_dma_control_t CONTROL; - }; - uint32_t reserved; -} sam_uotghs_dmadesc_t, uotghs_dmadesc_t; - //! Structure for DMA registers in a channel -typedef struct { - union { - uint32_t nextdesc; - uotghs_dma_nextdesc_t NEXTDESC; - }; - uint32_t addr; - union { - uint32_t control; - uotghs_dma_control_t CONTROL; - }; - union { - unsigned long status; - uotghs_dma_status_t STATUS; - }; -} sam_uotghs_dmach_t, uotghs_dmach_t; - //! DMA channel control command -#define UDD_ENDPOINT_DMA_STOP_NOW (0) -#define UDD_ENDPOINT_DMA_RUN_AND_STOP (UOTGHS_DEVDMACONTROL_CHANN_ENB) -#define UDD_ENDPOINT_DMA_LOAD_NEXT_DESC (UOTGHS_DEVDMACONTROL_LDNXT_DSC) -#define UDD_ENDPOINT_DMA_RUN_AND_LINK (UOTGHS_DEVDMACONTROL_CHANN_ENB|UOTGHS_DEVDMACONTROL_LDNXT_DSC) - //! Structure for DMA registers -#define UOTGHS_UDDMA_ARRAY(ep) (((volatile uotghs_dmach_t *)UOTGHS->UOTGHS_DEVDMA)[(ep) - 1]) - - //! Set control desc to selected endpoint DMA channel -#define udd_endpoint_dma_set_control(ep,desc) (UOTGHS_UDDMA_ARRAY(ep).control = desc) - //! Get control desc to selected endpoint DMA channel -#define udd_endpoint_dma_get_control(ep) (UOTGHS_UDDMA_ARRAY(ep).control) - //! Set RAM address to selected endpoint DMA channel -#define udd_endpoint_dma_set_addr(ep,add) (UOTGHS_UDDMA_ARRAY(ep).addr = add) - //! Get status to selected endpoint DMA channel -#define udd_endpoint_dma_get_status(ep) (UOTGHS_UDDMA_ARRAY(ep).status) - //! @} -//! @} - -//! @} -//! @} -//! @} -//! @} - - -/// @cond 0 -/**INDENT-OFF**/ -#ifdef __cplusplus -} -#endif -/**INDENT-ON**/ -/// @endcond - -#endif /* UOTGHS_DEVICE_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/uotghs_otg.h b/src/HAL/DUE/usb/uotghs_otg.h deleted file mode 100644 index eca5e93..0000000 --- a/src/HAL/DUE/usb/uotghs_otg.h +++ /dev/null @@ -1,241 +0,0 @@ -/** - * \file - * - * \brief USB OTG Driver for UOTGHS. - * - * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef UOTGHS_OTG_H_INCLUDED -#define UOTGHS_OTG_H_INCLUDED - -#include "compiler.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -//! \ingroup usb_group -//! \defgroup otg_group UOTGHS OTG Driver -//! UOTGHS low-level driver for OTG features -//! -//! @{ - -/** - * \brief Initialize the dual role - * This function is implemented in uotghs_host.c file. - * - * \return \c true if the ID pin management has been started, otherwise \c false. - */ -bool otg_dual_enable(void); - -/** - * \brief Uninitialize the dual role - * This function is implemented in uotghs_host.c file. - */ -void otg_dual_disable(void); - - -//! @name UOTGHS OTG ID pin management -//! The ID pin come from the USB OTG connector (A and B receptable) and -//! allows to select the USB mode host or device. -//! The UOTGHS hardware can manage it automatically. This feature is optional. -//! When USB_ID_GPIO is defined (in board.h), this feature is enabled. -//! -//! @{ - //! Enable external OTG_ID pin (listened to by USB) -#define otg_enable_id_pin() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) - //! Disable external OTG_ID pin (ignored by USB) -#define otg_disable_id_pin() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) - //! Test if external OTG_ID pin enabled (listened to by USB) -#define Is_otg_id_pin_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIDE)) - //! Disable external OTG_ID pin and force device mode -#define otg_force_device_mode() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD), otg_disable_id_pin()) - //! Test if device mode is forced -#define Is_otg_device_mode_forced() (!Is_otg_id_pin_enabled() && Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD)) - //! Disable external OTG_ID pin and force host mode -#define otg_force_host_mode() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD), otg_disable_id_pin()) - //! Test if host mode is forced -#define Is_otg_host_mode_forced() (!Is_otg_id_pin_enabled() && !Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD)) - -//! @name UOTGHS OTG ID pin interrupt management -//! These macros manage the ID pin interrupt -//! @{ -#define otg_enable_id_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) -#define otg_disable_id_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) -#define Is_otg_id_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_IDTE)) -#define Is_otg_id_device() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_ID)) -#define Is_otg_id_host() (!Is_otg_id_device()) -#define otg_ack_id_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_IDTIC) -#define otg_raise_id_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_IDTIS) -#define Is_otg_id_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_IDTI)) -//! @} -//! @} - -//! @name OTG Vbus management -//! @{ -#define otg_enable_vbus_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define otg_disable_vbus_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define Is_otg_vbus_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE)) -#define Is_otg_vbus_high() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUS)) -#define Is_otg_vbus_low() (!Is_otg_vbus_high()) -#define otg_ack_vbus_transition() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC) -#define otg_raise_vbus_transition() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS) -#define Is_otg_vbus_transition() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSTI)) -//! @} - -//! @name UOTGHS OTG main management -//! These macros allows to enable/disable pad and UOTGHS hardware -//! @{ - //! Reset USB macro -#define otg_reset() \ - do { \ - UOTGHS->UOTGHS_CTRL = 0; \ - while( UOTGHS->UOTGHS_SR & 0x3FFF) {\ - UOTGHS->UOTGHS_SCR = 0xFFFFFFFF;\ - } \ - } while (0) - //! Enable USB macro -#define otg_enable() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE)) - //! Disable USB macro -#define otg_disable() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE)) -#define Is_otg_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_USBE)) - - //! Enable OTG pad -#define otg_enable_pad() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) - //! Disable OTG pad -#define otg_disable_pad() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) -#define Is_otg_pad_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE)) - - //! Check Clock Usable - //! For parts with HS feature, this one corresponding at UTMI clock -#define Is_otg_clock_usable() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_CLKUSABLE)) - - //! Stop (freeze) internal USB clock -#define otg_freeze_clock() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) -#define otg_unfreeze_clock() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) -#define Is_otg_clock_frozen() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK)) - - //! Configure time-out of specified OTG timer -#define otg_configure_timeout(timer, timeout) (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\ - Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMPAGE_Msk, timer),\ - Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMVALUE_Msk, timeout),\ - Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK)) - //! Get configured time-out of specified OTG timer -#define otg_get_timeout(timer) (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\ - Wr_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMPAGE_Msk, timer),\ - Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_UNLOCK),\ - Rd_bitfield(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_TIMVALUE_Msk)) - - - //! Get the dual-role device state of the internal USB finite state machine of the UOTGHS controller -#define otg_get_fsm_drd_state() (Rd_bitfield(UOTGHS->UOTGHS_FSM, UOTGHS_FSM_DRDSTATE_Msk)) -#define Is_otg_a_suspend() (4==otg_get_fsm_drd_state()) -#define Is_otg_a_wait_vrise() (1==otg_get_fsm_drd_state()) -//! @} - -//! @name UOTGHS OTG hardware protocol -//! These macros manages the hardware OTG protocol -//! @{ - //! Initiates a Host negotiation Protocol -#define otg_device_initiate_hnp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ)) - //! Accepts a Host negotiation Protocol -#define otg_host_accept_hnp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ)) - //! Rejects a Host negotiation Protocol -#define otg_host_reject_hnp() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ)) - //! initiates a Session Request Protocol -#define otg_device_initiate_srp() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPREQ)) - //! Selects VBus as SRP method -#define otg_select_vbus_srp_method() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL)) -#define Is_otg_vbus_srp_method_selected() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL)) - //! Selects data line as SRP method -#define otg_select_data_srp_method() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPSEL)) -#define Is_otg_data_srp_method_selected() (!Is_otg_vbus_srp_method_selected()) - //! Tests if a HNP occurs -#define Is_otg_hnp() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPREQ)) - //! Tests if a SRP from device occurs -#define Is_otg_device_srp() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPREQ)) - - //! Enables HNP error interrupt -#define otg_enable_hnp_error_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE)) - //! Disables HNP error interrupt -#define otg_disable_hnp_error_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE)) -#define Is_otg_hnp_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_HNPERRE)) - //! ACKs HNP error interrupt -#define otg_ack_hnp_error_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_HNPERRIC) - //! Raises HNP error interrupt -#define otg_raise_hnp_error_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_HNPERRIS) - //! Tests if a HNP error occurs -#define Is_otg_hnp_error_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_HNPERRI)) - - //! Enables role exchange interrupt -#define otg_enable_role_exchange_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE)) - //! Disables role exchange interrupt -#define otg_disable_role_exchange_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE)) -#define Is_otg_role_exchange_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_ROLEEXE)) - //! ACKs role exchange interrupt -#define otg_ack_role_exchange_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_ROLEEXIC) - //! Raises role exchange interrupt -#define otg_raise_role_exchange_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_ROLEEXIS) - //! Tests if a role exchange occurs -#define Is_otg_role_exchange_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_ROLEEXI)) - - //! Enables SRP interrupt -#define otg_enable_srp_interrupt() (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE)) - //! Disables SRP interrupt -#define otg_disable_srp_interrupt() (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE)) -#define Is_otg_srp_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_SRPE)) - //! ACKs SRP interrupt -#define otg_ack_srp_interrupt() (UOTGHS->UOTGHS_SCR = UOTGHS_SCR_SRPIC) - //! Raises SRP interrupt -#define otg_raise_srp_interrupt() (UOTGHS->UOTGHS_SFR = UOTGHS_SFR_SRPIS) - //! Tests if a SRP occurs -#define Is_otg_srp_interrupt() (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SRPI)) -//! @} - -//! @} - -#ifdef __cplusplus -} -#endif - -#endif /* UOTGHS_OTG_H_INCLUDED */ diff --git a/src/HAL/DUE/usb/usb_protocol.h b/src/HAL/DUE/usb/usb_protocol.h deleted file mode 100644 index ea51a86..0000000 --- a/src/HAL/DUE/usb/usb_protocol.h +++ /dev/null @@ -1,496 +0,0 @@ -/** - * \file - * - * \brief USB protocol definitions. - * - * This file contains the USB definitions and data structures provided by the - * USB 2.0 specification. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _USB_PROTOCOL_H_ -#define _USB_PROTOCOL_H_ - -/** - * \ingroup usb_group - * \defgroup usb_protocol_group USB Protocol Definitions - * - * This module defines constants and data structures provided by the USB - * 2.0 specification. - * - * @{ - */ - -//! Value for field bcdUSB -#define USB_V2_0 0x0200 //!< USB Specification version 2.00 -#define USB_V2_1 0x0201 //!< USB Specification version 2.01 - -/*! \name Generic definitions (Class, subclass and protocol) - */ -//! @{ -#define NO_CLASS 0x00 -#define CLASS_VENDOR_SPECIFIC 0xFF -#define NO_SUBCLASS 0x00 -#define NO_PROTOCOL 0x00 -//! @} - -//! \name IAD (Interface Association Descriptor) constants -//! @{ -#define CLASS_IAD 0xEF -#define SUB_CLASS_IAD 0x02 -#define PROTOCOL_IAD 0x01 -//! @} - -/** - * \brief USB request data transfer direction (bmRequestType) - */ -#define USB_REQ_DIR_OUT (0<<7) //!< Host to device -#define USB_REQ_DIR_IN (1<<7) //!< Device to host -#define USB_REQ_DIR_MASK (1<<7) //!< Mask - -/** - * \brief USB request types (bmRequestType) - */ -#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request -#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request -#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request -#define USB_REQ_TYPE_MASK (3<<5) //!< Mask - -/** - * \brief USB recipient codes (bmRequestType) - */ -#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device -#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface -#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint -#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other -#define USB_REQ_RECIP_MASK (0x1F) //!< Mask - -/** - * \brief Standard USB requests (bRequest) - */ -enum usb_reqid { - USB_REQ_GET_STATUS = 0, - USB_REQ_CLEAR_FEATURE = 1, - USB_REQ_SET_FEATURE = 3, - USB_REQ_SET_ADDRESS = 5, - USB_REQ_GET_DESCRIPTOR = 6, - USB_REQ_SET_DESCRIPTOR = 7, - USB_REQ_GET_CONFIGURATION = 8, - USB_REQ_SET_CONFIGURATION = 9, - USB_REQ_GET_INTERFACE = 10, - USB_REQ_SET_INTERFACE = 11, - USB_REQ_SYNCH_FRAME = 12, -}; - -/** - * \brief Standard USB device status flags - * - */ -enum usb_device_status { - USB_DEV_STATUS_BUS_POWERED = 0, - USB_DEV_STATUS_SELF_POWERED = 1, - USB_DEV_STATUS_REMOTEWAKEUP = 2 -}; - -/** - * \brief Standard USB Interface status flags - * - */ -enum usb_interface_status { - USB_IFACE_STATUS_RESERVED = 0 -}; - -/** - * \brief Standard USB endpoint status flags - * - */ -enum usb_endpoint_status { - USB_EP_STATUS_HALTED = 1, -}; - -/** - * \brief Standard USB device feature flags - * - * \note valid for SetFeature request. - */ -enum usb_device_feature { - USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled - USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode - USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, - USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, - USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 -}; - -/** - * \brief Test Mode possible on HS USB device - * - * \note valid for USB_DEV_FEATURE_TEST_MODE request. - */ -enum usb_device_hs_test_mode { - USB_DEV_TEST_MODE_J = 1, - USB_DEV_TEST_MODE_K = 2, - USB_DEV_TEST_MODE_SE0_NAK = 3, - USB_DEV_TEST_MODE_PACKET = 4, - USB_DEV_TEST_MODE_FORCE_ENABLE = 5, -}; - -/** - * \brief Standard USB endpoint feature/status flags - */ -enum usb_endpoint_feature { - USB_EP_FEATURE_HALT = 0, -}; - -/** - * \brief Standard USB Test Mode Selectors - */ -enum usb_test_mode_selector { - USB_TEST_J = 0x01, - USB_TEST_K = 0x02, - USB_TEST_SE0_NAK = 0x03, - USB_TEST_PACKET = 0x04, - USB_TEST_FORCE_ENABLE = 0x05, -}; - -/** - * \brief Standard USB descriptor types - */ -enum usb_descriptor_type { - USB_DT_DEVICE = 1, - USB_DT_CONFIGURATION = 2, - USB_DT_STRING = 3, - USB_DT_INTERFACE = 4, - USB_DT_ENDPOINT = 5, - USB_DT_DEVICE_QUALIFIER = 6, - USB_DT_OTHER_SPEED_CONFIGURATION = 7, - USB_DT_INTERFACE_POWER = 8, - USB_DT_OTG = 9, - USB_DT_IAD = 0x0B, - USB_DT_BOS = 0x0F, - USB_DT_DEVICE_CAPABILITY = 0x10, -}; - -/** - * \brief USB Device Capability types - */ -enum usb_capability_type { - USB_DC_USB20_EXTENSION = 0x02, -}; - -/** - * \brief USB Device Capability - USB 2.0 Extension - * To fill bmAttributes field of usb_capa_ext_desc_t structure. - */ -enum usb_capability_extension_attr { - USB_DC_EXT_LPM = 0x00000002, -}; - -#define HIRD_50_US 0 -#define HIRD_125_US 1 -#define HIRD_200_US 2 -#define HIRD_275_US 3 -#define HIRD_350_US 4 -#define HIRD_425_US 5 -#define HIRD_500_US 6 -#define HIRD_575_US 7 -#define HIRD_650_US 8 -#define HIRD_725_US 9 -#define HIRD_800_US 10 -#define HIRD_875_US 11 -#define HIRD_950_US 12 -#define HIRD_1025_US 13 -#define HIRD_1100_US 14 -#define HIRD_1175_US 15 - -/** Fields definition from a LPM TOKEN */ -#define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0) -#define USB_LPM_ATTRIBUT_FIRD_MASK (0xF << 4) -#define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8) -#define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0) -#define USB_LPM_ATTRIBUT_FIRD(value) ((value & 0xF) << 4) -#define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8) -#define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1) - -/** - * \brief Standard USB endpoint transfer types - */ -enum usb_ep_type { - USB_EP_TYPE_CONTROL = 0x00, - USB_EP_TYPE_ISOCHRONOUS = 0x01, - USB_EP_TYPE_BULK = 0x02, - USB_EP_TYPE_INTERRUPT = 0x03, - USB_EP_TYPE_MASK = 0x03, -}; - -/** - * \brief Standard USB language IDs for string descriptors - */ -enum usb_langid { - USB_LANGID_EN_US = 0x0409, //!< English (United States) -}; - -/** - * \brief Mask selecting the index part of an endpoint address - */ -#define USB_EP_ADDR_MASK 0x0F - -//! \brief USB address identifier -typedef uint8_t usb_add_t; - -/** - * \brief Endpoint transfer direction is IN - */ -#define USB_EP_DIR_IN 0x80 - -/** - * \brief Endpoint transfer direction is OUT - */ -#define USB_EP_DIR_OUT 0x00 - -//! \brief Endpoint identifier -typedef uint8_t usb_ep_t; - -/** - * \brief Maximum length in bytes of a USB descriptor - * - * The maximum length of a USB descriptor is limited by the 8-bit - * bLength field. - */ -#define USB_MAX_DESC_LEN 255 - -/* - * 2-byte alignment requested for all USB structures. - */ -COMPILER_PACK_SET(1) - -/** - * \brief A USB Device SETUP request - * - * The data payload of SETUP packets always follows this structure. - */ -typedef struct { - uint8_t bmRequestType; - uint8_t bRequest; - le16_t wValue; - le16_t wIndex; - le16_t wLength; -} usb_setup_req_t; - -/** - * \brief Standard USB device descriptor structure - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - le16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize0; - le16_t idVendor; - le16_t idProduct; - le16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} usb_dev_desc_t; - -/** - * \brief Standard USB device qualifier descriptor structure - * - * This descriptor contains information about the device when running at - * the "other" speed (i.e. if the device is currently operating at high - * speed, this descriptor can be used to determine what would change if - * the device was operating at full speed.) - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - le16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize0; - uint8_t bNumConfigurations; - uint8_t bReserved; -} usb_dev_qual_desc_t; - -/** - * \brief USB Device BOS descriptor structure - * - * The BOS descriptor (Binary device Object Store) defines a root - * descriptor that is similar to the configuration descriptor, and is - * the base descriptor for accessing a family of related descriptors. - * A host can read a BOS descriptor and learn from the wTotalLength field - * the entire size of the device-level descriptor set, or it can read in - * the entire BOS descriptor set of device capabilities. - * The host accesses this descriptor using the GetDescriptor() request. - * The descriptor type in the GetDescriptor() request is set to BOS. - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - le16_t wTotalLength; - uint8_t bNumDeviceCaps; -} usb_dev_bos_desc_t; - - -/** - * \brief USB Device Capabilities - USB 2.0 Extension Descriptor structure - * - * Defines the set of USB 1.1-specific device level capabilities. - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; - le32_t bmAttributes; -} usb_dev_capa_ext_desc_t; - -/** - * \brief USB Device LPM Descriptor structure - * - * The BOS descriptor and capabilities descriptors for LPM. - */ -typedef struct { - usb_dev_bos_desc_t bos; - usb_dev_capa_ext_desc_t capa_ext; -} usb_dev_lpm_desc_t; - -/** - * \brief Standard USB Interface Association Descriptor structure - */ -typedef struct { - uint8_t bLength; //!< size of this descriptor in bytes - uint8_t bDescriptorType; //!< INTERFACE descriptor type - uint8_t bFirstInterface; //!< Number of interface - uint8_t bInterfaceCount; //!< value to select alternate setting - uint8_t bFunctionClass; //!< Class code assigned by the USB - uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB - uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB - uint8_t iFunction; //!< Index of string descriptor -} usb_association_desc_t; - - -/** - * \brief Standard USB configuration descriptor structure - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - le16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t bMaxPower; -} usb_conf_desc_t; - - -#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set -#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered -#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered -#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported - -#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA - -/** - * \brief Standard USB association descriptor structure - */ -typedef struct { - uint8_t bLength; //!< Size of this descriptor in bytes - uint8_t bDescriptorType; //!< Interface descriptor type - uint8_t bFirstInterface; //!< Number of interface - uint8_t bInterfaceCount; //!< value to select alternate setting - uint8_t bFunctionClass; //!< Class code assigned by the USB - uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB - uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB - uint8_t iFunction; //!< Index of string descriptor -} usb_iad_desc_t; - -/** - * \brief Standard USB interface descriptor structure - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; -} usb_iface_desc_t; - -/** - * \brief Standard USB endpoint descriptor structure - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - le16_t wMaxPacketSize; - uint8_t bInterval; -} usb_ep_desc_t; - - -/** - * \brief A standard USB string descriptor structure - */ -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; -} usb_str_desc_t; - -typedef struct { - usb_str_desc_t desc; - le16_t string[1]; -} usb_str_lgid_desc_t; - -COMPILER_PACK_RESET() - -//! @} - -#endif /* _USB_PROTOCOL_H_ */ diff --git a/src/HAL/DUE/usb/usb_protocol_cdc.h b/src/HAL/DUE/usb/usb_protocol_cdc.h deleted file mode 100644 index d594db5..0000000 --- a/src/HAL/DUE/usb/usb_protocol_cdc.h +++ /dev/null @@ -1,320 +0,0 @@ -/** - * \file - * - * \brief USB Communication Device Class (CDC) protocol definitions - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ -#ifndef _USB_PROTOCOL_CDC_H_ -#define _USB_PROTOCOL_CDC_H_ - -#include "compiler.h" - -/** - * \ingroup usb_protocol_group - * \defgroup cdc_protocol_group Communication Device Class Definitions - * @{ - */ - -/** - * \name Possible values of class - */ -//@{ -#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class -#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface -#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface -#define CDC_CLASS_MULTI 0xEF //!< CDC Multi-interface Function - -//@} - -//! \name USB CDC Subclass IDs -//@{ -#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model -#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model -#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model -#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model -#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model -#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model -#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model -//@} - -//! \name USB CDC Communication Interface Protocol IDs -//@{ -#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands -//@} - -//! \name USB CDC Data Interface Protocol IDs -//@{ -#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI -#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC -#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent -#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol -#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol -#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor -#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures -#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control -#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN -#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands -#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver -/** - * \brief Describes the Protocol Unit Functional Descriptors [sic] - * on Communication Class Interface - */ -#define CDC_PROTOCOL_PUFD 0xFE -//@} - -//! \name USB CDC Functional Descriptor Types -//@{ -#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor -#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor -//@} - -//! \name USB CDC Functional Descriptor Subtypes -//@{ -#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor -#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management -#define CDC_SCS_ACM 0x02 //!< Abstract Control Management -#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor -//@} - -//! \name USB CDC Request IDs -//@{ -#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00 -#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01 -#define USB_REQ_CDC_SET_COMM_FEATURE 0x02 -#define USB_REQ_CDC_GET_COMM_FEATURE 0x03 -#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04 -#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10 -#define USB_REQ_CDC_SET_HOOK_STATE 0x11 -#define USB_REQ_CDC_PULSE_SETUP 0x12 -#define USB_REQ_CDC_SEND_PULSE 0x13 -#define USB_REQ_CDC_SET_PULSE_TIME 0x14 -#define USB_REQ_CDC_RING_AUX_JACK 0x15 -#define USB_REQ_CDC_SET_LINE_CODING 0x20 -#define USB_REQ_CDC_GET_LINE_CODING 0x21 -#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22 -#define USB_REQ_CDC_SEND_BREAK 0x23 -#define USB_REQ_CDC_SET_RINGER_PARMS 0x30 -#define USB_REQ_CDC_GET_RINGER_PARMS 0x31 -#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32 -#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33 -#define USB_REQ_CDC_SET_LINE_PARMS 0x34 -#define USB_REQ_CDC_GET_LINE_PARMS 0x35 -#define USB_REQ_CDC_DIAL_DIGITS 0x36 -#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37 -#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38 -#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39 -#define USB_REQ_CDC_GET_PROFILE 0x3A -#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 -#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41 -#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42 -#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43 -#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44 -#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50 -#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51 -#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52 -#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53 -// Added bNotification codes according cdc spec 1.1 chapter 6.3 -#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09 -#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20 -#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28 -#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29 -//@} - -/* - * Need to pack structures tightly, or the compiler might insert padding - * and violate the spec-mandated layout. - */ -COMPILER_PACK_SET(1) - -//! \name USB CDC Descriptors -//@{ - - -//! CDC Header Functional Descriptor -typedef struct { - uint8_t bFunctionLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubtype; - le16_t bcdCDC; -} usb_cdc_hdr_desc_t; - -//! CDC Call Management Functional Descriptor -typedef struct { - uint8_t bFunctionLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubtype; - uint8_t bmCapabilities; - uint8_t bDataInterface; -} usb_cdc_call_mgmt_desc_t; - -//! CDC ACM Functional Descriptor -typedef struct { - uint8_t bFunctionLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubtype; - uint8_t bmCapabilities; -} usb_cdc_acm_desc_t; - -//! CDC Union Functional Descriptor -typedef struct { - uint8_t bFunctionLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubtype; - uint8_t bMasterInterface; - uint8_t bSlaveInterface0; -} usb_cdc_union_desc_t; - - -//! \name USB CDC Call Management Capabilities -//@{ -//! Device handles call management itself -#define CDC_CALL_MGMT_SUPPORTED (1 << 0) -//! Device can send/receive call management info over a Data Class interface -#define CDC_CALL_MGMT_OVER_DCI (1 << 1) -//@} - -//! \name USB CDC ACM Capabilities -//@{ -//! Device supports the request combination of -//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. -#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0) -//! Device supports the request combination of -//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, -//! and the notification Serial_State. -#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1) -//! Device supports the request Send_Break -#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2) -//! Device supports the notification Network_Connection. -#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3) -//@} -//@} - -//! \name USB CDC line control -//@{ - -//! \name USB CDC line coding -//@{ -//! Line Coding structure -typedef struct { - le32_t dwDTERate; - uint8_t bCharFormat; - uint8_t bParityType; - uint8_t bDataBits; -} usb_cdc_line_coding_t; -//! Possible values of bCharFormat -enum cdc_char_format { - CDC_STOP_BITS_1 = 0, //!< 1 stop bit - CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits - CDC_STOP_BITS_2 = 2, //!< 2 stop bits -}; -//! Possible values of bParityType -enum cdc_parity { - CDC_PAR_NONE = 0, //!< No parity - CDC_PAR_ODD = 1, //!< Odd parity - CDC_PAR_EVEN = 2, //!< Even parity - CDC_PAR_MARK = 3, //!< Parity forced to 0 (space) - CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark) -}; -//@} - -//! \name USB CDC control signals -//! spec 1.1 chapter 6.2.14 -//@{ - -//! Control signal structure -typedef struct { - uint16_t value; -} usb_cdc_control_signal_t; - -//! \name Possible values in usb_cdc_control_signal_t -//@{ -//! Carrier control for half duplex modems. -//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS. -//! The device ignores the value of this bit -//! when operating in full duplex mode. -#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1) -//! Indicates to DCE if DTE is present or not. -//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. -#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0) -//@} -//@} - - -//! \name USB CDC notification message -//@{ - -typedef struct { - uint8_t bmRequestType; - uint8_t bNotification; - le16_t wValue; - le16_t wIndex; - le16_t wLength; -} usb_cdc_notify_msg_t; - -//! \name USB CDC serial state -//@{* - -//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5) -typedef struct { - usb_cdc_notify_msg_t header; - le16_t value; -} usb_cdc_notify_serial_state_t; - -//! \name Possible values in usb_cdc_notify_serial_state_t -//@{ -#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0)) -#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1)) -#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2)) -#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3)) -#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4)) -#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5)) -#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6)) -//@} -//! @} - -//! @} - -COMPILER_PACK_RESET() - -//! @} - -#endif // _USB_PROTOCOL_CDC_H_ diff --git a/src/HAL/DUE/usb/usb_protocol_msc.h b/src/HAL/DUE/usb/usb_protocol_msc.h deleted file mode 100644 index e1e5923..0000000 --- a/src/HAL/DUE/usb/usb_protocol_msc.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * \file - * - * \brief USB Mass Storage Class (MSC) protocol definitions. - * - * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _USB_PROTOCOL_MSC_H_ -#define _USB_PROTOCOL_MSC_H_ - - -/** - * \ingroup usb_protocol_group - * \defgroup usb_msc_protocol USB Mass Storage Class (MSC) protocol definitions - * - * @{ - */ - -/** - * \name Possible Class value - */ -//@{ -#define MSC_CLASS 0x08 -//@} - -/** - * \name Possible SubClass value - * \note In practise, most devices should use - * #MSC_SUBCLASS_TRANSPARENT and specify the actual command set in - * the standard INQUIRY data block, even if the MSC spec indicates - * otherwise. In particular, RBC is not supported by certain major - * operating systems like Windows XP. - */ -//@{ -#define MSC_SUBCLASS_RBC 0x01 //!< Reduced Block Commands -#define MSC_SUBCLASS_ATAPI 0x02 //!< CD/DVD devices -#define MSC_SUBCLASS_QIC_157 0x03 //!< Tape devices -#define MSC_SUBCLASS_UFI 0x04 //!< Floppy disk drives -#define MSC_SUBCLASS_SFF_8070I 0x05 //!< Floppy disk drives -#define MSC_SUBCLASS_TRANSPARENT 0x06 //!< Determined by INQUIRY -//@} - -/** - * \name Possible protocol value - * \note Only the BULK protocol should be used in new designs. - */ -//@{ -#define MSC_PROTOCOL_CBI 0x00 //!< Command/Bulk/Interrupt -#define MSC_PROTOCOL_CBI_ALT 0x01 //!< W/o command completion -#define MSC_PROTOCOL_BULK 0x50 //!< Bulk-only -//@} - - -/** - * \brief MSC USB requests (bRequest) - */ -enum usb_reqid_msc { - USB_REQ_MSC_BULK_RESET = 0xFF, //!< Mass Storage Reset - USB_REQ_MSC_GET_MAX_LUN = 0xFE //!< Get Max LUN -}; - - -COMPILER_PACK_SET(1) - -/** - * \name A Command Block Wrapper (CBW). - */ -//@{ -struct usb_msc_cbw { - le32_t dCBWSignature; //!< Must contain 'USBC' - le32_t dCBWTag; //!< Unique command ID - le32_t dCBWDataTransferLength; //!< Number of bytes to transfer - uint8_t bmCBWFlags; //!< Direction in bit 7 - uint8_t bCBWLUN; //!< Logical Unit Number - uint8_t bCBWCBLength; //!< Number of valid CDB bytes - uint8_t CDB[16]; //!< SCSI Command Descriptor Block -}; - -#define USB_CBW_SIGNATURE 0x55534243 //!< dCBWSignature value -#define USB_CBW_DIRECTION_IN (1<<7) //!< Data from device to host -#define USB_CBW_DIRECTION_OUT (0<<7) //!< Data from host to device -#define USB_CBW_LUN_MASK 0x0F //!< Valid bits in bCBWLUN -#define USB_CBW_LEN_MASK 0x1F //!< Valid bits in bCBWCBLength -//@} - - -/** - * \name A Command Status Wrapper (CSW). - */ -//@{ -struct usb_msc_csw { - le32_t dCSWSignature; //!< Must contain 'USBS' - le32_t dCSWTag; //!< Same as dCBWTag - le32_t dCSWDataResidue; //!< Number of bytes not transferred - uint8_t bCSWStatus; //!< Status code -}; - -#define USB_CSW_SIGNATURE 0x55534253 //!< dCSWSignature value -#define USB_CSW_STATUS_PASS 0x00 //!< Command Passed -#define USB_CSW_STATUS_FAIL 0x01 //!< Command Failed -#define USB_CSW_STATUS_PE 0x02 //!< Phase Error -//@} - -COMPILER_PACK_RESET() - -//@} - -#endif // _USB_PROTOCOL_MSC_H_ diff --git a/src/HAL/DUE/usb/usb_task.c b/src/HAL/DUE/usb/usb_task.c deleted file mode 100644 index 54a808d..0000000 --- a/src/HAL/DUE/usb/usb_task.c +++ /dev/null @@ -1,341 +0,0 @@ -/** - * \file - * - * \brief Main functions for USB composite example - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -// Support and FAQ: visit Atmel Support - -#ifdef ARDUINO_ARCH_SAM - -#include -#include - -#include "conf_usb.h" -#include "udc.h" - -#if ENABLED(SDSUPPORT) - static volatile bool main_b_msc_enable = false; -#endif -static volatile bool main_b_cdc_enable = false; -static volatile bool main_b_dtr_active = false; - -void usb_task_idle(void) { - #if ENABLED(SDSUPPORT) - // Attend SD card access from the USB MSD -- Prioritize access to improve speed - int delay = 2; - while (main_b_msc_enable && --delay > 0) { - if (udi_msc_process_trans()) delay = 10000; - - // Reset the watchdog, just to be sure - REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5); - } - #endif -} - -#if ENABLED(SDSUPPORT) - bool usb_task_msc_enable(void) { return ((main_b_msc_enable = true)); } - void usb_task_msc_disable(void) { main_b_msc_enable = false; } - bool usb_task_msc_isenabled(void) { return main_b_msc_enable; } -#endif - -bool usb_task_cdc_enable(const uint8_t port) { UNUSED(port); return ((main_b_cdc_enable = true)); } -void usb_task_cdc_disable(const uint8_t port) { UNUSED(port); main_b_cdc_enable = false; main_b_dtr_active = false; } -bool usb_task_cdc_isenabled(void) { return main_b_cdc_enable; } - -/*! \brief Called by CDC interface - * Callback running when CDC device have received data - */ -void usb_task_cdc_rx_notify(const uint8_t port) { UNUSED(port); } - -/*! \brief Configures communication line - * - * \param cfg line configuration - */ -static uint16_t dwDTERate = 0; -void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg) { - UNUSED(port); - // Store last DTE rate - dwDTERate = cfg->dwDTERate; -} - -void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable) { - UNUSED(port); - // Keep DTR status - main_b_dtr_active = b_enable; - - // Implement Arduino-Compatible kludge to enter programming mode from - // the native port: - // "Auto-reset into the bootloader is triggered when the port, already - // open at 1200 bps, is closed." - - if (1200 == dwDTERate) { - // We check DTR state to determine if host port is open (bit 0 of lineState). - if (!b_enable) { - - // Set RST pin to go low for 65535 clock cycles on reset - // This helps restarting when firmware flash ends - RSTC->RSTC_MR = 0xA5000F01; - - // Schedule delayed reset - initiateReset(250); - } - else - cancelReset(); - } -} - -bool usb_task_cdc_dtr_active(void) { return main_b_dtr_active; } - -/// Microsoft WCID descriptor -typedef struct USB_MicrosoftCompatibleDescriptor_Interface { - uint8_t bFirstInterfaceNumber; - uint8_t reserved1; - uint8_t compatibleID[8]; - uint8_t subCompatibleID[8]; - uint8_t reserved2[6]; -} __attribute__((packed)) USB_MicrosoftCompatibleDescriptor_Interface; - -typedef struct USB_MicrosoftCompatibleDescriptor { - uint32_t dwLength; - uint16_t bcdVersion; - uint16_t wIndex; - uint8_t bCount; - uint8_t reserved[7]; - USB_MicrosoftCompatibleDescriptor_Interface interfaces[]; -} __attribute__((packed)) USB_MicrosoftCompatibleDescriptor; - -// 3D Printer compatible descriptor -static USB_MicrosoftCompatibleDescriptor microsoft_compatible_id_descriptor = { - .dwLength = sizeof(USB_MicrosoftCompatibleDescriptor) + - 1*sizeof(USB_MicrosoftCompatibleDescriptor_Interface), - .bcdVersion = 0x0100, - .wIndex = 0x0004, - .bCount = 1, - .reserved = {0, 0, 0, 0, 0, 0, 0}, - .interfaces = { - { - .bFirstInterfaceNumber = 0, - .reserved1 = 1, - .compatibleID = "3DPRINT", - .subCompatibleID = {0, 0, 0, 0, 0, 0, 0, 0}, - .reserved2 = {0, 0, 0, 0, 0, 0}, - } - } -}; - -#define xstr(s) str(s) -#define str(s) #s - -#define MS3DPRINT_CONFIG u"MS3DPrintConfig" -#define MS3DPRINT_CONFIG_DATA \ - u"Base=SD\0"\ - u"Job3DOutputAreaWidth=" xstr(X_BED_SIZE) "000\0"\ - u"Job3DOutputAreaDepth=" xstr(Y_BED_SIZE) "000\0"\ - u"Job3DOutputAreaHeight=" xstr(Z_MAX_POS) "000\0"\ - u"filamentdiameter=1750\0" - -typedef struct USB_MicrosoftExtendedPropertiesDescriptor { - uint32_t dwLength; - uint16_t bcdVersion; - uint16_t wIndex; - uint16_t bCount; - uint32_t dwPropertySize; - uint32_t dwPropertyDataType; - uint16_t wPropertyNameLength; - uint16_t PropertyName[sizeof(MS3DPRINT_CONFIG)/sizeof(uint16_t)]; - uint32_t dwPropertyDataLength; - uint16_t PropertyData[sizeof(MS3DPRINT_CONFIG_DATA)/sizeof(uint16_t)]; -} __attribute__((packed)) USB_MicrosoftExtendedPropertiesDescriptor; - -static USB_MicrosoftExtendedPropertiesDescriptor microsoft_extended_properties_descriptor = { - .dwLength = sizeof(USB_MicrosoftExtendedPropertiesDescriptor), - .bcdVersion = 0x0100, - .wIndex = 0x0005, - .bCount = 1, - - .dwPropertySize = 4 + 4 + 2 + 4 + sizeof(MS3DPRINT_CONFIG) + sizeof(MS3DPRINT_CONFIG_DATA), - .dwPropertyDataType = 7, // (1=REG_SZ, 4=REG_DWORD, 7=REG_MULTI_SZ) - .wPropertyNameLength = sizeof(MS3DPRINT_CONFIG), - .PropertyName = MS3DPRINT_CONFIG, - .dwPropertyDataLength = sizeof(MS3DPRINT_CONFIG_DATA), - .PropertyData = MS3DPRINT_CONFIG_DATA -}; - -/************************************************************************************************** -** WCID configuration information -** Hooked into UDC via UDC_GET_EXTRA_STRING #define. -*/ -bool usb_task_extra_string(void) { - static uint8_t udi_msft_magic[] = "MSFT100\xEE"; - static uint8_t udi_cdc_name[] = "CDC interface"; - #if ENABLED(SDSUPPORT) - static uint8_t udi_msc_name[] = "MSC interface"; - #endif - - struct extra_strings_desc_t { - usb_str_desc_t header; - #if ENABLED(SDSUPPORT) - le16_t string[Max(Max(sizeof(udi_cdc_name) - 1, sizeof(udi_msc_name) - 1), sizeof(udi_msft_magic) - 1)]; - #else - le16_t string[Max(sizeof(udi_cdc_name) - 1, sizeof(udi_msft_magic) - 1)]; - #endif - }; - static UDC_DESC_STORAGE struct extra_strings_desc_t extra_strings_desc = { - .header.bDescriptorType = USB_DT_STRING - }; - - uint8_t *str; - uint8_t str_lgt = 0; - - // Link payload pointer to the string corresponding at request - switch (udd_g_ctrlreq.req.wValue & 0xFF) { - case UDI_CDC_IAD_STRING_ID: - str_lgt = sizeof(udi_cdc_name) - 1; - str = udi_cdc_name; - break; - #if ENABLED(SDSUPPORT) - case UDI_MSC_STRING_ID: - str_lgt = sizeof(udi_msc_name) - 1; - str = udi_msc_name; - break; - #endif - case 0xEE: - str_lgt = sizeof(udi_msft_magic) - 1; - str = udi_msft_magic; - break; - default: - return false; - } - - for (uint8_t i = 0; i < str_lgt; i++) - extra_strings_desc.string[i] = cpu_to_le16((le16_t)str[i]); - - extra_strings_desc.header.bLength = 2 + str_lgt * 2; - udd_g_ctrlreq.payload_size = extra_strings_desc.header.bLength; - udd_g_ctrlreq.payload = (uint8_t*)&extra_strings_desc; - - // if the string is larger than request length, then cut it - if (udd_g_ctrlreq.payload_size > udd_g_ctrlreq.req.wLength) { - udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; - } - - return true; -} - -/************************************************************************************************** -** Handle device requests that the ASF stack doesn't -*/ -bool usb_task_other_requests(void) { - uint8_t *ptr = 0; - uint16_t size = 0; - - if (Udd_setup_type() == USB_REQ_TYPE_VENDOR) { - //if (udd_g_ctrlreq.req.bRequest == 0x30) - if (1) { - if (udd_g_ctrlreq.req.wIndex == 0x04) { - ptr = (uint8_t*)µsoft_compatible_id_descriptor; - size = (udd_g_ctrlreq.req.wLength); - if (size > microsoft_compatible_id_descriptor.dwLength) - size = microsoft_compatible_id_descriptor.dwLength; - } - else if (udd_g_ctrlreq.req.wIndex == 0x05) { - ptr = (uint8_t*)µsoft_extended_properties_descriptor; - size = (udd_g_ctrlreq.req.wLength); - if (size > microsoft_extended_properties_descriptor.dwLength) - size = microsoft_extended_properties_descriptor.dwLength; - } - else - return false; - } - } - - udd_g_ctrlreq.payload_size = size; - if (size == 0) { - udd_g_ctrlreq.callback = 0; - udd_g_ctrlreq.over_under_run = 0; - } - else - udd_g_ctrlreq.payload = ptr; - - return true; -} - -void usb_task_init(void) { - - uint16_t *ptr; - - // Disable USB peripheral so we start clean and avoid lockups - otg_disable(); - udd_disable(); - - // Set the USB interrupt to our stack - UDD_SetStack(&USBD_ISR); - - // Start USB stack to authorize VBus monitoring - udc_start(); - - // Patch in filament diameter - Be careful: String is in UNICODE (2bytes per char) - ptr = µsoft_extended_properties_descriptor.PropertyData[0]; - while (ptr[0] || ptr[1]) { // Double 0 flags end of resource - - // Found the filamentdiameter= unicode string - if (ptr[0] == 'r' && ptr[1] == '=') { - char diam[16]; - char *sptr; - - // Patch in the filament diameter - itoa((int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000), diam, 10); - - // And copy it to the proper place, expanding it to unicode - sptr = &diam[0]; - ptr += 2; - while (*sptr) *ptr++ = *sptr++; - - // Done! - break; - } - - // Go to the next character - ptr++; - } -} - -#endif // ARDUINO_ARCH_SAM diff --git a/src/HAL/DUE/usb/usb_task.h b/src/HAL/DUE/usb/usb_task.h deleted file mode 100644 index e9831ae..0000000 --- a/src/HAL/DUE/usb/usb_task.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * \file - * - * \brief Declaration of main function used by Composite example 4 - * - * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit Atmel Support - */ - -#ifndef _USB_TASK_H_ -#define _USB_TASK_H_ - -#include "usb_protocol_cdc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \brief Called by MSC interface - * Callback running when USB Host enable MSC interface - * - * \retval true if MSC startup is ok - */ -bool usb_task_msc_enable(void); - -/*! \brief Called by MSC interface - * Callback running when USB Host disable MSC interface - */ -void usb_task_msc_disable(void); - -/*! \brief Opens the communication port - * This is called by CDC interface when USB Host enable it. - * - * \retval true if cdc startup is successfully done - */ -bool usb_task_cdc_enable(const uint8_t port); - -/*! \brief Closes the communication port - * This is called by CDC interface when USB Host disable it. - */ -void usb_task_cdc_disable(const uint8_t port); - -/*! \brief Save new DTR state to change led behavior. - * The DTR notify that the terminal have open or close the communication port. - */ -void usb_task_cdc_set_dtr(const uint8_t port, const bool b_enable); - -/*! \brief Check if MSC is enumerated and configured on the PC side - */ -bool usb_task_msc_isenabled(void); - -/*! \brief Check if CDC is enumerated and configured on the PC side - */ -bool usb_task_cdc_isenabled(void); - -/*! \brief Check if CDC is actually OPEN by an application on the PC side - * assuming DTR signal means a program is listening to messages - */ -bool usb_task_cdc_dtr_active(void); - -/*! \brief Called by UDC when USB Host request a extra string different - * of this specified in USB device descriptor - */ -bool usb_task_extra_string(void); - -/*! \brief Called by UDC when USB Host performs unknown requests - */ -bool usb_task_other_requests(void); - -/*! \brief Called by CDC interface - * Callback running when CDC device have received data - */ -void usb_task_cdc_rx_notify(const uint8_t port); - -/*! \brief Configures communication line - * - * \param cfg line configuration - */ -void usb_task_cdc_config(const uint8_t port, usb_cdc_line_coding_t *cfg); - -/*! \brief The USB device interrupt - */ -void USBD_ISR(void); - -/*! \brief USB task init - */ -void usb_task_init(void); - -/*! \brief USB task idle - */ -void usb_task_idle(void); - -#ifdef __cplusplus -} -#endif - -#endif // _USB_TASK_H_ diff --git a/src/HAL/ESP32/FlushableHardwareSerial.cpp b/src/HAL/ESP32/FlushableHardwareSerial.cpp deleted file mode 100644 index 1456622..0000000 --- a/src/HAL/ESP32/FlushableHardwareSerial.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef ARDUINO_ARCH_ESP32 - -#include "FlushableHardwareSerial.h" - -Serial1Class flushableSerial(false, 0); - -#endif diff --git a/src/HAL/ESP32/FlushableHardwareSerial.h b/src/HAL/ESP32/FlushableHardwareSerial.h deleted file mode 100644 index 012dda8..0000000 --- a/src/HAL/ESP32/FlushableHardwareSerial.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -#include "../shared/Marduino.h" -#include "../../core/serial_hook.h" - -class FlushableHardwareSerial : public HardwareSerial { -public: - FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {} -}; - -extern Serial1Class flushableSerial; diff --git a/src/HAL/ESP32/HAL.cpp b/src/HAL/ESP32/HAL.cpp deleted file mode 100644 index 29f3be3..0000000 --- a/src/HAL/ESP32/HAL.cpp +++ /dev/null @@ -1,429 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" - -#include -#include -#include -#include - -#if ENABLED(USE_ESP32_TASK_WDT) - #include -#endif - -#if ENABLED(WIFISUPPORT) - #include - #include "wifi.h" - #if ENABLED(OTASUPPORT) - #include "ota.h" - #endif - #if ENABLED(WEBSUPPORT) - #include "spiffs.h" - #include "web.h" - #endif -#endif - -#if ENABLED(ESP3D_WIFISUPPORT) - DefaultSerial1 MSerial0(false, Serial2Socket); -#endif - -// ------------------------ -// Externs -// ------------------------ - -portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED; - -// ------------------------ -// Local defines -// ------------------------ - -#define V_REF 1100 - -// ------------------------ -// Public Variables -// ------------------------ - -uint16_t MarlinHAL::adc_result; -pwm_pin_t MarlinHAL::pwm_pin_data[MAX_EXPANDER_BITS]; - -// ------------------------ -// Private Variables -// ------------------------ - -esp_adc_cal_characteristics_t characteristics[ADC_ATTEN_MAX]; -adc_atten_t attenuations[ADC1_CHANNEL_MAX] = {}; -uint32_t thresholds[ADC_ATTEN_MAX]; - -volatile int numPWMUsed = 0; -volatile struct { pin_t pin; int value; } pwmState[MAX_PWM_PINS]; - -pin_t chan_pin[CHANNEL_MAX_NUM + 1] = { 0 }; // PWM capable IOpins - not 0 or >33 on ESP32 - -struct { - uint32_t freq; // ledcReadFreq doesn't work if a duty hasn't been set yet! - uint16_t res; -} pwmInfo[(CHANNEL_MAX_NUM + 1) / 2]; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(WIFI_CUSTOM_COMMAND) - - bool wifi_custom_command(char * const command_ptr) { - #if ENABLED(ESP3D_WIFISUPPORT) - return esp3dlib.parse(command_ptr); - #else - UNUSED(command_ptr); - return false; - #endif - } - -#endif - -#if ENABLED(USE_ESP32_EXIO) - - HardwareSerial YSerial2(2); - - void Write_EXIO(uint8_t IO, uint8_t v) { - if (hal.isr_state()) { - hal.isr_off(); - YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100)); - hal.isr_on(); - } - else - YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100)); - } - -#endif - -void MarlinHAL::init_board() { - #if ENABLED(USE_ESP32_TASK_WDT) - esp_task_wdt_init(10, true); - #endif - #if ENABLED(ESP3D_WIFISUPPORT) - esp3dlib.init(); - #elif ENABLED(WIFISUPPORT) - wifi_init(); - TERN_(OTASUPPORT, OTA_init()); - #if ENABLED(WEBSUPPORT) - spiffs_init(); - web_init(); - #endif - server.begin(); - #endif - - // ESP32 uses a GPIO matrix that allows pins to be assigned to hardware serial ports. - // The following code initializes hardware Serial1 and Serial2 to use user-defined pins - // if they have been defined. - #if defined(HARDWARE_SERIAL1_RX) && defined(HARDWARE_SERIAL1_TX) - HardwareSerial Serial1(1); - #ifdef TMC_BAUD_RATE // use TMC_BAUD_RATE for Serial1 if defined - Serial1.begin(TMC_BAUD_RATE, SERIAL_8N1, HARDWARE_SERIAL1_RX, HARDWARE_SERIAL1_TX); - #else // use default BAUDRATE if TMC_BAUD_RATE not defined - Serial1.begin(BAUDRATE, SERIAL_8N1, HARDWARE_SERIAL1_RX, HARDWARE_SERIAL1_TX); - #endif - #endif - #if defined(HARDWARE_SERIAL2_RX) && defined(HARDWARE_SERIAL2_TX) - HardwareSerial Serial2(2); - #ifdef TMC_BAUD_RATE // use TMC_BAUD_RATE for Serial1 if defined - Serial2.begin(TMC_BAUD_RATE, SERIAL_8N1, HARDWARE_SERIAL2_RX, HARDWARE_SERIAL2_TX); - #else // use default BAUDRATE if TMC_BAUD_RATE not defined - Serial2.begin(BAUDRATE, SERIAL_8N1, HARDWARE_SERIAL2_RX, HARDWARE_SERIAL2_TX); - #endif - #endif - - // Initialize the i2s peripheral only if the I2S stepper stream is enabled. - // The following initialization is performed after Serial1 and Serial2 are defined as - // their native pins might conflict with the i2s stream even when they are remapped. - #if ENABLED(USE_ESP32_EXIO) - YSerial2.begin(460800 * 3, SERIAL_8N1, 16, 17); - #elif ENABLED(I2S_STEPPER_STREAM) - i2s_init(); - #endif -} - -void MarlinHAL::idletask() { - #if BOTH(WIFISUPPORT, OTASUPPORT) - OTA_handle(); - #endif - TERN_(ESP3D_WIFISUPPORT, esp3dlib.idletask()); -} - -uint8_t MarlinHAL::get_reset_source() { return rtc_get_reset_reason(1); } - -void MarlinHAL::reboot() { ESP.restart(); } - -void _delay_ms(int delay_ms) { delay(delay_ms); } - -// return free memory between end of heap (or end bss) and whatever is current -int MarlinHAL::freeMemory() { return ESP.getFreeHeap(); } - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout - - extern "C" { - esp_err_t esp_task_wdt_reset(); - } - - void watchdogSetup() { - // do whatever. don't remove this function. - } - - void MarlinHAL::watchdog_init() { - // TODO - } - - // Reset watchdog. - void MarlinHAL::watchdog_refresh() { esp_task_wdt_reset(); } - -#endif - -// ------------------------ -// ADC -// ------------------------ - -#define ADC1_CHANNEL(pin) ADC1_GPIO ## pin ## _CHANNEL - -adc1_channel_t get_channel(int pin) { - switch (pin) { - case 39: return ADC1_CHANNEL(39); - case 36: return ADC1_CHANNEL(36); - case 35: return ADC1_CHANNEL(35); - case 34: return ADC1_CHANNEL(34); - case 33: return ADC1_CHANNEL(33); - case 32: return ADC1_CHANNEL(32); - } - return ADC1_CHANNEL_MAX; -} - -void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) { - if (attenuations[chan] != atten) { - adc1_config_channel_atten(chan, atten); - attenuations[chan] = atten; - } -} - -void MarlinHAL::adc_init() { - // Configure ADC - adc1_config_width(ADC_WIDTH_12Bit); - - // Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects - TERN_(HAS_TEMP_ADC_0, adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_1, adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_2, adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_3, adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_4, adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_5, adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_6, adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db)); - TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_PROBE, adc1_set_attenuation(get_channel(TEMP_PROBE_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db)); - TERN_(HAS_TEMP_BOARD, adc1_set_attenuation(get_channel(TEMP_BOARD_PIN), ADC_ATTEN_11db)); - TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db)); - - // Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail. - // That's why we're not setting it up here. - - // Calculate ADC characteristics (i.e., gain and offset factors for each attenuation level) - for (int i = 0; i < ADC_ATTEN_MAX; i++) { - esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t)i, ADC_WIDTH_BIT_12, V_REF, &characteristics[i]); - - // Change attenuation 100mV below the calibrated threshold - thresholds[i] = esp_adc_cal_raw_to_voltage(4095, &characteristics[i]); - } -} - -#ifndef ADC_REFERENCE_VOLTAGE - #define ADC_REFERENCE_VOLTAGE 3.3 -#endif - -void MarlinHAL::adc_start(const pin_t pin) { - const adc1_channel_t chan = get_channel(pin); - uint32_t mv; - esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv); - - adc_result = mv * isr_float_t(1023) / isr_float_t(ADC_REFERENCE_VOLTAGE) / isr_float_t(1000); - - // Change the attenuation level based on the new reading - adc_atten_t atten; - if (mv < thresholds[ADC_ATTEN_DB_0] - 100) - atten = ADC_ATTEN_DB_0; - else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100) - atten = ADC_ATTEN_DB_2_5; - else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100) - atten = ADC_ATTEN_DB_6; - else if (mv > thresholds[ADC_ATTEN_DB_6] - 50) - atten = ADC_ATTEN_DB_11; - else return; - - adc1_set_attenuation(chan, atten); -} - -// ------------------------ -// PWM -// ------------------------ - -int8_t channel_for_pin(const uint8_t pin) { - for (int i = 0; i <= CHANNEL_MAX_NUM; i++) - if (chan_pin[i] == pin) return i; - return -1; -} - -// get PWM channel for pin - if none then attach a new one -// return -1 if fail or invalid pin#, channel # (0-15) if success -int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res) { - if (!WITHIN(pin, 1, MAX_PWM_IOPIN)) return -1; // Not a hardware PWM pin! - int8_t cid = channel_for_pin(pin); - if (cid >= 0) return cid; - - // Find an empty adjacent channel (same timer & freq/res) - for (int i = 0; i <= CHANNEL_MAX_NUM; i++) { - if (chan_pin[i] == 0) { - if (chan_pin[i ^ 0x1] != 0) { - if (pwmInfo[i / 2].freq == freq && pwmInfo[i / 2].res == res) { - chan_pin[i] = pin; // Allocate PWM to this channel - ledcAttachPin(pin, i); - return i; - } - } - else if (cid == -1) // Pair of empty channels? - cid = i & 0xFE; // Save lower channel number - } - } - // not attached, is an empty timer slot avail? - if (cid >= 0) { - chan_pin[cid] = pin; - pwmInfo[cid / 2].freq = freq; - pwmInfo[cid / 2].res = res; - ledcSetup(cid, freq, res); - ledcAttachPin(pin, cid); - } - return cid; // -1 if no channel avail -} - -void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=_BV(PWM_RESOLUTION)-1*/, const bool invert/*=false*/) { - #if ENABLED(I2S_STEPPER_STREAM) - if (pin > 127) { - const uint8_t pinlo = pin & 0x7F; - pwm_pin_t &pindata = pwm_pin_data[pinlo]; - const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, pindata.pwm_cycle_ticks); - if (duty == 0 || duty == pindata.pwm_cycle_ticks) { // max or min (i.e., on/off) - pindata.pwm_duty_ticks = 0; // turn off PWM for this pin - duty ? SBI32(i2s_port_data, pinlo) : CBI32(i2s_port_data, pinlo); // set pin level - } - else - pindata.pwm_duty_ticks = duty; // PWM duty count = # of 4µs ticks per full PWM cycle - } - else - #endif - { - const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION); - if (cid >= 0) { - const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1); - ledcWrite(cid, duty); - } - } -} - -int8_t MarlinHAL::set_pwm_frequency(const pin_t pin, const uint32_t f_desired) { - #if ENABLED(I2S_STEPPER_STREAM) - if (pin > 127) { - pwm_pin_data[pin & 0x7F].pwm_cycle_ticks = 1000000UL / f_desired / 4; // # of 4µs ticks per full PWM cycle - return 0; - } - else - #endif - { - const int8_t cid = channel_for_pin(pin); - if (cid >= 0) { - if (f_desired == ledcReadFreq(cid)) return cid; // no freq change - ledcDetachPin(chan_pin[cid]); - chan_pin[cid] = 0; // remove old freq channel - } - return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one - } -} - -// use hardware PWM if avail, if not then ISR -void analogWrite(const pin_t pin, const uint16_t value, const uint32_t freq/*=PWM_FREQUENCY*/, const uint16_t res/*=8*/) { // always 8 bit resolution! - // Use ledc hardware for internal pins - const int8_t cid = get_pwm_channel(pin, freq, res); - if (cid >= 0) { - ledcWrite(cid, value); // set duty value - return; - } - - // not a hardware PWM pin OR no PWM channels available - int idx = -1; - - // Search Pin - for (int i = 0; i < numPWMUsed; ++i) - if (pwmState[i].pin == pin) { idx = i; break; } - - // not found ? - if (idx < 0) { - // No slots remaining - if (numPWMUsed >= MAX_PWM_PINS) return; - - // Take new slot for pin - idx = numPWMUsed; - pwmState[idx].pin = pin; - // Start timer on first use - if (idx == 0) HAL_timer_start(MF_TIMER_PWM, PWM_TIMER_FREQUENCY); - - ++numPWMUsed; - } - - // Use 7bit internal value - add 1 to have 100% high at 255 - pwmState[idx].value = (value + 1) / 2; -} - -// Handle PWM timer interrupt -HAL_PWM_TIMER_ISR() { - HAL_timer_isr_prologue(MF_TIMER_PWM); - - static uint8_t count = 0; - - for (int i = 0; i < numPWMUsed; ++i) { - if (count == 0) // Start of interval - digitalWrite(pwmState[i].pin, pwmState[i].value ? HIGH : LOW); - else if (pwmState[i].value == count) // End of duration - digitalWrite(pwmState[i].pin, LOW); - } - - // 128 for 7 Bit resolution - count = (count + 1) & 0x7F; - - HAL_timer_isr_epilogue(MF_TIMER_PWM); -} - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/HAL.h b/src/HAL/ESP32/HAL.h deleted file mode 100644 index ddfedf9..0000000 --- a/src/HAL/ESP32/HAL.h +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Espressif ESP32 WiFi - */ - -#define CPU_32_BIT - -#include - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" - -#include "fastio.h" -#include "i2s.h" - -#if ENABLED(WIFISUPPORT) - #include "WebSocketSerial.h" -#endif - -#if ENABLED(ESP3D_WIFISUPPORT) - #include "esp3dlib.h" -#endif - -#include "FlushableHardwareSerial.h" - -// ------------------------ -// Defines -// ------------------------ - -#define MYSERIAL1 flushableSerial - -#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT) - #if ENABLED(ESP3D_WIFISUPPORT) - typedef ForwardSerial1Class< decltype(Serial2Socket) > DefaultSerial1; - extern DefaultSerial1 MSerial0; - #define MYSERIAL2 MSerial0 - #else - #define MYSERIAL2 webSocketSerial - #endif -#endif - -#define CRITICAL_SECTION_START() portENTER_CRITICAL(&hal.spinlock) -#define CRITICAL_SECTION_END() portEXIT_CRITICAL(&hal.spinlock) - -#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment -#define PWM_FREQUENCY 1000u // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency() -#define PWM_RESOLUTION 10u // Default PWM bit resolution -#define CHANNEL_MAX_NUM 15u // max PWM channel # to allocate (7 to only use low speed, 15 to use low & high) -#define MAX_PWM_IOPIN 33u // hardware pwm pins < 34 -#ifndef MAX_EXPANDER_BITS - #define MAX_EXPANDER_BITS 32 // I2S expander bit width (max 32) -#endif - -// ------------------------ -// Types -// ------------------------ - -typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. -typedef int16_t pin_t; - -typedef struct pwm_pin { - uint32_t pwm_cycle_ticks = 1000000UL / (PWM_FREQUENCY) / 4; // # ticks per pwm cycle - uint32_t pwm_tick_count = 0; // current tick count - uint32_t pwm_duty_ticks = 0; // # of ticks for current duty cycle -} pwm_pin_t; - -class Servo; -typedef Servo hal_servo_t; - -// ------------------------ -// Public functions -// ------------------------ - -// -// Tone -// -void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0); -void noTone(const pin_t _pin); -int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res); -void analogWrite(const pin_t pin, const uint16_t value, const uint32_t freq=PWM_FREQUENCY, const uint16_t res=8); - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -#if ENABLED(USE_ESP32_EXIO) - void Write_EXIO(uint8_t IO, uint8_t v); -#endif - -// -// Delay in cycles (used by DELAY_NS / DELAY_US) -// -FORCE_INLINE static void DELAY_CYCLES(uint32_t x) { - unsigned long start, ccount, stop; - - /** - * It's important to care for race conditions (and overflows) here. - * Race condition example: If `stop` calculates to being close to the upper boundary of - * `uint32_t` and if at the same time a longer loop interruption kicks in (e.g. due to other - * FreeRTOS tasks or interrupts), `ccount` might overflow (and therefore be below `stop` again) - * without the loop ever being able to notice that `ccount` had already been above `stop` once - * (and that therefore the number of cycles to delay has already passed). - * As DELAY_CYCLES (through DELAY_NS / DELAY_US) is used by software SPI bit banging to drive - * LCDs and therefore might be called very, very often, this seemingly improbable situation did - * actually happen in reality. It resulted in apparently random print pauses of ~17.9 seconds - * (0x100000000 / 240 MHz) or multiples thereof, essentially ruining the current print by causing - * large blobs of filament. - */ - - __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (start) ); - stop = start + x; - ccount = start; - - if (stop >= start) { - // no overflow, so only loop while in between start and stop: - // 0x00000000 -----------------start****stop-- 0xFFFFFFFF - while (ccount >= start && ccount < stop) { - __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); - } - } - else { - // stop did overflow, so only loop while outside of stop and start: - // 0x00000000 **stop-------------------start** 0xFFFFFFFF - while (ccount >= start || ccount < stop) { - __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); - } - } - -} - -// ------------------------ -// Class Utilities -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -int freeMemory(); - -#pragma GCC diagnostic pop - -void _delay_ms(const int ms); - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init() {} // Called early in setup() - static void init_board(); // Called less early in setup() - static void reboot(); // Restart the firmware - - // Interrupts - static portMUX_TYPE spinlock; - static bool isr_state() { return spinlock.owner == portMUX_FREE_VAL; } - static void isr_on() { if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock); } - static void isr_off() { portENTER_CRITICAL(&spinlock); } - - static void delay_ms(const int ms) { _delay_ms(ms); } - - // Tasks, called from idle() - static void idletask(); - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory(); - - static pwm_pin_t pwm_pin_data[MAX_EXPANDER_BITS]; - - // - // ADC Methods - // - - static uint16_t adc_result; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t pin) {} - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return adc_result; } - - /** - * If not already allocated, allocate a hardware PWM channel - * to the pin and set the duty cycle.. - * Optionally invert the duty cycle [default = false] - * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); - - /** - * Allocate and set the frequency of a hardware PWM pin - * Returns -1 if no pin available. - */ - static int8_t set_pwm_frequency(const pin_t pin, const uint32_t f_desired); - -}; diff --git a/src/HAL/ESP32/HAL_SPI.cpp b/src/HAL/ESP32/HAL_SPI.cpp deleted file mode 100644 index 868ab1b..0000000 --- a/src/HAL/ESP32/HAL_SPI.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" - -#include "../shared/HAL_SPI.h" - -#include -#include - -// ------------------------ -// Public Variables -// ------------------------ - -static SPISettings spiConfig; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(SOFTWARE_SPI) - - // ------------------------ - // Software SPI - // ------------------------ - #error "Software SPI not supported for ESP32. Use Hardware SPI." - -#else - -// ------------------------ -// Hardware SPI -// ------------------------ - -void spiBegin() { - #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif -} - -void spiInit(uint8_t spiRate) { - uint32_t clock; - - switch (spiRate) { - case SPI_FULL_SPEED: clock = 16000000; break; - case SPI_HALF_SPEED: clock = 8000000; break; - case SPI_QUARTER_SPEED: clock = 4000000; break; - case SPI_EIGHTH_SPEED: clock = 2000000; break; - case SPI_SIXTEENTH_SPEED: clock = 1000000; break; - case SPI_SPEED_5: clock = 500000; break; - case SPI_SPEED_6: clock = 250000; break; - default: clock = 1000000; // Default from the SPI library - } - - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - SPI.begin(); -} - -uint8_t spiRec() { - SPI.beginTransaction(spiConfig); - uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); - return returnByte; -} - -void spiRead(uint8_t *buf, uint16_t nbyte) { - SPI.beginTransaction(spiConfig); - SPI.transferBytes(0, buf, nbyte); - SPI.endTransaction(); -} - -void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); - SPI.transfer(b); - SPI.endTransaction(); -} - -void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI.beginTransaction(spiConfig); - SPI.transfer(token); - SPI.writeBytes(const_cast(buf), 512); - SPI.endTransaction(); -} - -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, bitOrder, dataMode); - - SPI.beginTransaction(spiConfig); -} - -#endif // !SOFTWARE_SPI - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/MarlinSPI.h b/src/HAL/ESP32/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/ESP32/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/ESP32/Servo.cpp b/src/HAL/ESP32/Servo.cpp deleted file mode 100644 index ca3950d..0000000 --- a/src/HAL/ESP32/Servo.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "Servo.h" - -// Adjacent channels (0/1, 2/3 etc.) share the same timer and therefore the same frequency and resolution settings on ESP32, -// so we only allocate servo channels up high to avoid side effects with regards to analogWrite (fans, leds, laser pwm etc.) -int Servo::channel_next_free = 12; - -Servo::Servo() {} - -int8_t Servo::attach(const int inPin) { - if (inPin > 0) pin = inPin; - channel = get_pwm_channel(pin, 50u, 16u); - return channel; // -1 if no PWM avail. -} - -// leave channel connected to servo - set duty to zero -void Servo::detach() { - if (channel >= 0) ledcWrite(channel, 0); -} - -int Servo::read() { return degrees; } - -void Servo::write(int inDegrees) { - degrees = constrain(inDegrees, MIN_ANGLE, MAX_ANGLE); - int us = map(degrees, MIN_ANGLE, MAX_ANGLE, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); - int duty = map(us, 0, TAU_USEC, 0, MAX_COMPARE); - if (channel >= 0) ledcWrite(channel, duty); // don't save duty for servos! -} - -void Servo::move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - if (attach(0) >= 0) { - write(value); - safe_delay(servo_delay[channel]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} -#endif // HAS_SERVOS - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/Servo.h b/src/HAL/ESP32/Servo.h deleted file mode 100644 index 1dbb416..0000000 --- a/src/HAL/ESP32/Servo.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -class Servo { - static const int MIN_ANGLE = 0, - MAX_ANGLE = 180, - MIN_PULSE_WIDTH = 544, // Shortest pulse sent to a servo - MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo - TAU_MSEC = 20, - TAU_USEC = (TAU_MSEC * 1000), - MAX_COMPARE = _BV(16) - 1; // 65535 - -public: - Servo(); - int8_t attach(const int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail) - void detach(); - void write(int degrees); // set angle - void move(const int degrees); // attach the servo, then move to value - int read(); // returns current pulse width as an angle between 0 and 180 degrees - -private: - static int channel_next_free; - int channel; - int pin; - int degrees; -}; diff --git a/src/HAL/ESP32/Tone.cpp b/src/HAL/ESP32/Tone.cpp deleted file mode 100644 index 839c612..0000000 --- a/src/HAL/ESP32/Tone.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Description: Tone function for ESP32 - * Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012 - */ - -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -static pin_t tone_pin; -volatile static int32_t toggles; - -void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) { - tone_pin = _pin; - toggles = 2 * frequency * duration / 1000; - HAL_timer_start(MF_TIMER_TONE, 2 * frequency); -} - -void noTone(const pin_t _pin) { - HAL_timer_disable_interrupt(MF_TIMER_TONE); - WRITE(_pin, LOW); -} - -HAL_TONE_TIMER_ISR() { - HAL_timer_isr_prologue(MF_TIMER_TONE); - - if (toggles) { - toggles--; - TOGGLE(tone_pin); - } - else noTone(tone_pin); // turn off interrupt -} - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/WebSocketSerial.cpp b/src/HAL/ESP32/WebSocketSerial.cpp deleted file mode 100644 index eb5b9d6..0000000 --- a/src/HAL/ESP32/WebSocketSerial.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(WIFISUPPORT) - -#include "WebSocketSerial.h" -#include "wifi.h" -#include - -MSerialWebSocketT webSocketSerial(false); -AsyncWebSocket ws("/ws"); // TODO Move inside the class. - -// RingBuffer impl - -#define NEXT_INDEX(I, SIZE) ((I + 1) & (ring_buffer_pos_t)(SIZE - 1)) - -RingBuffer::RingBuffer(ring_buffer_pos_t size) - : data(new uint8_t[size]), - size(size), - read_index(0), - write_index(0) -{} - -RingBuffer::~RingBuffer() { delete[] data; } - -ring_buffer_pos_t RingBuffer::write(const uint8_t c) { - const ring_buffer_pos_t n = NEXT_INDEX(write_index, size); - - if (n != read_index) { - this->data[write_index] = c; - write_index = n; - return 1; - } - - // TODO: buffer is full, handle? - return 0; -} - -ring_buffer_pos_t RingBuffer::write(const uint8_t *buffer, ring_buffer_pos_t size) { - ring_buffer_pos_t written = 0; - for (ring_buffer_pos_t i = 0; i < size; i++) { - written += write(buffer[i]); - } - return written; -} - -int RingBuffer::available() { - return (size - read_index + write_index) & (size - 1); -} - -int RingBuffer::peek() { - return available() ? data[read_index] : -1; -} - -int RingBuffer::read() { - if (available()) { - const int ret = data[read_index]; - read_index = NEXT_INDEX(read_index, size); - return ret; - } - return -1; -} - -ring_buffer_pos_t RingBuffer::read(uint8_t *buffer) { - ring_buffer_pos_t len = available(); - - for (ring_buffer_pos_t i = 0; read_index != write_index; i++) { - buffer[i] = data[read_index]; - read_index = NEXT_INDEX(read_index, size); - } - - return len; -} - -void RingBuffer::flush() { read_index = write_index; } - -// WebSocketSerial impl -WebSocketSerial::WebSocketSerial() - : rx_buffer(RingBuffer(RX_BUFFER_SIZE)), - tx_buffer(RingBuffer(TX_BUFFER_SIZE)) -{} - -void WebSocketSerial::begin(const long baud_setting) { - ws.onEvent([this](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { - switch (type) { - case WS_EVT_CONNECT: client->ping(); break; // client connected - case WS_EVT_DISCONNECT: // client disconnected - case WS_EVT_ERROR: // error was received from the other end - case WS_EVT_PONG: break; // pong message was received (in response to a ping request maybe) - case WS_EVT_DATA: { // data packet - AwsFrameInfo * info = (AwsFrameInfo*)arg; - if (info->opcode == WS_TEXT || info->message_opcode == WS_TEXT) - this->rx_buffer.write(data, len); - } - } - }); - server.addHandler(&ws); -} - -void WebSocketSerial::end() { } -int WebSocketSerial::peek() { return rx_buffer.peek(); } -int WebSocketSerial::read() { return rx_buffer.read(); } -int WebSocketSerial::available() { return rx_buffer.available(); } -void WebSocketSerial::flush() { rx_buffer.flush(); } - -size_t WebSocketSerial::write(const uint8_t c) { - size_t ret = tx_buffer.write(c); - - if (ret && c == '\n') { - uint8_t tmp[TX_BUFFER_SIZE]; - ring_buffer_pos_t size = tx_buffer.read(tmp); - ws.textAll(tmp, size); - } - - return ret; -} - -size_t WebSocketSerial::write(const uint8_t *buffer, size_t size) { - size_t written = 0; - for (size_t i = 0; i < size; i++) - written += write(buffer[i]); - return written; -} - -#endif // WIFISUPPORT -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/WebSocketSerial.h b/src/HAL/ESP32/WebSocketSerial.h deleted file mode 100644 index 6b3e419..0000000 --- a/src/HAL/ESP32/WebSocketSerial.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfig.h" -#include "../../core/serial_hook.h" - -#include - -#ifndef TX_BUFFER_SIZE - #define TX_BUFFER_SIZE 32 -#endif -#if ENABLED(WIFISUPPORT) - #ifndef RX_BUFFER_SIZE - #define RX_BUFFER_SIZE 128 - #endif - #if TX_BUFFER_SIZE <= 0 - #error "TX_BUFFER_SIZE is required for the WebSocket." - #endif -#endif - -typedef uint16_t ring_buffer_pos_t; - -class RingBuffer { - uint8_t *data; - ring_buffer_pos_t size, read_index, write_index; - -public: - RingBuffer(ring_buffer_pos_t size); - ~RingBuffer(); - - int available(); - int peek(); - int read(); - ring_buffer_pos_t read(uint8_t *buffer); - void flush(); - ring_buffer_pos_t write(const uint8_t c); - ring_buffer_pos_t write(const uint8_t *buffer, ring_buffer_pos_t size); -}; - -class WebSocketSerial: public Stream { - RingBuffer rx_buffer; - RingBuffer tx_buffer; - -public: - WebSocketSerial(); - void begin(const long); - void end(); - int available(); - int peek(); - int read(); - void flush(); - size_t write(const uint8_t c); - size_t write(const uint8_t *buffer, size_t size); - - #if ENABLED(SERIAL_STATS_DROPPED_RX) - FORCE_INLINE uint32_t dropped() { return 0; } - #endif - - #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - FORCE_INLINE int rxMaxEnqueued() { return 0; } - #endif -}; - -typedef Serial1Class MSerialWebSocketT; -extern MSerialWebSocketT webSocketSerial; diff --git a/src/HAL/ESP32/eeprom.cpp b/src/HAL/ESP32/eeprom.cpp deleted file mode 100644 index cb5f881..0000000 --- a/src/HAL/ESP32/eeprom.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EEPROM_SETTINGS) - -#include "../shared/eeprom_api.h" -#include - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { return EEPROM.begin(MARLIN_EEPROM_SIZE); } -bool PersistentStore::access_finish() { EEPROM.end(); return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - for (size_t i = 0; i < size; i++) { - EEPROM.write(pos++, value[i]); - crc16(crc, &value[i], 1); - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - for (size_t i = 0; i < size; i++) { - uint8_t c = EEPROM.read(pos++); - if (writing) value[i] = c; - crc16(crc, &c, 1); - } - return false; -} - -#endif // EEPROM_SETTINGS -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/endstop_interrupts.h b/src/HAL/ESP32/endstop_interrupts.h deleted file mode 100644 index 4725df9..0000000 --- a/src/HAL/ESP32/endstop_interrupts.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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 an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void ICACHE_RAM_ATTR endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/ESP32/esp32.csv b/src/HAL/ESP32/esp32.csv deleted file mode 100644 index 6360bbc..0000000 --- a/src/HAL/ESP32/esp32.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x180000, -app1, app, ota_1, 0x190000, 0x180000, -spiffs, data, spiffs, 0x310000, 0xF0000, diff --git a/src/HAL/ESP32/fastio.h b/src/HAL/ESP32/fastio.h deleted file mode 100644 index c8e3f7e..0000000 --- a/src/HAL/ESP32/fastio.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "i2s.h" - -/** - * Utility functions - */ - -// I2S expander pin mapping. -#define IS_I2S_EXPANDER_PIN(IO) TEST(IO, 7) -#define I2S_EXPANDER_PIN_INDEX(IO) (IO & 0x7F) - -// Set pin as input -#define _SET_INPUT(IO) pinMode(IO, INPUT) - -// Set pin as output -#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) - -// Set pin as input with pullup mode -#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT) - -#if ENABLED(USE_ESP32_EXIO) - // Read a pin wrapper - #define READ(IO) digitalRead(IO) - // Write to a pin wrapper - #define WRITE(IO, v) (IO >= 100 ? Write_EXIO(IO, v) : digitalWrite(IO, v)) -#else - // Read a pin wrapper - #define READ(IO) (IS_I2S_EXPANDER_PIN(IO) ? i2s_state(I2S_EXPANDER_PIN_INDEX(IO)) : digitalRead(IO)) - // Write to a pin wrapper - #define WRITE(IO, v) (IS_I2S_EXPANDER_PIN(IO) ? i2s_write(I2S_EXPANDER_PIN_INDEX(IO), v) : digitalWrite(IO, v)) -#endif - -// Set pin as input wrapper (0x80 | (v << 5) | (IO - 100)) -#define SET_INPUT(IO) _SET_INPUT(IO) - -// Set pin as input with pullup wrapper -#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) - -// Set pin as input with pulldown (substitution) -#define SET_INPUT_PULLDOWN SET_INPUT - -// Set pin as output wrapper -#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0) - -// Set pin as PWM -#define SET_PWM SET_OUTPUT - -// Set pin as output and init -#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -// PWM outputs -#define PWM_PIN(P) (P < 34 || P > 127) // NOTE Pins >= 34 are input only on ESP32, so they can't be used for output. - -// Toggle pin value -#define TOGGLE(IO) WRITE(IO, !READ(IO)) - -// -// Ports and functions -// - -// UART -#define RXD 3 -#define TXD 1 - -// TWI (I2C) -#define SCL 5 -#define SDA 4 diff --git a/src/HAL/ESP32/i2s.cpp b/src/HAL/ESP32/i2s.cpp deleted file mode 100644 index cf337ee..0000000 --- a/src/HAL/ESP32/i2s.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfigPre.h" - -#if DISABLED(USE_ESP32_EXIO) - -#include "i2s.h" - -#include "../shared/Marduino.h" -#include -#include -#include -#include -#include "../../module/stepper.h" - -#define DMA_BUF_COUNT 8 // number of DMA buffers to store data -#define DMA_BUF_LEN 4092 // maximum size in bytes -#define I2S_SAMPLE_SIZE 4 // 4 bytes, 32 bits per sample -#define DMA_SAMPLE_COUNT DMA_BUF_LEN / I2S_SAMPLE_SIZE // number of samples per buffer - -typedef enum { - I2S_NUM_0 = 0x0, /*!< I2S 0*/ - I2S_NUM_1 = 0x1, /*!< I2S 1*/ - I2S_NUM_MAX, -} i2s_port_t; - -typedef struct { - uint32_t **buffers; - uint32_t *current; - uint32_t rw_pos; - lldesc_t **desc; - xQueueHandle queue; -} i2s_dma_t; - -static portMUX_TYPE i2s_spinlock[I2S_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; -static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1}; -static i2s_dma_t dma; - -// output value -uint32_t i2s_port_data = 0; - -#define I2S_ENTER_CRITICAL() portENTER_CRITICAL(&i2s_spinlock[i2s_num]) -#define I2S_EXIT_CRITICAL() portEXIT_CRITICAL(&i2s_spinlock[i2s_num]) - -static inline void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); - gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT); - gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv); -} - -static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num) { - I2S_ENTER_CRITICAL(); - I2S[i2s_num]->conf.rx_fifo_reset = 1; - I2S[i2s_num]->conf.rx_fifo_reset = 0; - I2S[i2s_num]->conf.tx_fifo_reset = 1; - I2S[i2s_num]->conf.tx_fifo_reset = 0; - I2S_EXIT_CRITICAL(); - - return ESP_OK; -} - -esp_err_t i2s_start(i2s_port_t i2s_num) { - //start DMA link - I2S_ENTER_CRITICAL(); - i2s_reset_fifo(i2s_num); - - //reset dma - I2S[i2s_num]->lc_conf.in_rst = 1; - I2S[i2s_num]->lc_conf.in_rst = 0; - I2S[i2s_num]->lc_conf.out_rst = 1; - I2S[i2s_num]->lc_conf.out_rst = 0; - - I2S[i2s_num]->conf.tx_reset = 1; - I2S[i2s_num]->conf.tx_reset = 0; - I2S[i2s_num]->conf.rx_reset = 1; - I2S[i2s_num]->conf.rx_reset = 0; - - I2S[i2s_num]->int_clr.val = 0xFFFFFFFF; - I2S[i2s_num]->out_link.start = 1; - I2S[i2s_num]->conf.tx_start = 1; - I2S_EXIT_CRITICAL(); - - return ESP_OK; -} - -esp_err_t i2s_stop(i2s_port_t i2s_num) { - I2S_ENTER_CRITICAL(); - I2S[i2s_num]->out_link.stop = 1; - I2S[i2s_num]->conf.tx_start = 0; - - I2S[i2s_num]->int_clr.val = I2S[i2s_num]->int_st.val; //clear pending interrupt - I2S_EXIT_CRITICAL(); - - return ESP_OK; -} - -static void IRAM_ATTR i2s_intr_handler_default(void *arg) { - int dummy; - lldesc_t *finish_desc; - portBASE_TYPE high_priority_task_awoken = pdFALSE; - - if (I2S0.int_st.out_eof) { - // Get the descriptor of the last item in the linkedlist - finish_desc = (lldesc_t*) I2S0.out_eof_des_addr; - - // If the queue is full it's because we have an underflow, - // more than buf_count isr without new data, remove the front buffer - if (xQueueIsQueueFullFromISR(dma.queue)) - xQueueReceiveFromISR(dma.queue, &dummy, &high_priority_task_awoken); - - xQueueSendFromISR(dma.queue, (void *)(&finish_desc->buf), &high_priority_task_awoken); - } - - if (high_priority_task_awoken == pdTRUE) portYIELD_FROM_ISR(); - - // clear interrupt - I2S0.int_clr.val = I2S0.int_st.val; //clear pending interrupt -} - -void stepperTask(void *parameter) { - uint32_t remaining = 0; - - while (1) { - xQueueReceive(dma.queue, &dma.current, portMAX_DELAY); - dma.rw_pos = 0; - - while (dma.rw_pos < DMA_SAMPLE_COUNT) { - // Fill with the port data post pulse_phase until the next step - if (remaining) { - i2s_push_sample(); - remaining--; - } - else { - Stepper::pulse_phase_isr(); - remaining = Stepper::block_phase_isr(); - } - } - } -} - -int i2s_init() { - periph_module_enable(PERIPH_I2S0_MODULE); - - /** - * Each i2s transfer will take - * fpll = PLL_D2_CLK -- clka_en = 0 - * - * fi2s = fpll / N + b/a -- N = clkm_div_num - * fi2s = 160MHz / 2 - * fi2s = 80MHz - * - * fbclk = fi2s / M -- M = tx_bck_div_num - * fbclk = 80MHz / 2 - * fbclk = 40MHz - * - * fwclk = fbclk / 32 - * - * for fwclk = 250kHz (4µS pulse time) - * N = 10 - * M = 20 - */ - - // Allocate the array of pointers to the buffers - dma.buffers = (uint32_t **)malloc(sizeof(uint32_t*) * DMA_BUF_COUNT); - if (!dma.buffers) return -1; - - // Allocate each buffer that can be used by the DMA controller - for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) { - dma.buffers[buf_idx] = (uint32_t*) heap_caps_calloc(1, DMA_BUF_LEN, MALLOC_CAP_DMA); - if (dma.buffers[buf_idx] == nullptr) return -1; - } - - // Allocate the array of DMA descriptors - dma.desc = (lldesc_t**) malloc(sizeof(lldesc_t*) * DMA_BUF_COUNT); - if (!dma.desc) return -1; - - // Allocate each DMA descriptor that will be used by the DMA controller - for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) { - dma.desc[buf_idx] = (lldesc_t*) heap_caps_malloc(sizeof(lldesc_t), MALLOC_CAP_DMA); - if (dma.desc[buf_idx] == nullptr) return -1; - } - - // Initialize - for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) { - dma.desc[buf_idx]->owner = 1; - dma.desc[buf_idx]->eof = 1; // set to 1 will trigger the interrupt - dma.desc[buf_idx]->sosf = 0; - dma.desc[buf_idx]->length = DMA_BUF_LEN; - dma.desc[buf_idx]->size = DMA_BUF_LEN; - dma.desc[buf_idx]->buf = (uint8_t *) dma.buffers[buf_idx]; - dma.desc[buf_idx]->offset = 0; - dma.desc[buf_idx]->empty = (uint32_t)((buf_idx < (DMA_BUF_COUNT - 1)) ? (dma.desc[buf_idx + 1]) : dma.desc[0]); - } - - dma.queue = xQueueCreate(DMA_BUF_COUNT, sizeof(uint32_t *)); - - // Set the first DMA descriptor - I2S0.out_link.addr = (uint32_t)dma.desc[0]; - - // stop i2s - i2s_stop(I2S_NUM_0); - - // configure I2S data port interface. - i2s_reset_fifo(I2S_NUM_0); - - //reset i2s - I2S0.conf.tx_reset = 1; - I2S0.conf.tx_reset = 0; - I2S0.conf.rx_reset = 1; - I2S0.conf.rx_reset = 0; - - //reset dma - I2S0.lc_conf.in_rst = 1; - I2S0.lc_conf.in_rst = 0; - I2S0.lc_conf.out_rst = 1; - I2S0.lc_conf.out_rst = 0; - - //Enable and configure DMA - I2S0.lc_conf.check_owner = 0; - I2S0.lc_conf.out_loop_test = 0; - I2S0.lc_conf.out_auto_wrback = 0; - I2S0.lc_conf.out_data_burst_en = 0; - I2S0.lc_conf.outdscr_burst_en = 0; - I2S0.lc_conf.out_no_restart_clr = 0; - I2S0.lc_conf.indscr_burst_en = 0; - I2S0.lc_conf.out_eof_mode = 1; - - I2S0.conf2.lcd_en = 0; - I2S0.conf2.camera_en = 0; - I2S0.pdm_conf.pcm2pdm_conv_en = 0; - I2S0.pdm_conf.pdm2pcm_conv_en = 0; - - I2S0.fifo_conf.dscr_en = 0; - - I2S0.conf_chan.tx_chan_mod = TERN(I2S_STEPPER_SPLIT_STREAM, 4, 0); - I2S0.fifo_conf.tx_fifo_mod = 0; - I2S0.conf.tx_mono = 0; - - I2S0.conf_chan.rx_chan_mod = 0; - I2S0.fifo_conf.rx_fifo_mod = 0; - I2S0.conf.rx_mono = 0; - - I2S0.fifo_conf.dscr_en = 1; //connect dma to fifo - - I2S0.conf.tx_start = 0; - I2S0.conf.rx_start = 0; - - I2S0.conf.tx_msb_right = 1; - I2S0.conf.tx_right_first = 1; - - I2S0.conf.tx_slave_mod = 0; // Master - I2S0.fifo_conf.tx_fifo_mod_force_en = 1; - - I2S0.pdm_conf.rx_pdm_en = 0; - I2S0.pdm_conf.tx_pdm_en = 0; - - I2S0.conf.tx_short_sync = 0; - I2S0.conf.rx_short_sync = 0; - I2S0.conf.tx_msb_shift = 0; - I2S0.conf.rx_msb_shift = 0; - - // set clock - I2S0.clkm_conf.clka_en = 0; // Use PLL/2 as reference - I2S0.clkm_conf.clkm_div_num = 10; // minimum value of 2, reset value of 4, max 256 - I2S0.clkm_conf.clkm_div_a = 0; // 0 at reset, what about divide by 0? (not an issue) - I2S0.clkm_conf.clkm_div_b = 0; // 0 at reset - - // fbck = fi2s / tx_bck_div_num - I2S0.sample_rate_conf.tx_bck_div_num = 2; // minimum value of 2 defaults to 6 - - // Enable TX interrupts - I2S0.int_ena.out_eof = 1; - I2S0.int_ena.out_dscr_err = 0; - I2S0.int_ena.out_total_eof = 0; - I2S0.int_ena.out_done = 0; - - // Allocate and Enable the I2S interrupt - intr_handle_t i2s_isr_handle; - esp_intr_alloc(ETS_I2S0_INTR_SOURCE, 0, i2s_intr_handler_default, nullptr, &i2s_isr_handle); - esp_intr_enable(i2s_isr_handle); - - // Create the task that will feed the buffer - xTaskCreatePinnedToCore(stepperTask, "StepperTask", 10000, nullptr, 1, nullptr, CONFIG_ARDUINO_RUNNING_CORE); // run I2S stepper task on same core as rest of Marlin - - // Route the i2s pins to the appropriate GPIO - // If a pin is not defined, no need to configure - #if defined(I2S_DATA) && I2S_DATA >= 0 - gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0); - #endif - #if defined(I2S_BCK) && I2S_BCK >= 0 - gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0); - #endif - #if defined(I2S_WS) && I2S_WS >= 0 - gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0); - #endif - - // Start the I2S peripheral - return i2s_start(I2S_NUM_0); -} - -void i2s_write(uint8_t pin, uint8_t val) { - #if ENABLED(I2S_STEPPER_SPLIT_STREAM) - if (pin >= 16) { - SET_BIT_TO(I2S0.conf_single_data, pin, val); - return; - } - #endif - SET_BIT_TO(i2s_port_data, pin, val); -} - -uint8_t i2s_state(uint8_t pin) { - #if ENABLED(I2S_STEPPER_SPLIT_STREAM) - if (pin >= 16) return TEST(I2S0.conf_single_data, pin); - #endif - return TEST(i2s_port_data, pin); -} - -void i2s_push_sample() { - // Every 4µs (when space in DMA buffer) toggle each expander PWM output using - // the current duty cycle/frequency so they sync with any steps (once - // through the DMA/FIFO buffers). PWM signal inversion handled by other functions - LOOP_L_N(p, MAX_EXPANDER_BITS) { - if (hal.pwm_pin_data[p].pwm_duty_ticks > 0) { // pin has active pwm? - if (hal.pwm_pin_data[p].pwm_tick_count == 0) { - if (TEST32(i2s_port_data, p)) { // hi->lo - CBI32(i2s_port_data, p); - hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_cycle_ticks - hal.pwm_pin_data[p].pwm_duty_ticks; - } - else { // lo->hi - SBI32(i2s_port_data, p); - hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_duty_ticks; - } - } - else - hal.pwm_pin_data[p].pwm_tick_count--; - } - } - - dma.current[dma.rw_pos++] = i2s_port_data; -} - -#endif // !USE_ESP32_EXIO -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/i2s.h b/src/HAL/ESP32/i2s.h deleted file mode 100644 index 573b983..0000000 --- a/src/HAL/ESP32/i2s.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -// current value of the outputs provided over i2s -extern uint32_t i2s_port_data; - -int i2s_init(); - -uint8_t i2s_state(uint8_t pin); - -void i2s_write(uint8_t pin, uint8_t val); - -void i2s_push_sample(); diff --git a/src/HAL/ESP32/inc/Conditionals_LCD.h b/src/HAL/ESP32/inc/Conditionals_LCD.h deleted file mode 100644 index 4da6001..0000000 --- a/src/HAL/ESP32/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/ESP32." -#endif diff --git a/src/HAL/ESP32/inc/Conditionals_adv.h b/src/HAL/ESP32/inc/Conditionals_adv.h deleted file mode 100644 index 3ca8068..0000000 --- a/src/HAL/ESP32/inc/Conditionals_adv.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// -// Board-specific options need to be defined before HAL.h -// -#if MB(MKS_TINYBEE) - #define MAX_EXPANDER_BITS 24 // TinyBee has 3 x HC595 -#endif diff --git a/src/HAL/ESP32/inc/Conditionals_post.h b/src/HAL/ESP32/inc/Conditionals_post.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/ESP32/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/ESP32/inc/SanityCheck.h b/src/HAL/ESP32/inc/SanityCheck.h deleted file mode 100644 index 3ccb159..0000000 --- a/src/HAL/ESP32/inc/SanityCheck.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for ESP32. Disable EMERGENCY_PARSER to continue." -#endif - -#if (ENABLED(SPINDLE_LASER_USE_PWM) && SPINDLE_LASER_FREQUENCY > 78125) || (ENABLED(FAST_PWM_FAN_FREQUENCY) && FAST_PWM_FAN_FREQUENCY > 78125) - #error "SPINDLE_LASER_FREQUENCY and FAST_PWM_FREQUENCY maximum value is 78125Hz for ESP32." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on ESP32." -#endif - -#if BOTH(WIFISUPPORT, ESP3D_WIFISUPPORT) - #error "Only enable one WiFi option, either WIFISUPPORT or ESP3D_WIFISUPPORT." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on ESP32." -#endif - -#if MB(MKS_TINYBEE) && ENABLED(FAST_PWM_FAN) - #error "FAST_PWM_FAN is not available on TinyBee." -#endif - -#if USING_PULLDOWNS - #error "PULLDOWN pin mode is not available on ESP32 boards." -#endif - -#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) - #error "I2S stream is currently incompatible with LIN_ADVANCE." -#endif diff --git a/src/HAL/ESP32/ota.cpp b/src/HAL/ESP32/ota.cpp deleted file mode 100644 index 69a3e25..0000000 --- a/src/HAL/ESP32/ota.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfigPre.h" - -#if BOTH(WIFISUPPORT, OTASUPPORT) - -#include -#include -#include -#include -#include - -void OTA_init() { - ArduinoOTA - .onStart([]() { - timer_pause(TIMER_GROUP_0, TIMER_0); - timer_pause(TIMER_GROUP_0, TIMER_1); - - // U_FLASH or U_SPIFFS - String type = (ArduinoOTA.getCommand() == U_FLASH) ? "sketch" : "filesystem"; - - // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() - Serial.println("Start updating " + type); - }) - .onEnd([]() { - Serial.println("\nEnd"); - }) - .onProgress([](unsigned int progress, unsigned int total) { - Serial.printf("Progress: %u%%\r", (progress / (total / 100))); - }) - .onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - char *str; - switch (error) { - case OTA_AUTH_ERROR: str = "Auth Failed"; break; - case OTA_BEGIN_ERROR: str = "Begin Failed"; break; - case OTA_CONNECT_ERROR: str = "Connect Failed"; break; - case OTA_RECEIVE_ERROR: str = "Receive Failed"; break; - case OTA_END_ERROR: str = "End Failed"; break; - } - Serial.println(str); - }); - - ArduinoOTA.begin(); -} - -void OTA_handle() { - ArduinoOTA.handle(); -} - -#endif // WIFISUPPORT && OTASUPPORT -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/ota.h b/src/HAL/ESP32/ota.h deleted file mode 100644 index 546ace8..0000000 --- a/src/HAL/ESP32/ota.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void OTA_init(); -void OTA_handle(); diff --git a/src/HAL/ESP32/servotimers.h b/src/HAL/ESP32/servotimers.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/ESP32/servotimers.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/ESP32/spi_pins.h b/src/HAL/ESP32/spi_pins.h deleted file mode 100644 index 58881f0..0000000 --- a/src/HAL/ESP32/spi_pins.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define SD_SS_PIN SDSS -#define SD_SCK_PIN 18 -#define SD_MISO_PIN 19 -#define SD_MOSI_PIN 23 diff --git a/src/HAL/ESP32/spiffs.cpp b/src/HAL/ESP32/spiffs.cpp deleted file mode 100644 index a0e713b..0000000 --- a/src/HAL/ESP32/spiffs.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfigPre.h" - -#if BOTH(WIFISUPPORT, WEBSUPPORT) - -#include "../../core/serial.h" - -#include -#include - -bool spiffs_initialized; - -void spiffs_init() { - if (SPIFFS.begin(true)) // formatOnFail = true - spiffs_initialized = true; - else - SERIAL_ERROR_MSG("SPIFFS mount failed"); -} - -#endif // WIFISUPPORT && WEBSUPPORT -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/spiffs.h b/src/HAL/ESP32/spiffs.h deleted file mode 100644 index 64ec7dd..0000000 --- a/src/HAL/ESP32/spiffs.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -extern bool spiffs_initialized; - -void spiffs_init(); diff --git a/src/HAL/ESP32/timers.cpp b/src/HAL/ESP32/timers.cpp deleted file mode 100644 index c37ad24..0000000 --- a/src/HAL/ESP32/timers.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include -#include -#include -#include -#include - -#include "../../inc/MarlinConfig.h" - -// ------------------------ -// Local defines -// ------------------------ - -#define NUM_HARDWARE_TIMERS 4 - -// ------------------------ -// Private Variables -// ------------------------ - -static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; - -const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = { - { TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper - { TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature - { TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM - { TIMER_GROUP_1, TIMER_1, TONE_TIMER_PRESCALE, toneTC_Handler }, // 3 - Tone -}; - -// ------------------------ -// Public functions -// ------------------------ - -void IRAM_ATTR timer_isr(void *para) { - const tTimerConfig& timer = timer_config[(int)para]; - - // Retrieve the interrupt status and the counter value - // from the timer that reported the interrupt - uint32_t intr_status = TG[timer.group]->int_st_timers.val; - TG[timer.group]->hw_timer[timer.idx].update = 1; - - // Clear the interrupt - if (intr_status & BIT(timer.idx)) { - switch (timer.idx) { - case TIMER_0: TG[timer.group]->int_clr_timers.t0 = 1; break; - case TIMER_1: TG[timer.group]->int_clr_timers.t1 = 1; break; - case TIMER_MAX: break; - } - } - - timer.fn(); - - // After the alarm has been triggered - // Enable it again so it gets triggered the next time - TG[timer.group]->hw_timer[timer.idx].config.alarm_en = TIMER_ALARM_EN; -} - -/** - * Enable and initialize the timer - * @param timer_num timer number to initialize - * @param frequency frequency of the timer - */ -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - const tTimerConfig timer = timer_config[timer_num]; - - timer_config_t config; - config.divider = timer.divider; - config.counter_dir = TIMER_COUNT_UP; - config.counter_en = TIMER_PAUSE; - config.alarm_en = TIMER_ALARM_EN; - config.intr_type = TIMER_INTR_LEVEL; - config.auto_reload = true; - - // Select and initialize the timer - timer_init(timer.group, timer.idx, &config); - - // Timer counter initial value and auto reload on alarm - timer_set_counter_value(timer.group, timer.idx, 0x00000000ULL); - - // Configure the alam value and the interrupt on alarm - timer_set_alarm_value(timer.group, timer.idx, (HAL_TIMER_RATE) / timer.divider / frequency - 1); - - timer_enable_intr(timer.group, timer.idx); - - timer_isr_register(timer.group, timer.idx, timer_isr, (void*)(uint32_t)timer_num, 0, nullptr); - - timer_start(timer.group, timer.idx); -} - -/** - * Set the upper value of the timer, when the timer reaches this upper value the - * interrupt should be triggered and the counter reset - * @param timer_num timer number to set the count to - * @param count threshold at which the interrupt is triggered - */ -void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) { - const tTimerConfig timer = timer_config[timer_num]; - timer_set_alarm_value(timer.group, timer.idx, count); -} - -/** - * Get the current upper value of the timer - * @param timer_num timer number to get the count from - * @return the timer current threshold for the alarm to be triggered - */ -hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - const tTimerConfig timer = timer_config[timer_num]; - - uint64_t alarm_value; - timer_get_alarm_value(timer.group, timer.idx, &alarm_value); - - return alarm_value; -} - -/** - * Get the current counter value between 0 and the maximum count (HAL_timer_set_count) - * @param timer_num timer number to get the current count - * @return the current counter of the alarm - */ -hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - const tTimerConfig timer = timer_config[timer_num]; - uint64_t counter_value; - timer_get_counter_value(timer.group, timer.idx, &counter_value); - return counter_value; -} - -/** - * Enable timer interrupt on the timer - * @param timer_num timer number to enable interrupts on - */ -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - //const tTimerConfig timer = timer_config[timer_num]; - //timer_enable_intr(timer.group, timer.idx); -} - -/** - * Disable timer interrupt on the timer - * @param timer_num timer number to disable interrupts on - */ -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - //const tTimerConfig timer = timer_config[timer_num]; - //timer_disable_intr(timer.group, timer.idx); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - const tTimerConfig timer = timer_config[timer_num]; - return TG[timer.group]->int_ena.val | BIT(timer_num); -} - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/timers.h b/src/HAL/ESP32/timers.h deleted file mode 100644 index aa4e155..0000000 --- a/src/HAL/ESP32/timers.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -// ------------------------ -// Defines -// ------------------------ -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint64_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif -#ifndef MF_TIMER_PWM - #define MF_TIMER_PWM 2 // index of timer to use for PWM outputs -#endif -#ifndef MF_TIMER_TONE - #define MF_TIMER_TONE 3 // index of timer for beeper tones -#endif - -#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals - -#if ENABLED(I2S_STEPPER_STREAM) - #define STEPPER_TIMER_PRESCALE 1 - #define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock - #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25 -#else - #define STEPPER_TIMER_PRESCALE 40 - #define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz - #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#endif - -#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts - -#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here - -#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define PWM_TIMER_PRESCALE 10 -#if ENABLED(FAST_PWM_FAN) - #define PWM_TIMER_FREQUENCY FAST_PWM_FAN_FREQUENCY -#else - #define PWM_TIMER_FREQUENCY (50*128) // 50Hz and 7bit resolution -#endif -#define MAX_PWM_PINS 32 // Number of PWM pin-slots - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() -#endif -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() -#endif -#ifndef HAL_PWM_TIMER_ISR - #define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler() -#endif -#ifndef HAL_TONE_TIMER_ISR - #define HAL_TONE_TIMER_ISR() extern "C" void toneTC_Handler() -#endif - -extern "C" { - void tempTC_Handler(); - void stepTC_Handler(); - void pwmTC_Handler(); - void toneTC_Handler(); -} - -// ------------------------ -// Types -// ------------------------ - -typedef struct { - timer_group_t group; - timer_idx_t idx; - uint32_t divider; - void (*fn)(); -} tTimerConfig; - -// ------------------------ -// Public Variables -// ------------------------ - -extern const tTimerConfig timer_config[]; - -// ------------------------ -// Public functions -// ------------------------ - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); -void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t count); -hal_timer_t HAL_timer_get_compare(const uint8_t timer_num); -hal_timer_t HAL_timer_get_count(const uint8_t timer_num); - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/ESP32/u8g_esp32_spi.cpp b/src/HAL/ESP32/u8g_esp32_spi.cpp deleted file mode 100644 index a445035..0000000 --- a/src/HAL/ESP32/u8g_esp32_spi.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfig.h" - -#if EITHER(MKS_MINI_12864, FYSETC_MINI_12864_2_1) - -#include -#include "../shared/HAL_SPI.h" -#include "HAL.h" -#include "SPI.h" - -static SPISettings spiConfig; - - -#ifndef LCD_SPI_SPEED - #ifdef SD_SPI_SPEED - #define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD - #else - #define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied - #endif -#endif - -uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT - if (msgInitCount) { - if (msg == U8G_COM_MSG_INIT) msgInitCount--; - if (msgInitCount) return -1; - } - - switch (msg) { - case U8G_COM_MSG_STOP: break; - - case U8G_COM_MSG_INIT: - OUT_WRITE(DOGLCD_CS, HIGH); - OUT_WRITE(DOGLCD_A0, HIGH); - OUT_WRITE(LCD_RESET_PIN, HIGH); - u8g_Delay(5); - spiBegin(); - spiInit(LCD_SPI_SPEED); - break; - - case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ - WRITE(DOGLCD_A0, arg_val ? HIGH : LOW); - break; - - case U8G_COM_MSG_CHIP_SELECT: /* arg_val == 0 means HIGH level of U8G_PI_CS */ - WRITE(DOGLCD_CS, arg_val ? LOW : HIGH); - break; - - case U8G_COM_MSG_RESET: - WRITE(LCD_RESET_PIN, arg_val); - break; - - case U8G_COM_MSG_WRITE_BYTE: - spiSend((uint8_t)arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - spiSend(*ptr++); - arg_val--; - } - break; - } - return 1; -} - -#endif // EITHER(MKS_MINI_12864, FYSETC_MINI_12864_2_1) - -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/web.cpp b/src/HAL/ESP32/web.cpp deleted file mode 100644 index 7a27707..0000000 --- a/src/HAL/ESP32/web.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../inc/MarlinConfigPre.h" - -#if BOTH(WIFISUPPORT, WEBSUPPORT) - -#include "../../inc/MarlinConfig.h" - -#undef DISABLED // esp32-hal-gpio.h -#include -#include "wifi.h" - -AsyncEventSource events("/events"); // event source (Server-Sent events) - -void onNotFound(AsyncWebServerRequest *request) { - request->send(404); -} - -void web_init() { - server.addHandler(&events); // attach AsyncEventSource - server.serveStatic("/", SPIFFS, "/www").setDefaultFile("index.html"); - server.onNotFound(onNotFound); -} - -#endif // WIFISUPPORT && WEBSUPPORT -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/web.h b/src/HAL/ESP32/web.h deleted file mode 100644 index 60023ac..0000000 --- a/src/HAL/ESP32/web.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void web_init(); diff --git a/src/HAL/ESP32/wifi.cpp b/src/HAL/ESP32/wifi.cpp deleted file mode 100644 index 060f3bd..0000000 --- a/src/HAL/ESP32/wifi.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_ESP32 - -#include "../../core/serial.h" -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(WIFISUPPORT) - -#include -#include -#include -#include "wifi.h" - -AsyncWebServer server(80); - -#ifndef WIFI_HOSTNAME - #define WIFI_HOSTNAME DEFAULT_WIFI_HOSTNAME -#endif - -void wifi_init() { - - SERIAL_ECHO_MSG("Starting WiFi..."); - - WiFi.mode(WIFI_STA); - WiFi.begin(WIFI_SSID, WIFI_PWD); - - while (WiFi.waitForConnectResult() != WL_CONNECTED) { - SERIAL_ERROR_MSG("Unable to connect to WiFi with SSID '" WIFI_SSID "', restarting."); - delay(5000); - ESP.restart(); - } - - delay(10); - if (!MDNS.begin(WIFI_HOSTNAME)) { - SERIAL_ERROR_MSG("Unable to start mDNS with hostname '" WIFI_HOSTNAME "', restarting."); - delay(5000); - ESP.restart(); - } - - MDNS.addService("http", "tcp", 80); - - SERIAL_ECHOLNPGM("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str()); -} - -#endif // WIFISUPPORT -#endif // ARDUINO_ARCH_ESP32 diff --git a/src/HAL/ESP32/wifi.h b/src/HAL/ESP32/wifi.h deleted file mode 100644 index 759a73b..0000000 --- a/src/HAL/ESP32/wifi.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -extern AsyncWebServer server; - -#define DEFAULT_WIFI_HOSTNAME "marlin" - -void wifi_init(); diff --git a/src/HAL/HAL.h b/src/HAL/HAL.h deleted file mode 100644 index 5186578..0000000 --- a/src/HAL/HAL.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "platforms.h" - -#ifndef GCC_VERSION - #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -#include HAL_PATH(.,HAL.h) -extern MarlinHAL hal; - -#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION) - -#ifndef I2C_ADDRESS - #define I2C_ADDRESS(A) uint8_t(A) -#endif - -// Needed for AVR sprintf_P PROGMEM extension -#ifndef S_FMT - #define S_FMT "%s" -#endif - -// String helper -#ifndef PGMSTR - #define PGMSTR(NAM,STR) const char NAM[] = STR -#endif diff --git a/src/HAL/LINUX/HAL.cpp b/src/HAL/LINUX/HAL.cpp deleted file mode 100644 index db43f42..0000000 --- a/src/HAL/LINUX/HAL.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "../../inc/MarlinConfig.h" -#include "../shared/Delay.h" - -// ------------------------ -// Serial ports -// ------------------------ - -MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true)); - -// U8glib required functions -extern "C" { - void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); } - void u8g_MicroDelay() { u8g_xMicroDelay(1); } - void u8g_10MicroDelay() { u8g_xMicroDelay(10); } - void u8g_Delay(uint16_t val) { delay(val); } -} - -//************************// - -// return free heap space -int freeMemory() { return 0; } - -// ------------------------ -// ADC -// ------------------------ - -uint8_t MarlinHAL::active_ch = 0; - -uint16_t MarlinHAL::adc_value() { - const pin_t pin = analogInputToDigitalPin(active_ch); - if (!VALID_PIN(pin)) return 0; - const uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF); - return data; // return 10bit value as Marlin expects -} - -void MarlinHAL::reboot() { /* Reset the application state and GPIO */ } - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/HAL.h b/src/HAL/LINUX/HAL.h deleted file mode 100644 index 22c3e52..0000000 --- a/src/HAL/LINUX/HAL.h +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfigPre.h" - -#include -#include -#include -#undef min -#undef max -#include - -#include "hardware/Clock.h" -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "serial.h" - -// ------------------------ -// Defines -// ------------------------ - -#define CPU_32_BIT -#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp - -#define F_CPU 100000000UL -#define SystemCoreClock F_CPU - -#define DELAY_CYCLES(x) Clock::delayCycles(x) - -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -void _printf(const char *format, ...); -void _putc(uint8_t c); -uint8_t _getc(); - -//arduino: Print.h -#define DEC 10 -#define HEX 16 -#define OCT 8 -#define BIN 2 -//arduino: binary.h (weird defines) -#define B01 1 -#define B10 2 - -// ------------------------ -// Serial ports -// ------------------------ - -extern MSerialT usb_serial; -#define MYSERIAL1 usb_serial - -// -// Interrupts -// -#define CRITICAL_SECTION_START() -#define CRITICAL_SECTION_END() - -// ADC -#define HAL_ADC_VREF 5.0 -#define HAL_ADC_RESOLUTION 10 - -// ------------------------ -// Class Utilities -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() {} - static void watchdog_refresh() {} - - static void init() {} // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Reset the application state and GPIO - - // Interrupts - static bool isr_state() { return true; } - static void isr_on() {} - static void isr_off() {} - - static void delay_ms(const int ms) { _delay_ms(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static constexpr uint8_t reset_reason = RST_POWER_ON; - static uint8_t get_reset_source() { return reset_reason; } - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint8_t active_ch; - - // Called by Temperature::init once at startup - static void adc_init() {} - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const uint8_t) {} - - // Begin ADC sampling on the given channel - static void adc_start(const uint8_t ch) { active_ch = ch; } - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to change the resolution or invert the duty cycle. - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - - static void set_pwm_frequency(const pin_t, int) {} -}; diff --git a/src/HAL/LINUX/MarlinSPI.h b/src/HAL/LINUX/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/LINUX/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/LINUX/arduino.cpp b/src/HAL/LINUX/arduino.cpp deleted file mode 100644 index 075b4cc..0000000 --- a/src/HAL/LINUX/arduino.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include -#include "../../inc/MarlinConfig.h" -#include "hardware/Clock.h" -#include "../shared/Delay.h" - -// Interrupts -void cli() { } // Disable -void sei() { } // Enable - -// Time functions -void _delay_ms(const int ms) { delay(ms); } - -uint32_t millis() { - return (uint32_t)Clock::millis(); -} - -// This is required for some Arduino libraries we are using -void delayMicroseconds(uint32_t us) { - Clock::delayMicros(us); -} - -extern "C" void delay(const int msec) { - Clock::delayMillis(msec); -} - -// IO functions -// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2) -void pinMode(const pin_t pin, const uint8_t mode) { - if (!VALID_PIN(pin)) return; - Gpio::setMode(pin, mode); -} - -void digitalWrite(pin_t pin, uint8_t pin_status) { - if (!VALID_PIN(pin)) return; - Gpio::set(pin, pin_status); -} - -bool digitalRead(pin_t pin) { - if (!VALID_PIN(pin)) return false; - return Gpio::get(pin); -} - -void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH - if (!VALID_PIN(pin)) return; - Gpio::set(pin, pwm_value); -} - -uint16_t analogRead(pin_t adc_pin) { - if (!VALID_PIN(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin))) return 0; - return Gpio::get(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin)); -} - -char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s) { - char format_string[20]; - snprintf(format_string, 20, "%%%d.%df", __width, __prec); - sprintf(__s, format_string, __val); - return __s; -} - -int32_t random(int32_t max) { - return rand() % max; -} - -int32_t random(int32_t min, int32_t max) { - return min + rand() % (max - min); -} - -void randomSeed(uint32_t value) { - srand(value); -} - -int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/eeprom.cpp b/src/HAL/LINUX/eeprom.cpp deleted file mode 100644 index f878bba..0000000 --- a/src/HAL/LINUX/eeprom.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EEPROM_SETTINGS) - -#include "../shared/eeprom_api.h" -#include - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB of Emulated EEPROM -#endif - -uint8_t buffer[MARLIN_EEPROM_SIZE]; -char filename[] = "eeprom.dat"; - -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { - const char eeprom_erase_value = 0xFF; - FILE * eeprom_file = fopen(filename, "rb"); - if (!eeprom_file) return false; - - fseek(eeprom_file, 0L, SEEK_END); - std::size_t file_size = ftell(eeprom_file); - - if (file_size < MARLIN_EEPROM_SIZE) { - memset(buffer + file_size, eeprom_erase_value, MARLIN_EEPROM_SIZE - file_size); - } - else { - fseek(eeprom_file, 0L, SEEK_SET); - fread(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file); - } - - fclose(eeprom_file); - return true; -} - -bool PersistentStore::access_finish() { - FILE * eeprom_file = fopen(filename, "wb"); - if (!eeprom_file) return false; - fwrite(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file); - fclose(eeprom_file); - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - std::size_t bytes_written = 0; - - for (std::size_t i = 0; i < size; i++) { - buffer[pos + i] = value[i]; - bytes_written++; - } - - crc16(crc, value, size); - pos += size; - return (bytes_written != size); // return true for any error -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) { - std::size_t bytes_read = 0; - if (writing) { - for (std::size_t i = 0; i < size; i++) { - value[i] = buffer[pos + i]; - bytes_read++; - } - crc16(crc, value, size); - } - else { - uint8_t temp[size]; - for (std::size_t i = 0; i < size; i++) { - temp[i] = buffer[pos + i]; - bytes_read++; - } - crc16(crc, temp, size); - } - - pos += size; - return bytes_read != size; // return true for any error -} - -#endif // EEPROM_SETTINGS -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/fastio.h b/src/HAL/LINUX/fastio.h deleted file mode 100644 index 4567c62..0000000 --- a/src/HAL/LINUX/fastio.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for X86_64 - */ - -#include "../shared/Marduino.h" -#include - -#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1) -#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0) - -#define SET_MODE(IO, mode) Gpio::setMode(IO, mode) - -#define WRITE_PIN_SET(IO) Gpio::set(IO) -#define WRITE_PIN_CLR(IO) Gpio::clear(IO) - -#define READ_PIN(IO) Gpio::get(IO) -#define WRITE_PIN(IO,V) Gpio::set(IO, V) - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); - * - * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html - */ - -/// Read a pin -#define _READ(IO) READ_PIN(IO) - -/// Write to a pin -#define _WRITE(IO,V) WRITE_PIN(IO,V) - -/// toggle a pin -#define _TOGGLE(IO) _WRITE(IO, !READ(IO)) - -/// set pin as input -#define _SET_INPUT(IO) SET_DIR_INPUT(IO) - -/// set pin as output -#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO) - -/// set pin as input with pullup mode -#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) - -/// set pin as input with pulldown mode -#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT) - -// hg42: all pins can be input or output (I hope) -// hg42: undefined pins create compile error (IO, is no pin) -// hg42: currently not used, but was used by pinsDebug - -/// check if pin is an input -#define _IS_INPUT(IO) (LPC1768_PIN_PIN(IO) >= 0) - -/// check if pin is an output -#define _IS_OUTPUT(IO) (LPC1768_PIN_PIN(IO) >= 0) - -/// 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 input with pullup wrapper -#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) -/// set pin as input with pulldown wrapper -#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0) -/// set pin as output wrapper - reads the pin and sets the output to that value -#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0) -// set pin as PWM -#define SET_PWM(IO) SET_OUTPUT(IO) - -/// check if pin is an input wrapper -#define IS_INPUT(IO) _IS_INPUT(IO) -/// check if pin is an output wrapper -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -// Shorthand -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/src/HAL/LINUX/hardware/Clock.cpp b/src/HAL/LINUX/hardware/Clock.cpp deleted file mode 100644 index 1984a4a..0000000 --- a/src/HAL/LINUX/hardware/Clock.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "../../../inc/MarlinConfig.h" -#include "Clock.h" - -std::chrono::nanoseconds Clock::startup = std::chrono::high_resolution_clock::now().time_since_epoch(); -uint32_t Clock::frequency = F_CPU; -double Clock::time_multiplier = 1.0; - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/Clock.h b/src/HAL/LINUX/hardware/Clock.h deleted file mode 100644 index 072eacf..0000000 --- a/src/HAL/LINUX/hardware/Clock.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -class Clock { -public: - static uint64_t ticks(uint32_t frequency = Clock::frequency) { - return (Clock::nanos() - Clock::startup.count()) / (1000000000ULL / frequency); - } - - static uint64_t nanosToTicks(uint64_t ns, uint32_t frequency = Clock::frequency) { - return ns / (1000000000ULL / frequency); - } - - // Time acceleration compensated - static uint64_t ticksToNanos(uint64_t tick, uint32_t frequency = Clock::frequency) { - return (tick * (1000000000ULL / frequency)) / Clock::time_multiplier; - } - - static void setFrequency(uint32_t freq) { - Clock::frequency = freq; - } - - // Time Acceleration compensated - static uint64_t nanos() { - auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); - return (now.count() - Clock::startup.count()) * Clock::time_multiplier; - } - - static uint64_t micros() { - return Clock::nanos() / 1000; - } - - static uint64_t millis() { - return Clock::micros() / 1000; - } - - static double seconds() { - return Clock::nanos() / 1000000000.0; - } - - static void delayCycles(uint64_t cycles) { - std::this_thread::sleep_for(std::chrono::nanoseconds( (1000000000L / frequency) * cycles) / Clock::time_multiplier ); - } - - static void delayMicros(uint64_t micros) { - std::this_thread::sleep_for(std::chrono::microseconds( micros ) / Clock::time_multiplier); - } - - static void delayMillis(uint64_t millis) { - std::this_thread::sleep_for(std::chrono::milliseconds( millis ) / Clock::time_multiplier); - } - - static void delaySeconds(double secs) { - std::this_thread::sleep_for(std::chrono::duration(secs * 1000) / Clock::time_multiplier); - } - - // Will reduce timer resolution increasing likelihood of overflows - static void setTimeMultiplier(double tm) { - Clock::time_multiplier = tm; - } - -private: - static std::chrono::nanoseconds startup; - static uint32_t frequency; - static double time_multiplier; -}; diff --git a/src/HAL/LINUX/hardware/Gpio.cpp b/src/HAL/LINUX/hardware/Gpio.cpp deleted file mode 100644 index 61a7be7..0000000 --- a/src/HAL/LINUX/hardware/Gpio.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "Gpio.h" - -pin_data Gpio::pin_map[Gpio::pin_count+1] = {}; -IOLogger* Gpio::logger = nullptr; - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/Gpio.h b/src/HAL/LINUX/hardware/Gpio.h deleted file mode 100644 index f946be6..0000000 --- a/src/HAL/LINUX/hardware/Gpio.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "Clock.h" -#include "../../../inc/MarlinConfigPre.h" -#include - -typedef int16_t pin_type; - -struct GpioEvent { - enum Type { - NOP, - FALL, - RISE, - SET_VALUE, - SETM, - SETD - }; - uint64_t timestamp; - pin_type pin_id; - GpioEvent::Type event; - - GpioEvent(uint64_t timestamp, pin_type pin_id, GpioEvent::Type event) { - this->timestamp = timestamp; - this->pin_id = pin_id; - this->event = event; - } -}; - -class IOLogger { -public: - virtual ~IOLogger(){}; - virtual void log(GpioEvent ev) = 0; -}; - -class Peripheral { -public: - virtual ~Peripheral(){}; - virtual void interrupt(GpioEvent ev) = 0; - virtual void update() = 0; -}; - -struct pin_data { - uint8_t dir; - uint8_t mode; - uint16_t value; - Peripheral* cb; -}; - -class Gpio { -public: - - static const pin_type pin_count = 255; - static pin_data pin_map[pin_count+1]; - - static bool valid_pin(pin_type pin) { - return pin >= 0 && pin <= pin_count; - } - - static void set(pin_type pin) { - set(pin, 1); - } - - static void set(pin_type pin, uint16_t value) { - if (!valid_pin(pin)) return; - GpioEvent::Type evt_type = value > 1 ? GpioEvent::SET_VALUE : value > pin_map[pin].value ? GpioEvent::RISE : value < pin_map[pin].value ? GpioEvent::FALL : GpioEvent::NOP; - pin_map[pin].value = value; - GpioEvent evt(Clock::nanos(), pin, evt_type); - if (pin_map[pin].cb) { - pin_map[pin].cb->interrupt(evt); - } - if (Gpio::logger) Gpio::logger->log(evt); - } - - static uint16_t get(pin_type pin) { - if (!valid_pin(pin)) return 0; - return pin_map[pin].value; - } - - static void clear(pin_type pin) { - set(pin, 0); - } - - static void setMode(pin_type pin, uint8_t value) { - if (!valid_pin(pin)) return; - pin_map[pin].mode = value; - GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETM); - if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt); - if (Gpio::logger) Gpio::logger->log(evt); - } - - static uint8_t getMode(pin_type pin) { - if (!valid_pin(pin)) return 0; - return pin_map[pin].mode; - } - - static void setDir(pin_type pin, uint8_t value) { - if (!valid_pin(pin)) return; - pin_map[pin].dir = value; - GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETD); - if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt); - if (Gpio::logger) Gpio::logger->log(evt); - } - - static uint8_t getDir(pin_type pin) { - if (!valid_pin(pin)) return 0; - return pin_map[pin].dir; - } - - static void attachPeripheral(pin_type pin, Peripheral* per) { - if (!valid_pin(pin)) return; - pin_map[pin].cb = per; - } - - static void attachLogger(IOLogger* logger) { - Gpio::logger = logger; - } - -private: - static IOLogger* logger; -}; diff --git a/src/HAL/LINUX/hardware/Heater.cpp b/src/HAL/LINUX/hardware/Heater.cpp deleted file mode 100644 index 44f1198..0000000 --- a/src/HAL/LINUX/hardware/Heater.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "Clock.h" -#include -#include "../../../inc/MarlinConfig.h" - -#include "Heater.h" - -Heater::Heater(pin_t heater, pin_t adc) { - heater_state = 0; - room_temp_raw = 150; - last = Clock::micros(); - heater_pin = heater; - adc_pin = adc; - heat = 0.0; -} - -Heater::~Heater() { -} - -void Heater::update() { - // crude pwm read and cruder heat simulation - auto now = Clock::micros(); - double delta = (now - last); - if (delta > 1000 ) { - heater_state = pwmcap.update(0xFFFF * Gpio::pin_map[heater_pin].value); - last = now; - heat += (heater_state - heat) * (delta / 1000000000.0); - - NOLESS(heat, room_temp_raw); - Gpio::pin_map[analogInputToDigitalPin(adc_pin)].value = 0xFFFF - (uint16_t)heat; - } -} - -void Heater::interrupt(GpioEvent ev) { - // unused -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/Heater.h b/src/HAL/LINUX/hardware/Heater.h deleted file mode 100644 index 6d590ce..0000000 --- a/src/HAL/LINUX/hardware/Heater.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "Gpio.h" - -struct LowpassFilter { - uint64_t data_delay = 0; - uint16_t update(uint16_t value) { - data_delay += value - (data_delay >> 6); - return uint16_t(data_delay >> 6); - } -}; - -class Heater: public Peripheral { -public: - Heater(pin_t heater, pin_t adc); - virtual ~Heater(); - void interrupt(GpioEvent ev); - void update(); - - pin_t heater_pin, adc_pin; - uint16_t room_temp_raw; - uint16_t heater_state; - LowpassFilter pwmcap; - double heat; - uint64_t last; -}; diff --git a/src/HAL/LINUX/hardware/IOLoggerCSV.cpp b/src/HAL/LINUX/hardware/IOLoggerCSV.cpp deleted file mode 100644 index c11fd1f..0000000 --- a/src/HAL/LINUX/hardware/IOLoggerCSV.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "IOLoggerCSV.h" - -IOLoggerCSV::IOLoggerCSV(std::string filename) { - file.open(filename); -} - -IOLoggerCSV::~IOLoggerCSV() { - file.close(); -} - -void IOLoggerCSV::log(GpioEvent ev) { - std::lock_guard lock(vector_lock); - events.push_back(ev); //minimal impact to signal handler -} - -void IOLoggerCSV::flush() { - { std::lock_guard lock(vector_lock); - while (!events.empty()) { - file << events.front().timestamp << ", "<< events.front().pin_id << ", " << events.front().event << std::endl; - events.pop_front(); - } - } - file.flush(); -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/IOLoggerCSV.h b/src/HAL/LINUX/hardware/IOLoggerCSV.h deleted file mode 100644 index d8fe738..0000000 --- a/src/HAL/LINUX/hardware/IOLoggerCSV.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include -#include -#include "Gpio.h" - -class IOLoggerCSV: public IOLogger { -public: - IOLoggerCSV(std::string filename); - virtual ~IOLoggerCSV(); - void flush(); - void log(GpioEvent ev); - -private: - std::ofstream file; - std::list events; - std::mutex vector_lock; -}; diff --git a/src/HAL/LINUX/hardware/LinearAxis.cpp b/src/HAL/LINUX/hardware/LinearAxis.cpp deleted file mode 100644 index e122ef3..0000000 --- a/src/HAL/LINUX/hardware/LinearAxis.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include -#include -#include "Clock.h" -#include "LinearAxis.h" - -LinearAxis::LinearAxis(pin_type enable, pin_type dir, pin_type step, pin_type end_min, pin_type end_max) { - enable_pin = enable; - dir_pin = dir; - step_pin = step; - min_pin = end_min; - max_pin = end_max; - - min_position = 50; - max_position = (200*80) + min_position; - position = rand() % ((max_position - 40) - min_position) + (min_position + 20); - last_update = Clock::nanos(); - - Gpio::attachPeripheral(step_pin, this); - -} - -LinearAxis::~LinearAxis() { - -} - -void LinearAxis::update() { - -} - -void LinearAxis::interrupt(GpioEvent ev) { - if (ev.pin_id == step_pin && !Gpio::pin_map[enable_pin].value) { - if (ev.event == GpioEvent::RISE) { - last_update = ev.timestamp; - position += -1 + 2 * Gpio::pin_map[dir_pin].value; - Gpio::pin_map[min_pin].value = (position < min_position); - //Gpio::pin_map[max_pin].value = (position > max_position); - //if (position < min_position) printf("axis(%d) endstop : pos: %d, mm: %f, min: %d\n", step_pin, position, position / 80.0, Gpio::pin_map[min_pin].value); - } - } -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/LinearAxis.h b/src/HAL/LINUX/hardware/LinearAxis.h deleted file mode 100644 index 34541e7..0000000 --- a/src/HAL/LINUX/hardware/LinearAxis.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include "Gpio.h" - -class LinearAxis: public Peripheral { -public: - LinearAxis(pin_type enable, pin_type dir, pin_type step, pin_type end_min, pin_type end_max); - virtual ~LinearAxis(); - void update(); - void interrupt(GpioEvent ev); - - pin_type enable_pin; - pin_type dir_pin; - pin_type step_pin; - pin_type min_pin; - pin_type max_pin; - - int32_t position; - int32_t min_position; - int32_t max_position; - uint64_t last_update; - -}; diff --git a/src/HAL/LINUX/hardware/Timer.cpp b/src/HAL/LINUX/hardware/Timer.cpp deleted file mode 100644 index 9f0d6a8..0000000 --- a/src/HAL/LINUX/hardware/Timer.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "Timer.h" -#include - -Timer::Timer() { - active = false; - compare = 0; - frequency = 0; - overruns = 0; - timerid = 0; - cbfn = nullptr; - period = 0; - start_time = 0; - avg_error = 0; -} - -Timer::~Timer() { - timer_delete(timerid); -} - -void Timer::init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn) { - struct sigaction sa; - struct sigevent sev; - - frequency = sim_freq; - cbfn = fn; - - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = Timer::handler; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGRTMIN, &sa, nullptr) == -1) { - return; // todo: handle error - } - - sigemptyset(&mask); - sigaddset(&mask, SIGRTMIN); - - disable(); - - sev.sigev_notify = SIGEV_SIGNAL; - sev.sigev_signo = SIGRTMIN; - sev.sigev_value.sival_ptr = (void*)this; - if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { - return; // todo: handle error - } -} - -void Timer::start(uint32_t frequency) { - setCompare(this->frequency / frequency); - //printf("timer(%ld) started\n", getID()); -} - -void Timer::enable() { - if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == -1) { - return; // todo: handle error - } - active = true; - //printf("timer(%ld) enabled\n", getID()); -} - -void Timer::disable() { - if (sigprocmask(SIG_SETMASK, &mask, nullptr) == -1) { - return; // todo: handle error - } - active = false; -} - -void Timer::setCompare(uint32_t compare) { - uint32_t nsec_offset = 0; - if (active) { - nsec_offset = Clock::nanos() - this->start_time; // calculate how long the timer would have been running for - nsec_offset = nsec_offset < 1000 ? nsec_offset : 0; // constrain, this shouldn't be needed but apparently Marlin enables interrupts on the stepper timer before initialising it, todo: investigate ?bug? - } - this->compare = compare; - uint64_t ns = Clock::ticksToNanos(compare, frequency) - nsec_offset; - struct itimerspec its; - its.it_value.tv_sec = ns / 1000000000; - its.it_value.tv_nsec = ns % 1000000000; - its.it_interval.tv_sec = its.it_value.tv_sec; - its.it_interval.tv_nsec = its.it_value.tv_nsec; - - if (timer_settime(timerid, 0, &its, nullptr) == -1) { - printf("timer(%ld) failed, compare: %d(%ld)\n", getID(), compare, its.it_value.tv_nsec); - return; // todo: handle error - } - //printf("timer(%ld) started, compare: %d(%d)\n", getID(), compare, its.it_value.tv_nsec); - this->period = its.it_value.tv_nsec; - this->start_time = Clock::nanos(); -} - -uint32_t Timer::getCount() { - return Clock::nanosToTicks(Clock::nanos() - this->start_time, frequency); -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/hardware/Timer.h b/src/HAL/LINUX/hardware/Timer.h deleted file mode 100644 index 1b3b800..0000000 --- a/src/HAL/LINUX/hardware/Timer.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "Clock.h" - -class Timer { -public: - Timer(); - virtual ~Timer(); - - typedef void (callback_fn)(); - - void init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn); - void start(uint32_t frequency); - void enable(); - bool enabled() {return active;} - void disable(); - void setCompare(uint32_t compare); - uint32_t getCount(); - uint32_t getCompare() {return compare;} - uint32_t getOverruns() {return overruns;} - uint32_t getAvgError() {return avg_error;} - - intptr_t getID() { - return (*(intptr_t*)timerid); - } - - static void handler(int sig, siginfo_t *si, void *uc) { - Timer* _this = (Timer*)si->si_value.sival_ptr; - _this->avg_error += (Clock::nanos() - _this->start_time) - _this->period; //high_resolution_clock is also limited in precision, but best we have - _this->avg_error /= 2; //very crude precision analysis (actually within +-500ns usually) - _this->start_time = Clock::nanos(); // wrap - _this->cbfn(); - _this->overruns += timer_getoverrun(_this->timerid); // even at 50Khz this doesn't stay zero, again demonstrating the limitations - // using a realtime linux kernel would help somewhat - } - -private: - bool active; - uint32_t compare; - uint32_t frequency; - uint32_t overruns; - timer_t timerid; - sigset_t mask; - callback_fn* cbfn; - uint64_t period; - uint64_t avg_error; - uint64_t start_time; -}; diff --git a/src/HAL/LINUX/inc/Conditionals_LCD.h b/src/HAL/LINUX/inc/Conditionals_LCD.h deleted file mode 100644 index 99a6fc2..0000000 --- a/src/HAL/LINUX/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/LINUX." -#endif diff --git a/src/HAL/LINUX/inc/Conditionals_adv.h b/src/HAL/LINUX/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/LINUX/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/LINUX/inc/Conditionals_post.h b/src/HAL/LINUX/inc/Conditionals_post.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/LINUX/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/LINUX/inc/SanityCheck.h b/src/HAL/LINUX/inc/SanityCheck.h deleted file mode 100644 index 36d3190..0000000 --- a/src/HAL/LINUX/inc/SanityCheck.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test X86_64-specific configuration values for errors at compile-time. - */ - -// Emulating RAMPS -#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) - #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on LINUX." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on LINUX." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on LINUX." -#endif diff --git a/src/HAL/LINUX/include/Arduino.h b/src/HAL/LINUX/include/Arduino.h deleted file mode 100644 index f05aaed..0000000 --- a/src/HAL/LINUX/include/Arduino.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include -#include -#include - -#include - -#define HIGH 0x01 -#define LOW 0x00 - -#define INPUT 0x00 -#define OUTPUT 0x01 -#define INPUT_PULLUP 0x02 -#define INPUT_PULLDOWN 0x03 - -#define LSBFIRST 0 -#define MSBFIRST 1 - -#define CHANGE 0x02 -#define FALLING 0x03 -#define RISING 0x04 - -typedef uint8_t byte; -#define PROGMEM -#define PSTR(v) (v) -#define PGM_P const char * - -// Used for libraries, preprocessor, and constants -#define abs(x) ((x)>0?(x):-(x)) - -#ifndef isnan - #define isnan std::isnan -#endif -#ifndef isinf - #define isinf std::isinf -#endif - -#define sq(v) ((v) * (v)) -#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value))) - -// Interrupts -void cli(); // Disable -void sei(); // Enable -void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode); -void detachInterrupt(uint32_t pin); - -extern "C" { - void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode); - void GpioDisableInt(uint32_t port, uint32_t pin); -} - -// Time functions -extern "C" void delay(const int ms); -void _delay_ms(const int ms); -void delayMicroseconds(unsigned long); -uint32_t millis(); - -//IO functions -void pinMode(const pin_t, const uint8_t); -void digitalWrite(pin_t, uint8_t); -bool digitalRead(pin_t); -void analogWrite(pin_t, int); -uint16_t analogRead(pin_t); - -int32_t random(int32_t); -int32_t random(int32_t, int32_t); -void randomSeed(uint32_t); - -char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s); - -int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max); diff --git a/src/HAL/LINUX/include/pinmapping.cpp b/src/HAL/LINUX/include/pinmapping.cpp deleted file mode 100644 index 5823668..0000000 --- a/src/HAL/LINUX/include/pinmapping.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include - -#include "../../../gcode/parser.h" - -int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) { - return parser.intval(code, dval); -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/include/pinmapping.h b/src/HAL/LINUX/include/pinmapping.h deleted file mode 100644 index cfac5e3..0000000 --- a/src/HAL/LINUX/include/pinmapping.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfigPre.h" - -#include -#include "../hardware/Gpio.h" - -typedef pin_type pin_t; - -#define P_NC -1 -constexpr uint16_t NUM_DIGITAL_PINS = Gpio::pin_count; -constexpr uint8_t NUM_ANALOG_INPUTS = 16; - -#define HAL_SENSITIVE_PINS - -constexpr uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS; - -// Get the digital pin for an analog index -constexpr pin_t analogInputToDigitalPin(const int8_t p) { - return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC); -} - -// Get the analog index for a digital pin -constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) { - return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC); -} - -// Return the index of a pin number -constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { return pin; } - -// Test whether the pin is valid -constexpr bool VALID_PIN(const pin_t p) { return WITHIN(p, 0, NUM_DIGITAL_PINS); } - -// Test whether the pin is PWM -constexpr bool PWM_PIN(const pin_t p) { return false; } - -// Test whether the pin is interruptible -constexpr bool INTERRUPT_PIN(const pin_t p) { return false; } - -// Get the pin number at the given index -constexpr pin_t GET_PIN_MAP_PIN(const int16_t ind) { return ind; } - -// Parse a G-code word into a pin index -int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); diff --git a/src/HAL/LINUX/include/serial.h b/src/HAL/LINUX/include/serial.h deleted file mode 100644 index ebae066..0000000 --- a/src/HAL/LINUX/include/serial.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfigPre.h" -#if ENABLED(EMERGENCY_PARSER) - #include "../../../feature/e_parser.h" -#endif -#include "../../../core/serial_hook.h" - -#include -#include - -/** - * Generic RingBuffer - * T type of the buffer array - * S size of the buffer (must be power of 2) - */ -template class RingBuffer { -public: - RingBuffer() { index_read = index_write = 0; } - uint32_t available() volatile { return index_write - index_read; } - uint32_t free() volatile { return buffer_size - available(); } - bool empty() volatile { return index_read == index_write; } - bool full() volatile { return available() == buffer_size; } - void clear() volatile { index_read = index_write = 0; } - - bool peek(T *value) volatile { - if (value == 0 || available() == 0) - return false; - *value = buffer[mask(index_read)]; - return true; - } - - int read() volatile { - if (empty()) return -1; - return buffer[mask(index_read++)]; - } - - bool write(T value) volatile { - if (full()) return false; - buffer[mask(index_write++)] = value; - return true; - } - -private: - uint32_t mask(uint32_t val) volatile { - return buffer_mask & val; - } - - static const uint32_t buffer_size = S; - static const uint32_t buffer_mask = buffer_size - 1; - volatile T buffer[buffer_size]; - volatile uint32_t index_write; - volatile uint32_t index_read; -}; - -struct HalSerial { - HalSerial() { host_connected = true; } - - void begin(int32_t) {} - void end() {} - - int peek() { - uint8_t value; - return receive_buffer.peek(&value) ? value : -1; - } - - int read() { return receive_buffer.read(); } - - size_t write(char c) { - if (!host_connected) return 0; - while (!transmit_buffer.free()); - return transmit_buffer.write(c); - } - - bool connected() { return host_connected; } - - uint16_t available() { - return (uint16_t)receive_buffer.available(); - } - - void flush() { receive_buffer.clear(); } - - uint8_t availableForWrite() { - return transmit_buffer.free() > 255 ? 255 : (uint8_t)transmit_buffer.free(); - } - - void flushTX() { - if (host_connected) - while (transmit_buffer.available()) { /* nada */ } - } - - volatile RingBuffer receive_buffer; - volatile RingBuffer transmit_buffer; - volatile bool host_connected; -}; - -typedef Serial1Class MSerialT; diff --git a/src/HAL/LINUX/main.cpp b/src/HAL/LINUX/main.cpp deleted file mode 100644 index f2af2ff..0000000 --- a/src/HAL/LINUX/main.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef __PLAT_LINUX__ - -//#define GPIO_LOGGING // Full GPIO and Positional Logging - -#include "../../inc/MarlinConfig.h" -#include "../shared/Delay.h" -#include "hardware/IOLoggerCSV.h" -#include "hardware/Heater.h" -#include "hardware/LinearAxis.h" - -#include -#include -#include -#include -#include - -extern void setup(); -extern void loop(); - -// simple stdout / stdin implementation for fake serial port -void write_serial_thread() { - for (;;) { - for (std::size_t i = usb_serial.transmit_buffer.available(); i > 0; i--) { - fputc(usb_serial.transmit_buffer.read(), stdout); - } - std::this_thread::yield(); - } -} - -void read_serial_thread() { - char buffer[255] = {}; - for (;;) { - std::size_t len = _MIN(usb_serial.receive_buffer.free(), 254U); - if (fgets(buffer, len, stdin)) - for (std::size_t i = 0; i < strlen(buffer); i++) - usb_serial.receive_buffer.write(buffer[i]); - std::this_thread::yield(); - } -} - -void simulation_loop() { - Heater hotend(HEATER_0_PIN, TEMP_0_PIN); - Heater bed(HEATER_BED_PIN, TEMP_BED_PIN); - LinearAxis x_axis(X_ENABLE_PIN, X_DIR_PIN, X_STEP_PIN, X_MIN_PIN, X_MAX_PIN); - LinearAxis y_axis(Y_ENABLE_PIN, Y_DIR_PIN, Y_STEP_PIN, Y_MIN_PIN, Y_MAX_PIN); - LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN); - LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC); - - #ifdef GPIO_LOGGING - IOLoggerCSV logger("all_gpio_log.csv"); - Gpio::attachLogger(&logger); - - std::ofstream position_log; - position_log.open("axis_position_log.csv"); - - int32_t x,y,z; - #endif - - for (;;) { - - hotend.update(); - bed.update(); - - x_axis.update(); - y_axis.update(); - z_axis.update(); - extruder0.update(); - - #ifdef GPIO_LOGGING - if (x_axis.position != x || y_axis.position != y || z_axis.position != z) { - uint64_t update = _MAX(x_axis.last_update, y_axis.last_update, z_axis.last_update); - position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl; - position_log.flush(); - x = x_axis.position; - y = y_axis.position; - z = z_axis.position; - } - // flush the logger - logger.flush(); - #endif - - std::this_thread::yield(); - } -} - -int main() { - std::thread write_serial (write_serial_thread); - std::thread read_serial (read_serial_thread); - - #ifdef MYSERIAL1 - MYSERIAL1.begin(BAUDRATE); - SERIAL_ECHOLNPGM("x86_64 Initialized"); - SERIAL_FLUSHTX(); - #endif - - Clock::setFrequency(F_CPU); - Clock::setTimeMultiplier(1.0); // some testing at 10x - - HAL_timer_init(); - - std::thread simulation (simulation_loop); - - DELAY_US(10000); - - setup(); - for (;;) { - loop(); - std::this_thread::yield(); - } - - simulation.join(); - write_serial.join(); - read_serial.join(); -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/pinsDebug.h b/src/HAL/LINUX/pinsDebug.h deleted file mode 100644 index 7bfd97d..0000000 --- a/src/HAL/LINUX/pinsDebug.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Support routines for X86_64 - */ - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define pwm_details(pin) NOOP // (do nothing) -#define pwm_status(pin) false // Print a pin's PWM status. Return true if it's currently a PWM pin. -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) digitalRead(p) -#define PRINT_PORT(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin - -// active ADC function/mode/code values for PINSEL registers -constexpr int8_t ADC_pin_mode(pin_t pin) { - return (-1); -} - -int8_t get_pin_mode(pin_t pin) { - if (!VALID_PIN(pin)) return -1; - return 0; -} - -bool GET_PINMODE(pin_t pin) { - int8_t pin_mode = get_pin_mode(pin); - if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin - return false; - - return (Gpio::getMode(pin) != 0); //input/output state -} - -bool GET_ARRAY_IS_DIGITAL(pin_t pin) { - return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin)); -} diff --git a/src/HAL/LINUX/servo_private.h b/src/HAL/LINUX/servo_private.h deleted file mode 100644 index bcc8d20..0000000 --- a/src/HAL/LINUX/servo_private.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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 - */ - -/** - * Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers - - * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. - * - * The only modification was to update/delete macros to match the LPC176x. - */ - -#include - -// Macros -//values in microseconds -#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 MAX_SERVOS 4 - -#define INVALID_SERVO 255 // flag indicating an invalid servo index - - -// Types - -typedef struct { - uint8_t nbr : 8 ; // a pin number from 0 to 254 (255 signals invalid pin) - uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false -} ServoPin_t; - -typedef struct { - ServoPin_t Pin; - unsigned int pulse_width; // pulse width in microseconds -} ServoInfo_t; - -// Global variables - -extern uint8_t ServoCount; -extern ServoInfo_t servo_info[MAX_SERVOS]; diff --git a/src/HAL/LINUX/spi_pins.h b/src/HAL/LINUX/spi_pins.h deleted file mode 100644 index 33136ac..0000000 --- a/src/HAL/LINUX/spi_pins.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/macros.h" -#include "../../inc/MarlinConfigPre.h" - -#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN) - #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently - // needed due to the speed and mode required for communicating with each device being different. - // This requirement can be removed if the SPI access to these devices is updated to use - // spiBeginTransaction. -#endif - -// Onboard SD -//#define SD_SCK_PIN P0_07 -//#define SD_MISO_PIN P0_08 -//#define SD_MOSI_PIN P0_09 -//#define SD_SS_PIN P0_06 - -// External SD -#ifndef SD_SCK_PIN - #define SD_SCK_PIN 50 -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN 51 -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN 52 -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN 53 -#endif -#ifndef SDSS - #define SDSS SD_SS_PIN -#endif diff --git a/src/HAL/LINUX/timers.cpp b/src/HAL/LINUX/timers.cpp deleted file mode 100644 index 66d80f2..0000000 --- a/src/HAL/LINUX/timers.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __PLAT_LINUX__ - -#include "hardware/Timer.h" - -#include "../../inc/MarlinConfig.h" - -/** - * Use POSIX signals to attempt to emulate Interrupts - * This has many limitations and is not fit for the purpose - */ - -HAL_STEP_TIMER_ISR(); -HAL_TEMP_TIMER_ISR(); - -Timer timers[2]; - -void HAL_timer_init() { - timers[0].init(0, STEPPER_TIMER_RATE, TIMER0_IRQHandler); - timers[1].init(1, TEMP_TIMER_RATE, TIMER1_IRQHandler); -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - timers[timer_num].start(frequency); -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - timers[timer_num].enable(); -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - timers[timer_num].disable(); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - return timers[timer_num].enabled(); -} - -void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - timers[timer_num].setCompare(compare); -} - -hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - return timers[timer_num].getCompare(); -} - -hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - return timers[timer_num].getCount(); -} - -#endif // __PLAT_LINUX__ diff --git a/src/HAL/LINUX/timers.h b/src/HAL/LINUX/timers.h deleted file mode 100644 index 2d2a957..0000000 --- a/src/HAL/LINUX/timers.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL timers for Linux X86_64 - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif - -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler() -#endif - -// PWM timer -#define HAL_PWM_TIMER -#define HAL_PWM_TIMER_ISR() extern "C" void TIMER3_IRQHandler() -#define HAL_PWM_TIMER_IRQn - -void HAL_timer_init(); -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare); -hal_timer_t HAL_timer_get_compare(const uint8_t timer_num); -hal_timer_t HAL_timer_get_count(const uint8_t timer_num); -FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks) { - const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks; - if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp); -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/LPC1768/HAL.cpp b/src/HAL/LPC1768/HAL.cpp deleted file mode 100644 index 9ff3a6b..0000000 --- a/src/HAL/LPC1768/HAL.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" -#include "../shared/Delay.h" -#include "../../../gcode/parser.h" - -DefaultSerial1 USBSerial(false, UsbSerial); - -uint32_t MarlinHAL::adc_result = 0; - -// U8glib required functions -extern "C" { - void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); } - void u8g_MicroDelay() { u8g_xMicroDelay(1); } - void u8g_10MicroDelay() { u8g_xMicroDelay(10); } - void u8g_Delay(uint16_t val) { delay(val); } -} - -// return free heap space -int freeMemory() { - char stack_end; - void *heap_start = malloc(sizeof(uint32_t)); - if (heap_start == 0) return 0; - - uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start; - free(heap_start); - return result; -} - -void MarlinHAL::reboot() { NVIC_SystemReset(); } - -uint8_t MarlinHAL::get_reset_source() { - #if ENABLED(USE_WATCHDOG) - if (watchdog_timed_out()) return RST_WATCHDOG; - #endif - return RST_POWER_ON; -} - -void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); } - -void flashFirmware(const int16_t) { - delay(500); // Give OS time to disconnect - USB_Connect(false); // USB clear connection - delay(1000); // Give OS time to notice - hal.reboot(); -} - -#if ENABLED(USE_WATCHDOG) - - #include - - #define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout - - void MarlinHAL::watchdog_init() { - #if ENABLED(WATCHDOG_RESET_MANUAL) - // We enable the watchdog timer, but only for the interrupt. - - // Configure WDT to only trigger an interrupt - // Disable WDT interrupt (just in case, to avoid triggering it!) - NVIC_DisableIRQ(WDT_IRQn); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); - - // Configure WDT to only trigger an interrupt - // Initialize WDT with the given parameters - WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY); - - // Configure and enable WDT interrupt. - NVIC_ClearPendingIRQ(WDT_IRQn); - NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups - NVIC_EnableIRQ(WDT_IRQn); - #else - WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET); - #endif - WDT_Start(WDT_TIMEOUT_US); - } - - void MarlinHAL::watchdog_refresh() { - WDT_Feed(); - #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) - TOGGLE(LED_PIN); // heartbeat indicator - #endif - } - - // Timeout state - bool MarlinHAL::watchdog_timed_out() { return TEST(WDT_ReadTimeOutFlag(), 0); } - void MarlinHAL::watchdog_clear_timeout_flag() { WDT_ClrTimeOutFlag(); } - -#endif // USE_WATCHDOG - -// For M42/M43, scan command line for pin code -// return index into pin map array if found and the pin is valid. -// return dval if not found or not a valid pin. -int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) { - const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100; - const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2; - return ind > -1 ? ind : dval; -} - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/HAL.h b/src/HAL/LPC1768/HAL.h deleted file mode 100644 index b0eeb98..0000000 --- a/src/HAL/LPC1768/HAL.h +++ /dev/null @@ -1,267 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL_LPC1768/HAL.h - * Hardware Abstraction Layer for NXP LPC1768 - */ - -#define CPU_32_BIT - -#include -#include -#include - -extern "C" volatile uint32_t _millis; - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "MarlinSerial.h" - -#include -#include -#include - -// ------------------------ -// Serial ports -// ------------------------ - -typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1; -extern DefaultSerial1 USBSerial; - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if SERIAL_PORT == -1 - #define MYSERIAL1 USBSerial -#elif WITHIN(SERIAL_PORT, 0, 3) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." -#endif - -#ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == -1 - #define MYSERIAL2 USBSerial - #elif WITHIN(SERIAL_PORT_2, 0, 3) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif -#endif - -#ifdef SERIAL_PORT_3 - #if SERIAL_PORT_3 == -1 - #define MYSERIAL3 USBSerial - #elif WITHIN(SERIAL_PORT_3, 0, 3) - #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) - #else - #error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if MMU2_SERIAL_PORT == -1 - #define MMU2_SERIAL USBSerial - #elif WITHIN(MMU2_SERIAL_PORT, 0, 3) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #else - #error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif -#endif - -#ifdef LCD_SERIAL_PORT - #if LCD_SERIAL_PORT == -1 - #define LCD_SERIAL USBSerial - #elif WITHIN(LCD_SERIAL_PORT, 0, 3) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #else - #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif - #if HAS_DGUS_LCD - #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available() - #endif -#endif - -// -// Interrupts -// - -#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() - -// -// ADC -// - -#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift), - // (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift) - // Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16 - // 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels - -#define ADC_LOWPASS_K_VALUE (2) // Higher values increase rise time - // Rise time sample delays for 100% signal convergence on full range step - // (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273) - // K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step - // Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels) - -#define HAL_ADC_VREF 3.3 // ADC voltage reference - -#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t -#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL - -// -// Pin Mapping for M42, M43, M226 -// - -// Test whether the pin is valid -constexpr bool VALID_PIN(const pin_t pin) { - return LPC176x::pin_is_valid(pin); -} - -// Get the analog index for a digital pin -constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) { - return (LPC176x::pin_is_valid(pin) && LPC176x::pin_has_adc(pin)) ? pin : -1; -} - -// Return the index of a pin number -constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { - return LPC176x::pin_index(pin); -} - -// Get the pin number at the given index -constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) { - return LPC176x::pin_index(index); -} - -// Parse a G-code word into a pin index -int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); -// P0.6 thru P0.9 are for the onboard SD card -#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09, - -// ------------------------ -// Defines -// ------------------------ - -#define PLATFORM_M997_SUPPORT -void flashFirmware(const int16_t); - -#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment - -// Default graphical display delays -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - static void init(); // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_PRIMASK(); } - static void isr_on() { __enable_irq(); } - static void isr_off() { __disable_irq(); } - - static void delay_ms(const int ms) { _delay_ms(ms); } - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; }); - static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {}); - - // Tasks, called from idle() - static void idletask(); - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source(); - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - using FilteredADC = LPC176x::ADC; - - // Called by Temperature::init once at startup - static void adc_init() {} - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t pin) { - FilteredADC::enable_channel(pin); - } - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static uint32_t adc_result; - static void adc_start(const pin_t pin) { - adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits - } - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return uint16_t(adc_result); } - - /** - * Set the PWM duty cycle for the pin to the given value. - * Optionally invert the duty cycle [default = false] - * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); - - /** - * Set the frequency of the timer corresponding to the provided pin - * All Hardware PWM pins will run at the same frequency and - * All Software PWM pins will run at the same frequency - */ - static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); -}; diff --git a/src/HAL/LPC1768/HAL_SPI.cpp b/src/HAL/LPC1768/HAL_SPI.cpp deleted file mode 100644 index 29f9b43..0000000 --- a/src/HAL/LPC1768/HAL_SPI.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Software SPI functions originally from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - */ - -/** - * For TARGET_LPC1768 - */ - -/** - * Hardware SPI and Software SPI implementations are included in this file. - * The hardware SPI runs faster and has higher throughput but is not compatible - * with some LCD interfaces/adapters. - * - * Control of the slave select pin(s) is handled by the calling routines. - * - * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card - * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with - * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is - * active. If any of these pins are shared then the software SPI must be used. - * - * A more sophisticated hardware SPI can be found at the following link. - * This implementation has not been fully debugged. - * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e - */ - -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" -#include - -// Hardware SPI and SPIClass -#include -#include - -#include "../shared/HAL_SPI.h" - -// ------------------------ -// Public functions -// ------------------------ -#if ENABLED(LPC_SOFTWARE_SPI) - - // Software SPI - - #include - - static uint8_t SPI_speed = SPI_FULL_SPEED; - - static uint8_t spiTransfer(uint8_t b) { - return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN); - } - - void spiBegin() { - swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN); - } - - void spiInit(uint8_t spiRate) { - SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN); - } - - uint8_t spiRec() { return spiTransfer(0xFF); } - - void spiRead(uint8_t*buf, uint16_t nbyte) { - for (int i = 0; i < nbyte; i++) - buf[i] = spiTransfer(0xFF); - } - - void spiSend(uint8_t b) { (void)spiTransfer(b); } - - void spiSend(const uint8_t *buf, size_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) - (void)spiTransfer(buf[i]); - } - - void spiSendBlock(uint8_t token, const uint8_t *buf) { - (void)spiTransfer(token); - for (uint16_t i = 0; i < 512; i++) - (void)spiTransfer(buf[i]); - } - -#else - - #ifdef SD_SPI_SPEED - #define INIT_SPI_SPEED SD_SPI_SPEED - #else - #define INIT_SPI_SPEED SPI_FULL_SPEED - #endif - - void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0 - - void spiInit(uint8_t spiRate) { - #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN - SPI.setModule(1); - #elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN - SPI.setModule(2); - #endif - SPI.setDataSize(DATA_SIZE_8BIT); - SPI.setDataMode(SPI_MODE0); - - SPI.setClock(SPISettings::spiRate2Clock(spiRate)); - SPI.begin(); - } - - static uint8_t doio(uint8_t b) { - return SPI.transfer(b & 0x00FF) & 0x00FF; - } - - void spiSend(uint8_t b) { doio(b); } - - void spiSend(const uint8_t *buf, size_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]); - } - - void spiSend(uint32_t chan, byte b) {} - - void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {} - - // Read single byte from SPI - uint8_t spiRec() { return doio(0xFF); } - - uint8_t spiRec(uint32_t chan) { return 0; } - - // Read from SPI into buffer - void spiRead(uint8_t *buf, uint16_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF); - } - - uint8_t spiTransfer(uint8_t b) { return doio(b); } - - // Write from buffer to SPI - void spiSendBlock(uint8_t token, const uint8_t *buf) { - (void)spiTransfer(token); - for (uint16_t i = 0; i < 512; i++) - (void)spiTransfer(buf[i]); - } - - // Begin SPI transaction, set clock, bit order, data mode - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - // TODO: Implement this method - } - -#endif // LPC_SOFTWARE_SPI - -/** - * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset. - */ -static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) { - while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1 - while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0 -} - -// Retain the pin init state of the SPI, to avoid init more than once, -// even if more instances of SPIClass exist -static bool spiInitialised[BOARD_NR_SPI] = { false }; - -SPIClass::SPIClass(uint8_t device) { - // Init things specific to each SPI device - // clock divider setup is a bit of hack, and needs to be improved at a later date. - - #if BOARD_NR_SPI >= 1 - _settings[0].spi_d = LPC_SSP0; - _settings[0].dataMode = SPI_MODE0; - _settings[0].dataSize = DATA_SIZE_8BIT; - _settings[0].clock = SPI_CLOCK_MAX; - //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); - #endif - - #if BOARD_NR_SPI >= 2 - _settings[1].spi_d = LPC_SSP1; - _settings[1].dataMode = SPI_MODE0; - _settings[1].dataSize = DATA_SIZE_8BIT; - _settings[1].clock = SPI_CLOCK_MAX; - //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); - #endif - - setModule(device); - - // Init the GPDMA controller - // TODO: call once in the constructor? or each time? - GPDMA_Init(); -} - -SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) { - #if BOARD_NR_SPI >= 1 - if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1); - #endif - #if BOARD_NR_SPI >= 2 - if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2); - #endif -} - -void SPIClass::begin() { - // Init the SPI pins in the first begin call - if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) || - (_currentSetting->spi_d == LPC_SSP1 && spiInitialised[1] == false)) { - pin_t sck, miso, mosi; - if (_currentSetting->spi_d == LPC_SSP0) { - sck = BOARD_SPI1_SCK_PIN; - miso = BOARD_SPI1_MISO_PIN; - mosi = BOARD_SPI1_MOSI_PIN; - spiInitialised[0] = true; - } - else if (_currentSetting->spi_d == LPC_SSP1) { - sck = BOARD_SPI2_SCK_PIN; - miso = BOARD_SPI2_MISO_PIN; - mosi = BOARD_SPI2_MOSI_PIN; - spiInitialised[1] = true; - } - PINSEL_CFG_Type PinCfg; // data structure to hold init values - PinCfg.Funcnum = 2; - PinCfg.OpenDrain = 0; - PinCfg.Pinmode = 0; - PinCfg.Pinnum = LPC176x::pin_bit(sck); - PinCfg.Portnum = LPC176x::pin_port(sck); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(sck); - - PinCfg.Pinnum = LPC176x::pin_bit(miso); - PinCfg.Portnum = LPC176x::pin_port(miso); - PINSEL_ConfigPin(&PinCfg); - SET_INPUT(miso); - - PinCfg.Pinnum = LPC176x::pin_bit(mosi); - PinCfg.Portnum = LPC176x::pin_port(mosi); - PINSEL_ConfigPin(&PinCfg); - SET_OUTPUT(mosi); - } - - updateSettings(); - SSP_Cmd(_currentSetting->spi_d, ENABLE); // start SSP running -} - -void SPIClass::beginTransaction(const SPISettings &cfg) { - setBitOrder(cfg.bitOrder); - setDataMode(cfg.dataMode); - setDataSize(cfg.dataSize); - //setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); - begin(); -} - -uint8_t SPIClass::transfer(const uint16_t b) { - // Send and receive a single byte - SSP_ReceiveData(_currentSetting->spi_d); // read any previous data - SSP_SendData(_currentSetting->spi_d, b); - waitSpiTxEnd(_currentSetting->spi_d); // wait for it to finish - return SSP_ReceiveData(_currentSetting->spi_d); -} - -uint16_t SPIClass::transfer16(const uint16_t data) { - return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF); -} - -void SPIClass::end() { - // Neither is needed for Marlin - //SSP_Cmd(_currentSetting->spi_d, DISABLE); - //SSP_DeInit(_currentSetting->spi_d); -} - -void SPIClass::send(uint8_t data) { - SSP_SendData(_currentSetting->spi_d, data); -} - -void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) { - //TODO: LPC dma can only write 0xFFF bytes at once. - GPDMA_Channel_CFG_Type GPDMACfg; - - /* Configure GPDMA channel 0 -------------------------------------------------------------*/ - /* DMA Channel 0 */ - GPDMACfg.ChannelNum = 0; - // Source memory - GPDMACfg.SrcMemAddr = (uint32_t)buf; - // Destination memory - Not used - GPDMACfg.DstMemAddr = 0; - // Transfer size - GPDMACfg.TransferSize = length; - // Transfer width - GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE; - // Transfer type - GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P; - // Source connection - unused - GPDMACfg.SrcConn = 0; - // Destination connection - GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx; - - GPDMACfg.DMALLI = 0; - - // Enable dma on SPI - SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE); - - // Only increase memory if minc is true - GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0); - - // Setup channel with given parameter - GPDMA_Setup(&GPDMACfg); - - // Enable DMA - GPDMA_ChannelCmd(0, ENABLE); - - // Wait for data transfer - while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { } - - // Clear err and int - GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); - GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0); - - // Disable DMA - GPDMA_ChannelCmd(0, DISABLE); - - waitSpiTxEnd(_currentSetting->spi_d); - - SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE); -} - -uint16_t SPIClass::read() { - return SSP_ReceiveData(_currentSetting->spi_d); -} - -void SPIClass::read(uint8_t *buf, uint32_t len) { - for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF); -} - -void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; } - -void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed - -void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; } - -void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; } - -void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; } - -/** - * Set up/tear down - */ -void SPIClass::updateSettings() { - //SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?! - - // Divide PCLK by 2 for SSP0 - //CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2); - - SSP_CFG_Type HW_SPI_init; // data structure to hold init values - SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode - HW_SPI_init.ClockRate = _currentSetting->clock; - HW_SPI_init.Databit = _currentSetting->dataSize; - - /** - * SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge - * 0 0 0 Falling Rising - * 1 0 1 Rising Falling - * 2 1 0 Rising Falling - * 3 1 1 Falling Rising - */ - switch (_currentSetting->dataMode) { - case SPI_MODE0: - HW_SPI_init.CPHA = SSP_CPHA_FIRST; - HW_SPI_init.CPOL = SSP_CPOL_HI; - break; - case SPI_MODE1: - HW_SPI_init.CPHA = SSP_CPHA_SECOND; - HW_SPI_init.CPOL = SSP_CPOL_HI; - break; - case SPI_MODE2: - HW_SPI_init.CPHA = SSP_CPHA_FIRST; - HW_SPI_init.CPOL = SSP_CPOL_LO; - break; - case SPI_MODE3: - HW_SPI_init.CPHA = SSP_CPHA_SECOND; - HW_SPI_init.CPOL = SSP_CPOL_LO; - break; - default: - break; - } - - // TODO: handle bitOrder - SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers -} - -#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN - SPIClass SPI(1); -#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN - SPIClass SPI(2); -#endif - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/MarlinSPI.h b/src/HAL/LPC1768/MarlinSPI.h deleted file mode 100644 index fab245f..0000000 --- a/src/HAL/LPC1768/MarlinSPI.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -/** - * Marlin currently requires 3 SPI classes: - * - * SPIClass: - * This class is normally provided by frameworks and has a semi-default interface. - * This is needed because some libraries reference it globally. - * - * SPISettings: - * Container for SPI configs for SPIClass. As above, libraries may reference it globally. - * - * These two classes are often provided by frameworks so we cannot extend them to add - * useful methods for Marlin. - * - * MarlinSPI: - * Provides the default SPIClass interface plus some Marlin goodies such as a simplified - * interface for SPI DMA transfer. - * - */ - -using MarlinSPI = SPIClass; diff --git a/src/HAL/LPC1768/MarlinSerial.cpp b/src/HAL/LPC1768/MarlinSerial.cpp deleted file mode 100644 index f2aecf5..0000000 --- a/src/HAL/LPC1768/MarlinSerial.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "MarlinSerial.h" - -#include "../../inc/MarlinConfig.h" - -#if USING_HW_SERIAL0 - MarlinSerial _MSerial0(LPC_UART0); - MSerialT MSerial0(true, _MSerial0); - extern "C" void UART0_IRQHandler() { _MSerial0.IRQHandler(); } -#endif -#if USING_HW_SERIAL1 - MarlinSerial _MSerial1((LPC_UART_TypeDef *) LPC_UART1); - MSerialT MSerial1(true, _MSerial1); - extern "C" void UART1_IRQHandler() { _MSerial1.IRQHandler(); } -#endif -#if USING_HW_SERIAL2 - MarlinSerial _MSerial2(LPC_UART2); - MSerialT MSerial2(true, _MSerial2); - extern "C" void UART2_IRQHandler() { _MSerial2.IRQHandler(); } -#endif -#if USING_HW_SERIAL3 - MarlinSerial _MSerial3(LPC_UART3); - MSerialT MSerial3(true, _MSerial3); - extern "C" void UART3_IRQHandler() { _MSerial3.IRQHandler(); } -#endif - -#if ENABLED(EMERGENCY_PARSER) - - bool MarlinSerial::recv_callback(const char c) { - // Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro) - if (false) {} - #if USING_HW_SERIAL0 - else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c); - #endif - #if USING_HW_SERIAL1 - else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c); - #endif - #if USING_HW_SERIAL2 - else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c); - #endif - #if USING_HW_SERIAL3 - else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c); - #endif - return true; - } - -#endif - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/MarlinSerial.h b/src/HAL/LPC1768/MarlinSerial.h deleted file mode 100644 index 3e6848a..0000000 --- a/src/HAL/LPC1768/MarlinSerial.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -#include "../../inc/MarlinConfigPre.h" -#if ENABLED(EMERGENCY_PARSER) - #include "../../feature/e_parser.h" -#endif -#include "../../core/serial_hook.h" - -#ifndef SERIAL_PORT - #define SERIAL_PORT 0 -#endif -#ifndef RX_BUFFER_SIZE - #define RX_BUFFER_SIZE 128 -#endif -#ifndef TX_BUFFER_SIZE - #define TX_BUFFER_SIZE 32 -#endif - -class MarlinSerial : public HardwareSerial { -public: - MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial(UARTx) { } - - void end() {} - - uint8_t availableForWrite(void) { /* flushTX(); */ return TX_BUFFER_SIZE; } - - #if ENABLED(EMERGENCY_PARSER) - bool recv_callback(const char c) override; - #endif -}; - -// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads -// of 'available' and 'read' method are not used in this multiple inheritance scenario. -// Instead, use a ForwardSerial here that adapts the interface. -typedef ForwardSerial1Class MSerialT; -extern MSerialT MSerial0; -extern MSerialT MSerial1; -extern MSerialT MSerial2; -extern MSerialT MSerial3; - -// Consequently, we can't use a RuntimeSerial either. The workaround would be to use -// a RuntimeSerial> type here. Ignore for now until it's actually required. -#if ENABLED(SERIAL_RUNTIME_HOOK) - #error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x." -#endif diff --git a/src/HAL/LPC1768/MinSerial.cpp b/src/HAL/LPC1768/MinSerial.cpp deleted file mode 100644 index 7a1c038..0000000 --- a/src/HAL/LPC1768/MinSerial.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - -#include "../shared/MinSerial.h" -#include - -static void TX(char c) { _DBC(c); } -void install_min_serial() { HAL_min_serial_out = &TX; } - -#if DISABLED(DYNAMIC_VECTORTABLE) -extern "C" { - __attribute__((naked)) void JumpHandler_ASM() { - __asm__ __volatile__ ( - "b CommonHandler_ASM\n" - ); - } - void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler(); -} -#endif - -#endif // POSTMORTEM_DEBUGGING -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/Servo.h b/src/HAL/LPC1768/Servo.h deleted file mode 100644 index f02f503..0000000 --- a/src/HAL/LPC1768/Servo.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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 - */ -#pragma once - -/** - * Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers - - * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. - * - * The only modification was to update/delete macros to match the LPC176x. - */ - -#include - -class libServo: public Servo { - public: - void move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - - if (attach(servo_info[servoIndex].Pin.nbr) >= 0) { // try to reattach - write(value); - safe_delay(servo_delay[servoIndex]); // delay to allow servo to reach position - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } - - } -}; - -class libServo; -typedef libServo hal_servo_t; diff --git a/src/HAL/LPC1768/eeprom_flash.cpp b/src/HAL/LPC1768/eeprom_flash.cpp deleted file mode 100644 index 38d2705..0000000 --- a/src/HAL/LPC1768/eeprom_flash.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -/** - * Emulate EEPROM storage using Flash Memory - * - * Use a single 32K flash sector to store EEPROM data. To reduce the - * number of erase operations a simple "leveling" scheme is used that - * maintains a number of EEPROM "slots" within the larger flash sector. - * Each slot is used in turn and the entire sector is only erased when all - * slots have been used. - * - * A simple RAM image is used to hold the EEPROM data during I/O operations - * and this is flushed to the next available slot when an update is complete. - * If RAM usage becomes an issue we could store this image in one of the two - * 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently - * unused). - */ -#include "../../inc/MarlinConfig.h" - -#if ENABLED(FLASH_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" - -extern "C" { - #include -} - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif - -#define SECTOR_START(sector) ((sector < 16) ? (sector << 12) : ((sector - 14) << 15)) -#define EEPROM_SECTOR 29 -#define SECTOR_SIZE 32768 -#define EEPROM_SLOTS ((SECTOR_SIZE)/(MARLIN_EEPROM_SIZE)) -#define EEPROM_ERASE 0xFF -#define SLOT_ADDRESS(sector, slot) (((uint8_t *)SECTOR_START(sector)) + slot * (MARLIN_EEPROM_SIZE)) - -static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; -static bool eeprom_dirty = false; -static int current_slot = 0; - -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { - uint32_t first_nblank_loc, first_nblank_val; - IAP_STATUS_CODE status; - - // discover which slot we are currently using. - __disable_irq(); - status = BlankCheckSector(EEPROM_SECTOR, EEPROM_SECTOR, &first_nblank_loc, &first_nblank_val); - __enable_irq(); - - if (status == CMD_SUCCESS) { - // sector is blank so nothing stored yet - for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE; - current_slot = EEPROM_SLOTS; - } - else { - // current slot is the first non blank one - current_slot = first_nblank_loc / (MARLIN_EEPROM_SIZE); - uint8_t *eeprom_data = SLOT_ADDRESS(EEPROM_SECTOR, current_slot); - // load current settings - for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; - } - eeprom_dirty = false; - - return true; -} - -bool PersistentStore::access_finish() { - if (eeprom_dirty) { - IAP_STATUS_CODE status; - if (--current_slot < 0) { - // all slots have been used, erase everything and start again - __disable_irq(); - status = EraseSector(EEPROM_SECTOR, EEPROM_SECTOR); - __enable_irq(); - - current_slot = EEPROM_SLOTS - 1; - } - - __disable_irq(); - status = CopyRAM2Flash(SLOT_ADDRESS(EEPROM_SECTOR, current_slot), ram_eeprom, IAP_WRITE_4096); - __enable_irq(); - - if (status != CMD_SUCCESS) return false; - eeprom_dirty = false; - } - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - for (size_t i = 0; i < size; i++) ram_eeprom[pos + i] = value[i]; - eeprom_dirty = true; - crc16(crc, value, size); - pos += size; - return false; // return true for any error -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos]; - if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i]; - crc16(crc, buff, size); - pos += size; - return false; // return true for any error -} - -#endif // FLASH_EEPROM_EMULATION -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/eeprom_sdcard.cpp b/src/HAL/LPC1768/eeprom_sdcard.cpp deleted file mode 100644 index 1991d79..0000000 --- a/src/HAL/LPC1768/eeprom_sdcard.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Implementation of EEPROM settings in SD Card - */ - -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SDCARD_EEPROM_EMULATION) - -//#define DEBUG_SD_EEPROM_EMULATION - -#include "../shared/eeprom_api.h" - -#include -#include - -extern uint32_t MSC_Aquire_Lock(); -extern uint32_t MSC_Release_Lock(); - -FATFS fat_fs; -FIL eeprom_file; -bool eeprom_file_open = false; - -#define EEPROM_FILENAME "eeprom.dat" -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM -#endif - -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { - const char eeprom_erase_value = 0xFF; - MSC_Aquire_Lock(); - if (f_mount(&fat_fs, "", 1)) { - MSC_Release_Lock(); - return false; - } - FRESULT res = f_open(&eeprom_file, EEPROM_FILENAME, FA_OPEN_ALWAYS | FA_WRITE | FA_READ); - if (res) MSC_Release_Lock(); - - if (res == FR_OK) { - UINT bytes_written; - FSIZE_t file_size = f_size(&eeprom_file); - f_lseek(&eeprom_file, file_size); - while (file_size < capacity() && res == FR_OK) { - res = f_write(&eeprom_file, &eeprom_erase_value, 1, &bytes_written); - file_size++; - } - } - if (res == FR_OK) { - f_lseek(&eeprom_file, 0); - f_sync(&eeprom_file); - eeprom_file_open = true; - } - return res == FR_OK; -} - -bool PersistentStore::access_finish() { - f_close(&eeprom_file); - f_unmount(""); - MSC_Release_Lock(); - eeprom_file_open = false; - return true; -} - -// This extra chit-chat goes away soon, but is helpful for now -// to see errors that are happening in read_data / write_data -static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) { - #if ENABLED(DEBUG_SD_EEPROM_EMULATION) - FSTR_P const rw_str = write ? F("write") : F("read"); - SERIAL_CHAR(' '); - SERIAL_ECHOF(rw_str); - SERIAL_ECHOLNPGM("_data(", pos, ",", *value, ",", size, ", ...)"); - if (total) { - SERIAL_ECHOPGM(" f_"); - SERIAL_ECHOF(rw_str); - SERIAL_ECHOPGM("()=", s, "\n size=", size, "\n bytes_"); - SERIAL_ECHOLNF(write ? F("written=") : F("read="), total); - } - else - SERIAL_ECHOLNPGM(" f_lseek()=", s); - #endif -} - -// File function return codes for type FRESULT. This goes away soon, but -// is helpful right now to see any errors in read_data and write_data. -// -// 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; - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - if (!eeprom_file_open) return true; - FRESULT s; - UINT bytes_written = 0; - - s = f_lseek(&eeprom_file, pos); - if (s) { - debug_rw(true, pos, value, size, s); - return s; - } - - s = f_write(&eeprom_file, (void*)value, size, &bytes_written); - if (s) { - debug_rw(true, pos, value, size, s, bytes_written); - return s; - } - crc16(crc, value, size); - pos += size; - return bytes_written != size; // return true for any error -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) { - if (!eeprom_file_open) return true; - UINT bytes_read = 0; - FRESULT s; - s = f_lseek(&eeprom_file, pos); - - if (s) { - debug_rw(false, pos, value, size, s); - return true; - } - - if (writing) { - s = f_read(&eeprom_file, (void*)value, size, &bytes_read); - crc16(crc, value, size); - } - else { - uint8_t temp[size]; - s = f_read(&eeprom_file, (void*)temp, size, &bytes_read); - crc16(crc, temp, size); - } - - if (s) { - debug_rw(false, pos, value, size, s, bytes_read); - return true; - } - - pos += size; - return bytes_read != size; // return true for any error -} - -#endif // SDCARD_EEPROM_EMULATION -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/eeprom_wired.cpp b/src/HAL/LPC1768/eeprom_wired.cpp deleted file mode 100644 index 1bbc39d..0000000 --- a/src/HAL/LPC1768/eeprom_wired.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -/** - * PersistentStore for Arduino-style EEPROM interface - * with implementations supplied by the framework. - */ - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x8000 // 32K -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t v = *value; - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - // Read from external EEPROM - const uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/endstop_interrupts.h b/src/HAL/LPC1768/endstop_interrupts.h deleted file mode 100644 index 23bd0cc..0000000 --- a/src/HAL/LPC1768/endstop_interrupts.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - #define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2) - - #if HAS_X_MAX - #if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN) - #error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - #if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN) - #error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - #if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN) - #error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - #if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN) - #error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - #if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN) - #error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN) - #error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - #if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN) - #error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - #if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN) - #error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z3_MAX - #if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN) - #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z3_MAX_PIN); - #endif - #if HAS_Z3_MIN - #if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN) - #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z3_MIN_PIN); - #endif - #if HAS_Z4_MAX - #if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN) - #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z4_MAX_PIN); - #endif - #if HAS_Z4_MIN - #if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN) - #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z4_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN) - #error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." - #endif - _ATTACH(Z_MIN_PROBE_PIN); - #endif - #if HAS_I_MAX - #if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN) - #error "I_MAX_PIN is not INTERRUPT-capable." - #endif - _ATTACH(I_MAX_PIN); - #elif HAS_I_MIN - #if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN) - #error "I_MIN_PIN is not INTERRUPT-capable." - #endif - _ATTACH(I_MIN_PIN); - #endif - #if HAS_J_MAX - #if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN) - #error "J_MAX_PIN is not INTERRUPT-capable." - #endif - _ATTACH(J_MAX_PIN); - #elif HAS_J_MIN - #if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN) - #error "J_MIN_PIN is not INTERRUPT-capable." - #endif - _ATTACH(J_MIN_PIN); - #endif - #if HAS_K_MAX - #if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN) - #error "K_MAX_PIN is not INTERRUPT-capable." - #endif - _ATTACH(K_MAX_PIN); - #elif HAS_K_MIN - #if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN) - #error "K_MIN_PIN is not INTERRUPT-capable." - #endif - _ATTACH(K_MIN_PIN); - #endif -} diff --git a/src/HAL/LPC1768/fast_pwm.cpp b/src/HAL/LPC1768/fast_pwm.cpp deleted file mode 100644 index 6d2b1a9..0000000 --- a/src/HAL/LPC1768/fast_pwm.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" -#include - -void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { - if (!LPC176x::pin_is_valid(pin)) return; - if (LPC176x::pwm_attach_pin(pin)) - LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range -} - -void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { - LPC176x::pwm_set_frequency(pin, f_desired); -} - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/fastio.h b/src/HAL/LPC1768/fastio.h deleted file mode 100644 index c553ffb..0000000 --- a/src/HAL/LPC1768/fastio.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for LPC1768/9 - * Use direct port manipulation to save scads of processor time. - * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. - */ - -/** - * Description: Fast IO functions LPC1768 - * - * For TARGET LPC1768 - */ - -#include "../shared/Marduino.h" - -#define PWM_PIN(P) true // all pins are PWM capable - -#define LPC_PIN(pin) LPC176x::gpio_pin(pin) -#define LPC_GPIO(port) LPC176x::gpio_port(port) - -#define SET_DIR_INPUT(IO) LPC176x::gpio_set_input(IO) -#define SET_DIR_OUTPUT(IO) LPC176x::gpio_set_output(IO) - -#define SET_MODE(IO, mode) pinMode(IO, mode) - -#define WRITE_PIN_SET(IO) LPC176x::gpio_set(IO) -#define WRITE_PIN_CLR(IO) LPC176x::gpio_clear(IO) - -#define READ_PIN(IO) LPC176x::gpio_get(IO) -#define WRITE_PIN(IO,V) LPC176x::gpio_set(IO, V) - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); - * - * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html - */ - -/// Read a pin -#define _READ(IO) READ_PIN(IO) - -/// Write to a pin -#define _WRITE(IO,V) WRITE_PIN(IO,V) - -/// toggle a pin -#define _TOGGLE(IO) _WRITE(IO, !READ(IO)) - -/// set pin as input -#define _SET_INPUT(IO) SET_DIR_INPUT(IO) - -/// set pin as output -#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO) - -/// set pin as input with pullup mode -#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) - -/// set pin as input with pulldown mode -#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT) - -/// check if pin is an input -#define _IS_INPUT(IO) (!LPC176x::gpio_get_dir(IO)) - -/// check if pin is an output -#define _IS_OUTPUT(IO) (LPC176x::gpio_get_dir(IO)) - -/// 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 input with pullup wrapper -#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) -/// set pin as input with pulldown wrapper -#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0) -/// set pin as output wrapper - reads the pin and sets the output to that value -#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0) -// set pin as PWM -#define SET_PWM SET_OUTPUT - -/// check if pin is an input wrapper -#define IS_INPUT(IO) _IS_INPUT(IO) -/// check if pin is an output wrapper -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -// Shorthand -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/src/HAL/LPC1768/inc/Conditionals_LCD.h b/src/HAL/LPC1768/inc/Conditionals_LCD.h deleted file mode 100644 index 32ef908..0000000 --- a/src/HAL/LPC1768/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_FSMC_TFT - #error "Sorry! FSMC TFT displays are not current available for HAL/LPC1768." -#endif diff --git a/src/HAL/LPC1768/inc/Conditionals_adv.h b/src/HAL/LPC1768/inc/Conditionals_adv.h deleted file mode 100644 index 8e7cab1..0000000 --- a/src/HAL/LPC1768/inc/Conditionals_adv.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if DISABLED(NO_SD_HOST_DRIVE) - #define HAS_SD_HOST_DRIVE 1 -#endif diff --git a/src/HAL/LPC1768/inc/Conditionals_post.h b/src/HAL/LPC1768/inc/Conditionals_post.h deleted file mode 100644 index be574a9..0000000 --- a/src/HAL/LPC1768/inc/Conditionals_post.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define FLASH_EEPROM_EMULATION -#elif EITHER(I2C_EEPROM, SPI_EEPROM) - #define USE_SHARED_EEPROM 1 -#endif - -// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785) -// TODO: Which other boards are incompatible? -#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0 - #define PRINTCOUNTER_SYNC 1 -#endif diff --git a/src/HAL/LPC1768/inc/SanityCheck.h b/src/HAL/LPC1768/inc/SanityCheck.h deleted file mode 100644 index 8265d58..0000000 --- a/src/HAL/LPC1768/inc/SanityCheck.h +++ /dev/null @@ -1,276 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if PIO_PLATFORM_VERSION < 1001 - #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically." -#endif -#if PIO_FRAMEWORK_VERSION < 2006 - #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries." -#endif - -/** - * Detect an old pins file by checking for old ADC pins values. - */ -#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && !WITHIN(_CAT(P,_PIN), TERN(LPC1768_IS_SKRV1_3, 0, 2), 3) // Include P0_00 and P0_01 for SKR V1.3 board -#if _OLD_TEMP_PIN(TEMP_BED) - #error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_0) - #error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_1) - #error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_2) - #error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_3) - #error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_4) - #error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_5) - #error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_6) - #error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#elif _OLD_TEMP_PIN(TEMP_7) - #error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." -#endif -#undef _OLD_TEMP_PIN - -/** - * Because PWM hardware channels all share the same frequency, along with the - * fallback software channels, FAST_PWM_FAN is incompatible with Servos. - */ -static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards."); - -#if SPINDLE_LASER_FREQUENCY - static_assert(!NUM_SERVOS, "BLTOUCH and Servos are incompatible with SPINDLE_LASER_FREQUENCY on LPC176x boards."); -#endif - -/** - * Test LPC176x-specific configuration values for errors at compile-time. - */ - -//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) -// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -//#endif - -#if MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF) - #if IS_RRD_FG_SC && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI) - #error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI." - #endif -#endif - -static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported on LPC176x."); - -/** - * Flag any serial port conflicts - * - * Port | TX | RX | - * --- | --- | --- | - * Serial | P0_02 | P0_03 | - * Serial1 | P0_15 | P0_16 | - * Serial2 | P0_10 | P0_11 | - * Serial3 | P0_00 | P0_01 | - */ -#define ANY_TX(N,V...) DO(IS_TX##N,||,V) -#define ANY_RX(N,V...) DO(IS_RX##N,||,V) - -#if USING_HW_SERIAL0 - #define IS_TX0(P) (P == P0_02) - #define IS_RX0(P) (P == P0_03) - #if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI) - #error "Serial port pins (0) conflict with Trinamic SPI pins!" - #elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN)) - #error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!" - #elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN)) - #error "Serial port pins (0) conflict with X/Y axis SPI pins!" - #endif - #undef IS_TX0 - #undef IS_RX0 -#endif - -#if USING_HW_SERIAL1 - #define IS_TX1(P) (P == P0_15) - #define IS_RX1(P) (P == P0_16) - #define _IS_TX1_1 IS_TX1 - #define _IS_RX1_1 IS_RX1 - #if IS_TX1(TMC_SW_SCK) - #error "Serial port pins (1) conflict with other pins!" - #elif HAS_ROTARY_ENCODER - #if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1) - #error "Serial port pins (1) conflict with Encoder Buttons!" - #elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \ - || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN) - #error "Serial port pins (1) conflict with LCD pins!" - #endif - #endif - #undef IS_TX1 - #undef IS_RX1 - #undef _IS_TX1_1 - #undef _IS_RX1_1 -#endif - -#if USING_HW_SERIAL2 - #define IS_TX2(P) (P == P0_10) - #define IS_RX2(P) (P == P0_11) - #define _IS_TX2_1 IS_TX2 - #define _IS_RX2_1 IS_RX2 - #if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN)) - #error "Serial port pins (2) conflict with X2 pins!" - #elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN)) - #error "Serial port pins (2) conflict with Y2 pins!" - #elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN)) - #error "Serial port pins (2) conflict with Z2 pins!" - #elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN)) - #error "Serial port pins (2) conflict with Z3 pins!" - #elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN)) - #error "Serial port pins (2) conflict with Z4 pins!" - #elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) - #error "Serial port pins (2) conflict with other pins!" - #elif Y_HOME_TO_MIN && IS_TX2(Y_STOP_PIN) - #error "Serial port pins (2) conflict with Y endstop pin!" - #elif USES_Z_MIN_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN) - #error "Serial port pins (2) conflict with probe pin!" - #elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) - #error "Serial port pins (2) conflict with X/Y stepper pins!" - #elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN))) - #error "Serial port pins (2) conflict with E1 stepper pins!" - #elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN) - #error "Serial port pins (2) conflict with E stepper pins!" - #endif - #undef IS_TX2 - #undef IS_RX2 - #undef _IS_TX2_1 - #undef _IS_RX2_1 -#endif - -#if USING_HW_SERIAL3 - #define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00) - #define PIN_IS_RX3(P) (P##_PIN == P0_01) - #if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX) - #error "Serial port pins (3) conflict with X endstop pins!" - #elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX) - #error "Serial port pins (3) conflict with X/Y axis UART pins!" - #elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP) - #error "Serial port pins (3) conflict with X2 pins!" - #elif PIN_IS_TX3(Y2_DIR) || PIN_IS_RX3(Y2_STEP) - #error "Serial port pins (3) conflict with Y2 pins!" - #elif PIN_IS_TX3(Z2_DIR) || PIN_IS_RX3(Z2_STEP) - #error "Serial port pins (3) conflict with Z2 pins!" - #elif PIN_IS_TX3(Z3_DIR) || PIN_IS_RX3(Z3_STEP) - #error "Serial port pins (3) conflict with Z3 pins!" - #elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP) - #error "Serial port pins (3) conflict with Z4 pins!" - #elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP)) - #error "Serial port pins (3) conflict with E1 pins!" - #endif - #undef PIN_IS_TX3 - #undef PIN_IS_RX3 -#endif - -#undef ANY_TX -#undef ANY_RX - -// -// Flag any i2c pin conflicts -// -#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM) - #define USEDI2CDEV_M 1 // /Wire.cpp - - #if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1) - #define PIN_IS_SDA0(P) (P##_PIN == P0_27) - #define IS_SCL0(P) (P == P0_28) - #if ENABLED(SDSUPPORT) && PIN_IS_SDA0(SD_DETECT) - #error "SDA0 overlaps with SD_DETECT_PIN!" - #elif PIN_IS_SDA0(E0_AUTO_FAN) - #error "SDA0 overlaps with E0_AUTO_FAN_PIN!" - #elif PIN_IS_SDA0(BEEPER) - #error "SDA0 overlaps with BEEPER_PIN!" - #elif IS_SCL0(BTN_ENC) - #error "SCL0 overlaps with Encoder Button!" - #elif IS_SCL0(SD_SS_PIN) - #error "SCL0 overlaps with SD_SS_PIN!" - #elif IS_SCL0(LCD_SDSS) - #error "SCL0 overlaps with LCD_SDSS!" - #endif - #undef PIN_IS_SDA0 - #undef IS_SCL0 - #elif USEDI2CDEV_M == 1 // P0_00 [D20] (SCA) ............ P0_01 [D21] (SCL) - #define PIN_IS_SDA1(P) (PIN_EXISTS(P) && P##_PIN == P0_00) - #define PIN_IS_SCL1(P) (P##_PIN == P0_01) - #if PIN_IS_SDA1(X_MIN) || PIN_IS_SCL1(X_MAX) - #error "One or more i2c (1) pins overlaps with X endstop pins! Disable i2c peripherals." - #elif PIN_IS_SDA1(X2_DIR) || PIN_IS_SCL1(X2_STEP) - #error "One or more i2c (1) pins overlaps with X2 pins! Disable i2c peripherals." - #elif PIN_IS_SDA1(Y2_DIR) || PIN_IS_SCL1(Y2_STEP) - #error "One or more i2c (1) pins overlaps with Y2 pins! Disable i2c peripherals." - #elif PIN_IS_SDA1(Z2_DIR) || PIN_IS_SCL1(Z2_STEP) - #error "One or more i2c (1) pins overlaps with Z2 pins! Disable i2c peripherals." - #elif PIN_IS_SDA1(Z3_DIR) || PIN_IS_SCL1(Z3_STEP) - #error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals." - #elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP) - #error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals." - #elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP)) - #error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals." - #endif - #undef PIN_IS_SDA1 - #undef PIN_IS_SCL1 - #elif USEDI2CDEV_M == 2 // P0_10 [D38] (X_ENABLE_PIN) ... P0_11 [D55] (X_DIR_PIN) - #define PIN_IS_SDA2(P) (P##_PIN == P0_10) - #define PIN_IS_SCL2(P) (P##_PIN == P0_11) - #if PIN_IS_SDA2(Y_STOP) - #error "i2c SDA2 overlaps with Y endstop pin!" - #elif USES_Z_MIN_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE) - #error "i2c SDA2 overlaps with Z probe pin!" - #elif PIN_IS_SDA2(X_ENABLE) || PIN_IS_SDA2(Y_ENABLE) - #error "i2c SDA2 overlaps with X/Y ENABLE pin!" - #elif AXIS_HAS_SPI(X) && PIN_IS_SDA2(X_CS) - #error "i2c SDA2 overlaps with X CS pin!" - #elif PIN_IS_SDA2(X2_ENABLE) - #error "i2c SDA2 overlaps with X2 enable pin! Disable i2c peripherals." - #elif PIN_IS_SDA2(Y2_ENABLE) - #error "i2c SDA2 overlaps with Y2 enable pin! Disable i2c peripherals." - #elif PIN_IS_SDA2(Z2_ENABLE) - #error "i2c SDA2 overlaps with Z2 enable pin! Disable i2c peripherals." - #elif PIN_IS_SDA2(Z3_ENABLE) - #error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals." - #elif PIN_IS_SDA2(Z4_ENABLE) - #error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals." - #elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE) - #error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals." - #elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS) - #error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals." - #elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR)) - #error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals." - #elif PIN_IS_SDA2(X_DIR) || PIN_IS_SDA2(Y_DIR) - #error "One or more i2c pins overlaps with X/Y DIR pin! Disable i2c peripherals." - #endif - #undef PIN_IS_SDA2 - #undef PIN_IS_SCL2 - #endif - - #undef USEDI2CDEV_M -#endif - -#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x." -#elif ENABLED(SERIAL_STATS_DROPPED_RX) - #error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x." -#endif diff --git a/src/HAL/LPC1768/include/SPI.h b/src/HAL/LPC1768/include/SPI.h deleted file mode 100644 index 24f4759..0000000 --- a/src/HAL/LPC1768/include/SPI.h +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../shared/HAL_SPI.h" - -#include -#include -#include - -//#define MSBFIRST 1 - -#define SPI_MODE0 0 -#define SPI_MODE1 1 -#define SPI_MODE2 2 -#define SPI_MODE3 3 - -#define DATA_SIZE_8BIT SSP_DATABIT_8 -#define DATA_SIZE_16BIT SSP_DATABIT_16 - -#define SPI_CLOCK_MAX_TFT 30000000UL -#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED -#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED -#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED -#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED -#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 -#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 -#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h - -#define SPI_CLOCK_MAX SPI_CLOCK_DIV2 - -#define BOARD_NR_SPI 2 - -//#define BOARD_SPI1_NSS_PIN PA4 ?! -#define BOARD_SPI1_SCK_PIN P0_15 -#define BOARD_SPI1_MISO_PIN P0_17 -#define BOARD_SPI1_MOSI_PIN P0_18 - -//#define BOARD_SPI2_NSS_PIN PB12 ?! -#define BOARD_SPI2_SCK_PIN P0_07 -#define BOARD_SPI2_MISO_PIN P0_08 -#define BOARD_SPI2_MOSI_PIN P0_09 - -class SPISettings { -public: - SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) { - init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT); - } - SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { - if (__builtin_constant_p(inClock)) - init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); - else - init_MightInline(inClock, inBitOrder, inDataMode, inDataSize); - } - SPISettings() { - init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); - } - - //uint32_t spiRate() const { return spi_speed; } - - static uint32_t spiRate2Clock(uint32_t spiRate) { - uint32_t Marlin_speed[7]; // CPSR is always 2 - Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED - Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED - Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED - Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED - Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 - Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 - Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h - return Marlin_speed[spiRate > 6 ? 6 : spiRate]; - } - -private: - void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { - init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); - } - void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) { - clock = inClock; - bitOrder = inBitOrder; - dataMode = inDataMode; - dataSize = inDataSize; - } - - //uint32_t spi_speed; - uint32_t clock; - uint32_t dataSize; - //uint32_t clockDivider; - uint8_t bitOrder; - uint8_t dataMode; - LPC_SSP_TypeDef *spi_d; - - friend class SPIClass; -}; - -/** - * @brief Wirish SPI interface. - * - * This is the same interface is available across HAL - * - * This implementation uses software slave management, so the caller - * is responsible for controlling the slave select line. - */ -class SPIClass { -public: - /** - * @param spiPortNumber Number of the SPI port to manage. - */ - SPIClass(uint8_t spiPortNumber); - - /** - * Init using pins - */ - SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1); - - /** - * Select and configure the current selected SPI device to use - */ - void begin(); - - /** - * Disable the current SPI device - */ - void end(); - - void beginTransaction(const SPISettings&); - void endTransaction() {} - - // Transfer using 1 "Data Size" - uint8_t transfer(uint16_t data); - // Transfer 2 bytes in 8 bit mode - uint16_t transfer16(uint16_t data); - - void send(uint8_t data); - - uint16_t read(); - void read(uint8_t *buf, uint32_t len); - - void dmaSend(void *buf, uint16_t length, bool minc); - - /** - * @brief Sets the number of the SPI peripheral to be used by - * this HardwareSPI instance. - * - * @param spi_num Number of the SPI port. 1-2 in low density devices - * or 1-3 in high density devices. - */ - void setModule(uint8_t device); - - void setClock(uint32_t clock); - void setBitOrder(uint8_t bitOrder); - void setDataMode(uint8_t dataMode); - void setDataSize(uint32_t ds); - - inline uint32_t getDataSize() { return _currentSetting->dataSize; } - -private: - SPISettings _settings[BOARD_NR_SPI]; - SPISettings *_currentSetting; - - void updateSettings(); -}; - -extern SPIClass SPI; diff --git a/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c b/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c deleted file mode 100644 index c489c16..0000000 --- a/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * digipot_mcp4451_I2C_routines.c - * Adapted from https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if ENABLED(DIGIPOT_MCP4451) && MB(MKS_SBASE) - -#ifdef __cplusplus - extern "C" { -#endif - -#include "digipot_mcp4451_I2C_routines.h" - -uint8_t digipot_mcp4451_start(uint8_t sla) { // send slave address and write bit - // Sometimes TX data ACK or NAK status is returned. That mean the start state didn't - // happen which means only the value of the slave address was send. Keep looping until - // the slave address and write bit are actually sent. - do { - _I2C_Stop(I2CDEV_M); // output stop state on I2C bus - _I2C_Start(I2CDEV_M); // output start state on I2C bus - while ((I2C_status != I2C_I2STAT_M_TX_START) - && (I2C_status != I2C_I2STAT_M_TX_RESTART) - && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted - - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address - LPC_I2C1->I2DAT = (sla << 1) & I2C_I2DAT_BITMASK; // transmit slave address & write bit - LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; - while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK) - && (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)) { /* wait for slaw to finish */ } - } while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK)); - return 1; -} - -uint8_t digipot_mcp4451_send_byte(uint8_t data) { - LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data - LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; - while (I2C_status != I2C_I2STAT_M_TX_DAT_ACK && I2C_status != I2C_I2STAT_M_TX_DAT_NACK); // wait for xmit to finish - return 1; -} - -#ifdef __cplusplus - } -#endif - -#endif // DIGIPOT_MCP4451 && MKS_SBASE -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h b/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h deleted file mode 100644 index 9b6c62b..0000000 --- a/src/HAL/LPC1768/include/digipot_mcp4451_I2C_routines.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * digipot_mcp4451_I2C_routines.h - * Adapted from https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html - */ - -#ifdef __cplusplus - extern "C" { -#endif - -#include -#include -#include -#include "i2c_util.h" - -uint8_t digipot_mcp4451_start(uint8_t sla); -uint8_t digipot_mcp4451_send_byte(uint8_t data); - -#ifdef __cplusplus - } -#endif diff --git a/src/HAL/LPC1768/include/i2c_util.c b/src/HAL/LPC1768/include/i2c_util.c deleted file mode 100644 index 4e24f23..0000000 --- a/src/HAL/LPC1768/include/i2c_util.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL_LPC1768/include/i2c_util.c - */ - -#ifdef TARGET_LPC1768 - -#include "i2c_util.h" - -#define U8G_I2C_OPT_FAST 16 // from u8g.h - -#ifdef __cplusplus - extern "C" { -#endif - -void configure_i2c(const uint8_t clock_option) { - /** - * Init I2C pin connect - */ - PINSEL_CFG_Type PinCfg; - PinCfg.OpenDrain = 0; - PinCfg.Pinmode = 0; - PinCfg.Portnum = 0; - #if I2C_MASTER_ID == 0 - PinCfg.Funcnum = 1; - PinCfg.Pinnum = 27; // SDA0 / D57 AUX-1 ... SCL0 / D58 AUX-1 - #elif I2C_MASTER_ID == 1 - PinCfg.Funcnum = 3; - PinCfg.Pinnum = 0; // SDA1 / D20 SCA ... SCL1 / D21 SCL - #elif I2C_MASTER_ID == 2 - PinCfg.Funcnum = 2; - PinCfg.Pinnum = 10; // SDA2 / D38 X_ENABLE_PIN ... SCL2 / D55 X_DIR_PIN - #endif - PINSEL_ConfigPin(&PinCfg); - PinCfg.Pinnum += 1; - PINSEL_ConfigPin(&PinCfg); - - // Initialize I2C peripheral - I2C_Init(I2CDEV_M, (clock_option & U8G_I2C_OPT_FAST) ? 400000: 100000); // LCD data rates - - // Enable Master I2C operation - I2C_Cmd(I2CDEV_M, I2C_MASTER_MODE, ENABLE); -} - -////////////////////////////////////////////////////////////////////////////////////// -// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to -// to the lpc17xx_i2c.c routines so had to copy them into this file & rename them. - -uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx) { - // Reset STA, STO, SI - I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC; - - // Enter to Master Transmitter mode - I2Cx->I2CONSET = I2C_I2CONSET_STA; - - // Wait for complete - while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); - I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; - return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); -} - -void _I2C_Stop(LPC_I2C_TypeDef *I2Cx) { - /* Make sure start bit is not active */ - if (I2Cx->I2CONSET & I2C_I2CONSET_STA) - I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; - - I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA; - I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; -} - -#ifdef __cplusplus - } -#endif - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/include/i2c_util.h b/src/HAL/LPC1768/include/i2c_util.h deleted file mode 100644 index 1f1c19f..0000000 --- a/src/HAL/LPC1768/include/i2c_util.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL_LPC1768/include/i2c_util.h - */ - -#include "../../../inc/MarlinConfigPre.h" - -#ifndef I2C_MASTER_ID - #define I2C_MASTER_ID 1 -#endif - -#if I2C_MASTER_ID == 0 - #define I2CDEV_M LPC_I2C0 -#elif I2C_MASTER_ID == 1 - #define I2CDEV_M LPC_I2C1 -#elif I2C_MASTER_ID == 2 - #define I2CDEV_M LPC_I2C2 -#else - #error "Master I2C device not defined!" -#endif - -#include -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -void configure_i2c(const uint8_t clock_option); - -uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx); -void _I2C_Stop(LPC_I2C_TypeDef *I2Cx); - -#define I2C_status (LPC_I2C1->I2STAT & I2C_STAT_CODE_BITMASK) - -#ifdef __cplusplus - } -#endif diff --git a/src/HAL/LPC1768/main.cpp b/src/HAL/LPC1768/main.cpp deleted file mode 100644 index 419c997..0000000 --- a/src/HAL/LPC1768/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../inc/MarlinConfig.h" -#include "../../core/millis_t.h" - -#include "../../sd/cardreader.h" - -extern uint32_t MSC_SD_Init(uint8_t pdrv); - -extern "C" { - #include - extern "C" int isLPC1769(); - extern "C" void disk_timerproc(); -} - -void SysTick_Callback() { disk_timerproc(); } - -TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial()); - -void MarlinHAL::init() { - - // Init LEDs - #if PIN_EXISTS(LED) - SET_DIR_OUTPUT(LED_PIN); - WRITE_PIN_CLR(LED_PIN); - #if PIN_EXISTS(LED2) - SET_DIR_OUTPUT(LED2_PIN); - WRITE_PIN_CLR(LED2_PIN); - #if PIN_EXISTS(LED3) - SET_DIR_OUTPUT(LED3_PIN); - WRITE_PIN_CLR(LED3_PIN); - #if PIN_EXISTS(LED4) - SET_DIR_OUTPUT(LED4_PIN); - WRITE_PIN_CLR(LED4_PIN); - #endif - #endif - #endif - - // Flash status LED 3 times to indicate Marlin has started booting - LOOP_L_N(i, 6) { - TOGGLE(LED_PIN); - delay(100); - } - #endif - - // Init Servo Pins - #define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW) - #if HAS_SERVO_0 - INIT_SERVO(0); - #endif - #if HAS_SERVO_1 - INIT_SERVO(1); - #endif - #if HAS_SERVO_2 - INIT_SERVO(2); - #endif - #if HAS_SERVO_3 - INIT_SERVO(3); - #endif - - //debug_frmwrk_init(); - //_DBG("\n\nDebug running\n"); - // Initialize the SD card chip select pins as soon as possible - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - - #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN - OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); - #endif - - #ifdef LPC1768_ENABLE_CLKOUT_12M - /** - * CLKOUTCFG register - * bit 8 (CLKOUT_EN) = enables CLKOUT signal. Disabled for now to prevent glitch when enabling GPIO. - * bits 7:4 (CLKOUTDIV) = set to 0 for divider setting of /1 - * bits 3:0 (CLKOUTSEL) = set to 1 to select main crystal oscillator as CLKOUT source - */ - LPC_SC->CLKOUTCFG = (0<<8)|(0<<4)|(1<<0); - // set P1.27 pin to function 01 (CLKOUT) - PINSEL_CFG_Type PinCfg; - PinCfg.Portnum = 1; - PinCfg.Pinnum = 27; - PinCfg.Funcnum = 1; // function 01 (CLKOUT) - PinCfg.OpenDrain = 0; // not open drain - PinCfg.Pinmode = 2; // no pull-up/pull-down - PINSEL_ConfigPin(&PinCfg); - // now set CLKOUT_EN bit - SBI(LPC_SC->CLKOUTCFG, 8); - #endif - - USB_Init(); // USB Initialization - USB_Connect(false); // USB clear connection - delay(1000); // Give OS time to notice - USB_Connect(true); - - TERN_(HAS_SD_HOST_DRIVE, MSC_SD_Init(0)); // Enable USB SD card access - - const millis_t usb_timeout = millis() + 2000; - while (!USB_Configuration && PENDING(millis(), usb_timeout)) { - delay(50); - idletask(); - #if PIN_EXISTS(LED) - TOGGLE(LED_PIN); // Flash quickly during USB initialization - #endif - } - - HAL_timer_init(); - - TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler -} - -// HAL idle task -void MarlinHAL::idletask() { - #if HAS_SHARED_MEDIA - // If Marlin is using the SD card we need to lock it to prevent access from - // a PC via USB. - // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but - // this will not reliably detect delete operations. To be safe we will lock - // the disk if Marlin has it mounted. Unfortunately there is currently no way - // to unmount the disk from the LCD menu. - // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) - if (card.isMounted()) - MSC_Aquire_Lock(); - else - MSC_Release_Lock(); - #endif - // Perform USB stack housekeeping - MSC_RunDeferredCommands(); -} - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/pinsDebug.h b/src/HAL/LPC1768/pinsDebug.h deleted file mode 100644 index a2f5c12..0000000 --- a/src/HAL/LPC1768/pinsDebug.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Support routines for LPC1768 - */ - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define pwm_details(pin) pin = pin // do nothing // print PWM details -#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin. -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PORT(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin - -// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities -#ifndef M43_NEVER_TOUCH - #define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins -#endif - -bool GET_PINMODE(const pin_t pin) { - if (!LPC176x::pin_is_valid(pin) || LPC176x::pin_adc_enabled(pin)) // found an invalid pin or active analog pin - return false; - - return LPC176x::gpio_direction(pin); -} - -#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) diff --git a/src/HAL/LPC1768/spi_pins.h b/src/HAL/LPC1768/spi_pins.h deleted file mode 100644 index e7d7747..0000000 --- a/src/HAL/LPC1768/spi_pins.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/macros.h" - -#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN) - #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently - // needed due to the speed and mode required for communicating with each device being different. - // This requirement can be removed if the SPI access to these devices is updated to use - // spiBeginTransaction. -#endif - -/** onboard SD card */ -//#define SD_SCK_PIN P0_07 -//#define SD_MISO_PIN P0_08 -//#define SD_MOSI_PIN P0_09 -//#define SD_SS_PIN P0_06 -/** external */ -#ifndef SD_SCK_PIN - #define SD_SCK_PIN P0_15 -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN P0_17 -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN P0_18 -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN P1_23 -#endif -#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h - #undef SDSS - #define SDSS SD_SS_PIN -#endif diff --git a/src/HAL/LPC1768/tft/tft_spi.cpp b/src/HAL/LPC1768/tft/tft_spi.cpp deleted file mode 100644 index a9847b2..0000000 --- a/src/HAL/LPC1768/tft/tft_spi.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_SPI_TFT - -#include "tft_spi.h" - -SPIClass TFT_SPI::SPIx(1); - -void TFT_SPI::Init() { - #if PIN_EXISTS(TFT_RESET) - OUT_WRITE(TFT_RESET_PIN, HIGH); - delay(100); - #endif - - #if PIN_EXISTS(TFT_BACKLIGHT) - OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); - #endif - - SET_OUTPUT(TFT_DC_PIN); - SET_OUTPUT(TFT_CS_PIN); - WRITE(TFT_DC_PIN, HIGH); - WRITE(TFT_CS_PIN, HIGH); - - /** - * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz - * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 - * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 - */ - #if 0 - #if SPI_DEVICE == 1 - #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 - #else - #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 - #endif - uint8_t clock; - uint8_t spiRate = SPI_FULL_SPEED; - switch (spiRate) { - case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break; - case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; - case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; - case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; - case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; - case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; - default: clock = SPI_CLOCK_DIV2; // Default from the SPI library - } - #endif - - #if TFT_MISO_PIN == BOARD_SPI1_MISO_PIN - SPIx.setModule(1); - #elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN - SPIx.setModule(2); - #endif - SPIx.setClock(SPI_CLOCK_MAX_TFT); - SPIx.setBitOrder(MSBFIRST); - SPIx.setDataMode(SPI_MODE0); -} - -void TFT_SPI::DataTransferBegin(uint16_t DataSize) { - SPIx.setDataSize(DataSize); - SPIx.begin(); - WRITE(TFT_CS_PIN, LOW); -} - -uint32_t TFT_SPI::GetID() { - uint32_t id; - id = ReadID(LCD_READ_ID); - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) - id = ReadID(LCD_READ_ID4); - return id; -} - -uint32_t TFT_SPI::ReadID(uint16_t Reg) { - uint32_t data = 0; - - #if PIN_EXISTS(TFT_MISO) - uint8_t d = 0; - SPIx.setDataSize(DATASIZE_8BIT); - SPIx.setClock(SPI_CLOCK_DIV64); - SPIx.begin(); - WRITE(TFT_CS_PIN, LOW); - WriteReg(Reg); - - LOOP_L_N(i, 4) { - SPIx.read((uint8_t*)&d, 1); - data = (data << 8) | d; - } - - DataTransferEnd(); - SPIx.setClock(SPI_CLOCK_MAX_TFT); - #endif - - return data >> 7; -} - -bool TFT_SPI::isBusy() { return false; } - -void TFT_SPI::Abort() { DataTransferEnd(); } - -void TFT_SPI::Transmit(uint16_t Data) { SPIx.transfer(Data); } - -void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - DataTransferBegin(DATASIZE_16BIT); - WRITE(TFT_DC_PIN, HIGH); - SPIx.dmaSend(Data, Count, MemoryIncrease); - DataTransferEnd(); -} - -#endif // HAS_SPI_TFT diff --git a/src/HAL/LPC1768/tft/tft_spi.h b/src/HAL/LPC1768/tft/tft_spi.h deleted file mode 100644 index 4753fdb..0000000 --- a/src/HAL/LPC1768/tft/tft_spi.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#include -#include -// #include - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#define DATASIZE_8BIT SSP_DATABIT_8 -#define DATASIZE_16BIT SSP_DATABIT_16 -#define TFT_IO_DRIVER TFT_SPI - -#define DMA_MINC_ENABLE 1 -#define DMA_MINC_DISABLE 0 - -class TFT_SPI { -private: - static uint32_t ReadID(uint16_t Reg); - static void Transmit(uint16_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - -public: - static SPIClass SPIx; - - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort(); - - static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); - static void DataTransferEnd() { OUT_WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; - static void DataTransferAbort(); - - static void WriteData(uint16_t Data) { Transmit(Data); } - static void WriteReg(uint16_t Reg) { OUT_WRITE(TFT_A0_PIN, LOW); Transmit(Reg); OUT_WRITE(TFT_A0_PIN, HIGH); } - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } - // static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - //LPC dma can only write 0xFFF bytes at once. - #define MAX_DMA_SIZE (0xFFF - 1) - while (Count > 0) { - TransmitDMA(DMA_MINC_DISABLE, &Data, Count > MAX_DMA_SIZE ? MAX_DMA_SIZE : Count); - Count = Count > MAX_DMA_SIZE ? Count - MAX_DMA_SIZE : 0; - } - #undef MAX_DMA_SIZE - } -}; diff --git a/src/HAL/LPC1768/tft/xpt2046.cpp b/src/HAL/LPC1768/tft/xpt2046.cpp deleted file mode 100644 index 9c1e158..0000000 --- a/src/HAL/LPC1768/tft/xpt2046.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS - -#include "xpt2046.h" -#include - -uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - #include - - SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE); - - static void touch_spi_init(uint8_t spiRate) { - XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE); - XPT2046::SPIx.setClock(SPI_CLOCK_DIV128); - XPT2046::SPIx.setBitOrder(MSBFIRST); - XPT2046::SPIx.setDataMode(SPI_MODE0); - XPT2046::SPIx.setDataSize(DATA_SIZE_8BIT); - } -#endif - -void XPT2046::Init() { - SET_INPUT(TOUCH_MISO_PIN); - SET_OUTPUT(TOUCH_MOSI_PIN); - SET_OUTPUT(TOUCH_SCK_PIN); - OUT_WRITE(TOUCH_CS_PIN, HIGH); - - #if PIN_EXISTS(TOUCH_INT) - // Optional Pendrive interrupt pin - SET_INPUT(TOUCH_INT_PIN); - #endif - - TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6)); - - // Read once to enable pendrive status pin - getRawData(XPT2046_X); -} - -bool XPT2046::isTouched() { - return isBusy() ? false : ( - #if PIN_EXISTS(TOUCH_INT) - READ(TOUCH_INT_PIN) != HIGH - #else - getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD - #endif - ); -} - -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; - *x = getRawData(XPT2046_X); - *y = getRawData(XPT2046_Y); - return isTouched(); -} - -uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { - uint16_t data[3]; - - DataTransferBegin(); - TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin()); - - for (uint16_t i = 0; i < 3 ; i++) { - IO(coordinate); - data[i] = (IO() << 4) | (IO() >> 4); - } - - TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end()); - DataTransferEnd(); - - uint16_t delta01 = delta(data[0], data[1]), - delta02 = delta(data[0], data[2]), - delta12 = delta(data[1], data[2]); - - if (delta01 > delta02 || delta01 > delta12) - data[delta02 > delta12 ? 0 : 1] = data[2]; - - return (data[0] + data[1]) >> 1; -} - -uint16_t XPT2046::IO(uint16_t data) { - return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); -} - -extern uint8_t spiTransfer(uint8_t b); - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - uint16_t XPT2046::HardwareIO(uint16_t data) { - return SPIx.transfer(data & 0xFF); - } -#endif - -uint16_t XPT2046::SoftwareIO(uint16_t data) { - uint16_t result = 0; - - for (uint8_t j = 0x80; j; j >>= 1) { - WRITE(TOUCH_SCK_PIN, LOW); - WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); - if (READ(TOUCH_MISO_PIN)) result |= j; - WRITE(TOUCH_SCK_PIN, HIGH); - } - WRITE(TOUCH_SCK_PIN, LOW); - - return result; -} - -#endif // HAS_TFT_XPT2046 diff --git a/src/HAL/LPC1768/tft/xpt2046.h b/src/HAL/LPC1768/tft/xpt2046.h deleted file mode 100644 index 7c456cf..0000000 --- a/src/HAL/LPC1768/tft/xpt2046.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - #include -#endif - -#ifndef TOUCH_MISO_PIN - #define TOUCH_MISO_PIN SD_MISO_PIN -#endif -#ifndef TOUCH_MOSI_PIN - #define TOUCH_MOSI_PIN SD_MOSI_PIN -#endif -#ifndef TOUCH_SCK_PIN - #define TOUCH_SCK_PIN SD_SCK_PIN -#endif -#ifndef TOUCH_CS_PIN - #define TOUCH_CS_PIN SD_SS_PIN -#endif -#ifndef TOUCH_INT_PIN - #define TOUCH_INT_PIN -1 -#endif - -#define XPT2046_DFR_MODE 0x00 -#define XPT2046_SER_MODE 0x04 -#define XPT2046_CONTROL 0x80 - -enum XPTCoordinate : uint8_t { - XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, -}; - -#ifndef XPT2046_Z1_THRESHOLD - #define XPT2046_Z1_THRESHOLD 10 -#endif - -class XPT2046 { -private: - static bool isBusy() { return false; } - - static uint16_t getRawData(const XPTCoordinate coordinate); - static bool isTouched(); - - static void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); }; - static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static uint16_t HardwareIO(uint16_t data); - #endif - static uint16_t SoftwareIO(uint16_t data); - static uint16_t IO(uint16_t data = 0); - -public: - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static SPIClass SPIx; - #endif - - static void Init(); - static bool getRawPoint(int16_t *x, int16_t *y); -}; diff --git a/src/HAL/LPC1768/timers.cpp b/src/HAL/LPC1768/timers.cpp deleted file mode 100644 index bbb13f8..0000000 --- a/src/HAL/LPC1768/timers.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Description: - * - * Timers for LPC1768 - */ - -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfig.h" - -void HAL_timer_init() { - SBI(LPC_SC->PCONP, SBIT_TIMER0); // Power ON Timer 0 - LPC_TIM0->PR = (HAL_TIMER_RATE) / (STEPPER_TIMER_RATE) - 1; // Use prescaler to set frequency if needed - - SBI(LPC_SC->PCONP, SBIT_TIMER1); // Power ON Timer 1 - LPC_TIM1->PR = (HAL_TIMER_RATE) / 1000000 - 1; -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - switch (timer_num) { - case MF_TIMER_STEP: - LPC_TIM0->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them - LPC_TIM0->MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency - LPC_TIM0->TCR = _BV(SBIT_CNTEN); // Counter Enable - - NVIC_SetPriority(TIMER0_IRQn, NVIC_EncodePriority(0, 1, 0)); - NVIC_EnableIRQ(TIMER0_IRQn); - break; - - case MF_TIMER_TEMP: - LPC_TIM1->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them - LPC_TIM1->MR0 = uint32_t(TEMP_TIMER_RATE) / frequency; - LPC_TIM1->TCR = _BV(SBIT_CNTEN); // Counter Enable - - NVIC_SetPriority(TIMER1_IRQn, NVIC_EncodePriority(0, 2, 0)); - NVIC_EnableIRQ(TIMER1_IRQn); - break; - - default: break; - } -} - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/timers.h b/src/HAL/LPC1768/timers.h deleted file mode 100644 index c6d7bc6..0000000 --- a/src/HAL/LPC1768/timers.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL For LPC1768 - */ - -#include - -#include "../../core/macros.h" - -#define SBIT_TIMER0 1 -#define SBIT_TIMER1 2 - -#define SBIT_CNTEN 0 - -#define SBIT_MR0I 0 // Timer 0 Interrupt when TC matches MR0 -#define SBIT_MR0R 1 // Timer 0 Reset TC on Match -#define SBIT_MR0S 2 // Timer 0 Stop TC and PC on Match -#define SBIT_MR1I 3 -#define SBIT_MR1R 4 -#define SBIT_MR1S 5 -#define SBIT_MR2I 6 -#define SBIT_MR2R 7 -#define SBIT_MR2S 8 -#define SBIT_MR3I 9 -#define SBIT_MR3R 10 -#define SBIT_MR3S 11 - -// ------------------------ -// Defines -// ------------------------ - -#define _HAL_TIMER(T) _CAT(LPC_TIM, T) -#define _HAL_TIMER_IRQ(T) TIMER##T##_IRQn -#define __HAL_TIMER_ISR(T) extern "C" void TIMER##T##_IRQHandler() -#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T) - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif -#ifndef MF_TIMER_PWM - #define MF_TIMER_PWM 3 // Timer Index for PWM -#endif - -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP) -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP) -#endif - -// Timer references by index -#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP) -#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP) - -// ------------------------ -// Public functions -// ------------------------ -void HAL_timer_init(); -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - switch (timer_num) { - case MF_TIMER_STEP: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0 - case MF_TIMER_TEMP: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0 - } -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0 - case MF_TIMER_TEMP: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0 - } - return 0; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return STEP_TIMER_PTR->TC; // Stepper Timer Count - case MF_TIMER_TEMP: return TEMP_TIMER_PTR->TC; // Temp Timer Count - } - return 0; -} - -FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler - case MF_TIMER_TEMP: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler - } -} - -FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler - case MF_TIMER_TEMP: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler - } - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); -} - -// This function is missing from CMSIS -FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) { - return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F); -} - -FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not - case MF_TIMER_TEMP: return NVIC_GetEnableIRQ(TIMER1_IRQn); // Check if interrupt is enabled or not - } - return false; -} - -FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break; - case MF_TIMER_TEMP: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break; - } -} - -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp b/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp deleted file mode 100644 index e714c3c..0000000 --- a/src/HAL/LPC1768/u8g/LCD_I2C_routines.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// adapted from I2C/master/master.c example -// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html - -#ifdef TARGET_LPC1768 - -#include "../include/i2c_util.h" -#include "../../../core/millis_t.h" - -extern int millis(); - -#ifdef __cplusplus - extern "C" { -#endif - -////////////////////////////////////////////////////////////////////////////////////// - -#define I2CDEV_S_ADDR 0x78 // From SSD1306 (actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write) - -// Send slave address and write bit -uint8_t u8g_i2c_start(const uint8_t sla) { - // Sometimes TX data ACK or NAK status is returned. That mean the start state didn't - // happen which means only the value of the slave address was send. Keep looping until - // the slave address and write bit are actually sent. - do{ - _I2C_Stop(I2CDEV_M); // output stop state on I2C bus - _I2C_Start(I2CDEV_M); // output start state on I2C bus - while ((I2C_status != I2C_I2STAT_M_TX_START) - && (I2C_status != I2C_I2STAT_M_TX_RESTART) - && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted - - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address - LPC_I2C1->I2DAT = I2CDEV_S_ADDR & I2C_I2DAT_BITMASK; // transmit slave address & write bit - LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; - while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK) - && (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) - && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for slaw to finish - }while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK)); - return 1; -} - -void u8g_i2c_init(const uint8_t clock_option) { - configure_i2c(clock_option); - u8g_i2c_start(0); // Send slave address and write bit -} - -uint8_t u8g_i2c_send_byte(uint8_t data) { - #define I2C_TIMEOUT 3 - LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data - LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; - LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; - const millis_t timeout = millis() + I2C_TIMEOUT; - while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(millis(), timeout)); // wait for xmit to finish - // had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens - return 1; -} - -void u8g_i2c_stop() { -} - -#ifdef __cplusplus - } -#endif - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/LCD_I2C_routines.h b/src/HAL/LPC1768/u8g/LCD_I2C_routines.h deleted file mode 100644 index 2d976c9..0000000 --- a/src/HAL/LPC1768/u8g/LCD_I2C_routines.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void u8g_i2c_init(const uint8_t clock_options); -//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos); -uint8_t u8g_i2c_start(uint8_t sla); -uint8_t u8g_i2c_send_byte(uint8_t data); -void u8g_i2c_stop(); diff --git a/src/HAL/LPC1768/u8g/LCD_defines.h b/src/HAL/LPC1768/u8g/LCD_defines.h deleted file mode 100644 index d226003..0000000 --- a/src/HAL/LPC1768/u8g/LCD_defines.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * LPC1768 LCD-specific defines - */ - -// The following are optional depending on the platform. - -// definitions of HAL specific com and device drivers. -uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); -uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); -uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); -uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); -uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); - - -// connect U8g com generic com names to the desired driver -#define U8G_COM_HW_SPI u8g_com_HAL_LPC1768_hw_spi_fn // use LPC1768 specific hardware SPI routine -#define U8G_COM_SW_SPI u8g_com_HAL_LPC1768_sw_spi_fn // use LPC1768 specific software SPI routine -#define U8G_COM_ST7920_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn -#define U8G_COM_ST7920_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn -#define U8G_COM_SSD_I2C u8g_com_HAL_LPC1768_ssd_hw_i2c_fn - -// let these default for now -#define U8G_COM_PARALLEL u8g_com_null_fn -#define U8G_COM_T6963 u8g_com_null_fn -#define U8G_COM_FAST_PARALLEL u8g_com_null_fn -#define U8G_COM_UC_I2C u8g_com_null_fn diff --git a/src/HAL/LPC1768/u8g/LCD_delay.h b/src/HAL/LPC1768/u8g/LCD_delay.h deleted file mode 100644 index 0b9e2b4..0000000 --- a/src/HAL/LPC1768/u8g/LCD_delay.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * LCD delay routines - used by all the drivers. - * - * These are based on the LPC1768 routines. - * - * Couldn't just call exact copies because the overhead - * results in a one microsecond delay taking about 4µS. - */ - -#ifdef __cplusplus - extern "C" { -#endif - -void U8g_delay(int msec); -void u8g_MicroDelay(); -void u8g_10MicroDelay(); - -#ifdef __cplusplus - } -#endif diff --git a/src/HAL/LPC1768/u8g/LCD_pin_routines.c b/src/HAL/LPC1768/u8g/LCD_pin_routines.c deleted file mode 100644 index 466fc80..0000000 --- a/src/HAL/LPC1768/u8g/LCD_pin_routines.c +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Low level pin manipulation routines - used by all the drivers. - * - * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. - * - * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. - */ - -#ifdef TARGET_LPC1768 - -#include -#include -#include "../../../core/macros.h" -//#include - -#define LPC_PORT_OFFSET (0x0020) -#define LPC_PIN(pin) (1UL << pin) -#define LPC_GPIO(port) ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port)) - -#define INPUT 0 -#define OUTPUT 1 -#define INPUT_PULLUP 2 - -uint8_t LPC1768_PIN_PORT(const uint8_t pin); -uint8_t LPC1768_PIN_PIN(const uint8_t pin); - -#ifdef __cplusplus - extern "C" { -#endif - -// I/O functions -// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2) -void pinMode_LCD(uint8_t pin, uint8_t mode) { - #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) - #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) - PINSEL_CFG_Type config = { LPC1768_PIN_PORT(pin), - LPC1768_PIN_PIN(pin), - PINSEL_FUNC_0, - PINSEL_PINMODE_TRISTATE, - PINSEL_PINMODE_NORMAL }; - switch (mode) { - case INPUT: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); - PINSEL_ConfigPin(&config); - break; - case OUTPUT: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin)); - PINSEL_ConfigPin(&config); - break; - case INPUT_PULLUP: - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); - config.Pinmode = PINSEL_PINMODE_PULLUP; - PINSEL_ConfigPin(&config); - break; - default: break; - } -} - -void u8g_SetPinOutput(uint8_t internal_pin_number) { - pinMode_LCD(internal_pin_number, 1); // OUTPUT -} - -void u8g_SetPinInput(uint8_t internal_pin_number) { - pinMode_LCD(internal_pin_number, 0); // INPUT -} - -void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) { - #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) - #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) - if (pin_status) - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOSET = LPC_PIN(LPC1768_PIN_PIN(pin)); - else - LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOCLR = LPC_PIN(LPC1768_PIN_PIN(pin)); -} - -uint8_t u8g_GetPinLevel(uint8_t pin) { - #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) - #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) - return (uint32_t)LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOPIN & LPC_PIN(LPC1768_PIN_PIN(pin)) ? 1 : 0; -} - -#ifdef __cplusplus - } -#endif - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/LCD_pin_routines.h b/src/HAL/LPC1768/u8g/LCD_pin_routines.h deleted file mode 100644 index d60d93d..0000000 --- a/src/HAL/LPC1768/u8g/LCD_pin_routines.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Low level pin manipulation routines - used by all the drivers. - * - * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. - * - * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. - */ - -void u8g_SetPinOutput(uint8_t internal_pin_number); -void u8g_SetPinInput(uint8_t internal_pin_number); -void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status); -uint8_t u8g_GetPinLevel(uint8_t pin); diff --git a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp deleted file mode 100644 index 0118f92..0000000 --- a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_msp430_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. - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include -#include "../../shared/HAL_SPI.h" - -#ifndef LCD_SPI_SPEED - #ifdef SD_SPI_SPEED - #define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD - #else - #define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied - #endif -#endif - -uint8_t u8g_com_HAL_LPC1768_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_SetPILevel(u8g, U8G_PI_CS, 1); - u8g_SetPILevel(u8g, U8G_PI_A0, 1); - u8g_SetPILevel(u8g, U8G_PI_RESET, 1); - u8g_SetPIOutput(u8g, U8G_PI_CS); - u8g_SetPIOutput(u8g, U8G_PI_A0); - u8g_SetPIOutput(u8g, U8G_PI_RESET); - u8g_Delay(5); - spiBegin(); - spiInit(LCD_SPI_SPEED); - break; - - case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ - u8g_SetPILevel(u8g, U8G_PI_A0, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - u8g_SetPILevel(u8g, U8G_PI_CS, (arg_val ? 0 : 1)); - break; - - case U8G_COM_MSG_RESET: - u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_WRITE_BYTE: - spiSend((uint8_t)arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - spiSend(*ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - spiSend(*ptr++); - arg_val--; - } - } - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp deleted file mode 100644 index bf76eaf..0000000 --- a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_arduino_ssd_i2c.c - * - * COM interface for Arduino (AND ATmega) and the SSDxxxx chip (SOLOMON) variant - * I2C protocol - * - * 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. - */ - -/** - * 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 - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include - -#define I2C_SLA (0x3C*2) -//#define I2C_CMD_MODE 0x080 -#define I2C_CMD_MODE 0x000 -#define I2C_DATA_MODE 0x040 - -uint8_t u8g_com_ssd_I2C_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_HAL_LPC1768_ssd_hw_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; /* initial RS state: unknown mode */ - - u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]); - u8g_com_ssd_I2C_start_sequence(u8g); - 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_ssd_I2C_start_sequence(u8g) == 0) { - u8g_i2c_stop(); - return 0; - } - - if (u8g_i2c_send_byte(arg_val) == 0) { - u8g_i2c_stop(); - return 0; - } - // u8g_i2c_stop(); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - //u8g->pin_list[U8G_PI_SET_A0] = 1; - if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) { - u8g_i2c_stop(); - return 0; - } - - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - if (u8g_i2c_send_byte(*ptr++) == 0) { - u8g_i2c_stop(); - return 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_ssd_I2C_start_sequence(u8g) == 0) { - u8g_i2c_stop(); - return 0; - } - - 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 */ - break; - - } // switch - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp deleted file mode 100644 index ce7b338..0000000 --- a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_LPC1768_st7920_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. - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB - -#include -#include "../../shared/HAL_SPI.h" -#include "../../shared/Delay.h" - -void spiBegin(); -void spiInit(uint8_t spiRate); -void spiSend(uint8_t b); -void spiSend(const uint8_t *buf, size_t n); - -static uint8_t rs_last_state = 255; - -static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) { - - if (rs != rs_last_state) { // Time to send a command/data byte - rs_last_state = rs; - spiSend(rs ? 0x0FA : 0x0F8); // Send data or command - DELAY_US(40); // Give the controller some time: 20 is bad, 30 is OK, 40 is safe - } - - spiSend(val & 0xF0); - spiSend(val << 4); -} - -uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - u8g_SetPILevel(u8g, U8G_PI_CS, 0); - u8g_SetPIOutput(u8g, U8G_PI_CS); - u8g_Delay(5); - spiBegin(); - spiInit(SPI_EIGHTH_SPEED); // ST7920 max speed is about 1.1 MHz - u8g->pin_list[U8G_PI_A0_STATE] = 0; // initial 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: - u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); // Note: the ST7920 has an active high chip-select - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB - -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp deleted file mode 100644 index e159eba..0000000 --- a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_st7920_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. - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if IS_U8GLIB_ST7920 - -#include -#include -#include "../../shared/Delay.h" -#include "../../shared/HAL_SPI.h" - -#ifndef LCD_SPI_SPEED - #define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz -#endif - -static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL; -static uint8_t SPI_speed = 0; - -static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) { - static uint8_t rs_last_state = 255; - if (rs != rs_last_state) { - // Transfer Data (FA) or Command (F8) - swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); - rs_last_state = rs; - DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe - } - swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); - swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); -} - -uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK]; - MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI]; - - u8g_SetPIOutput(u8g, U8G_PI_CS); - u8g_SetPIOutput(u8g, U8G_PI_SCK); - u8g_SetPIOutput(u8g, U8G_PI_MOSI); - u8g_Delay(5); - - SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL); - - u8g_SetPILevel(u8g, U8G_PI_CS, 0); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); - u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); - - u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */ - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_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 (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - } - return 1; -} - -#endif // IS_U8GLIB_ST7920 -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp deleted file mode 100644 index f116a9b..0000000 --- a/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_std_sw_spi.c - * - * Universal 8bit Graphics Library - * - * Copyright (c) 2015, 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. - */ - -#ifdef TARGET_LPC1768 - -#include "../../../inc/MarlinConfigPre.h" - -#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 - -#include -#include "../../shared/HAL_SPI.h" - -#ifndef LCD_SPI_SPEED - #define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz -#endif - -#include -#include -#include -#include - -#include - -uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - - LOOP_L_N(i, 8) { - if (spi_speed == 0) { - LPC176x::gpio_set(mosi_pin, !!(b & 0x80)); - LPC176x::gpio_set(sck_pin, HIGH); - b <<= 1; - if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; - LPC176x::gpio_set(sck_pin, LOW); - } - else { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - LOOP_L_N(j, spi_speed) - LPC176x::gpio_set(mosi_pin, state); - - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - LPC176x::gpio_set(sck_pin, HIGH); - - b <<= 1; - if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; - - LOOP_L_N(j, spi_speed) - LPC176x::gpio_set(sck_pin, LOW); - } - } - - return b; -} - -uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - - LOOP_L_N(i, 8) { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - if (spi_speed == 0) { - LPC176x::gpio_set(sck_pin, LOW); - LPC176x::gpio_set(mosi_pin, state); - LPC176x::gpio_set(mosi_pin, state); // need some setup time - LPC176x::gpio_set(sck_pin, HIGH); - } - else { - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - LPC176x::gpio_set(sck_pin, LOW); - - LOOP_L_N(j, spi_speed) - LPC176x::gpio_set(mosi_pin, state); - - LOOP_L_N(j, spi_speed) - LPC176x::gpio_set(sck_pin, HIGH); - } - b <<= 1; - if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; - } - - return b; -} - -static uint8_t SPI_speed = 0; - -static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) { - #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) - swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin); - #else - swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin); - #endif -} - -uint8_t u8g_com_HAL_LPC1768_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_CS); - u8g_SetPIOutput(u8g, U8G_PI_A0); - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET); - SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); - u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0 - if (arg_val) { // SCK idle state needs to be set to the proper idle state before - // the next chip select goes active - u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active - u8g_SetPILevel(u8g, U8G_PI_CS, LOW); - } - else { - u8g_SetPILevel(u8g, U8G_PI_CS, HIGH); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive - } - #else - u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val); - #endif - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_sw_spi_HAL_LPC1768_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: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_sw_spi_HAL_LPC1768_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_SetPILevel(u8g, U8G_PI_A0, arg_val); - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/upload_extra_script.py b/src/HAL/LPC1768/upload_extra_script.py deleted file mode 100644 index 7975f15..0000000 --- a/src/HAL/LPC1768/upload_extra_script.py +++ /dev/null @@ -1,127 +0,0 @@ -# -# upload_extra_script.py -# set the output_port -# if target_filename is found then that drive is used -# else if target_drive is found then that drive is used -# -from __future__ import print_function - -import pioutil -if pioutil.is_pio_build(): - - target_filename = "FIRMWARE.CUR" - target_drive = "REARM" - - import os,getpass,platform - - current_OS = platform.system() - Import("env") - - def print_error(e): - print('\nUnable to find destination disk (%s)\n' \ - 'Please select it in platformio.ini using the upload_port keyword ' \ - '(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \ - 'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \ - %(e, env.get('PIOENV'))) - - def before_upload(source, target, env): - try: - # - # Find a disk for upload - # - upload_disk = 'Disk not found' - target_file_found = False - target_drive_found = False - if current_OS == 'Windows': - # - # platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:' - # Windows - doesn't care about the disk's name, only cares about the drive letter - import subprocess,string - from ctypes import windll - - # getting list of drives - # https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python - drives = [] - bitmask = windll.kernel32.GetLogicalDrives() - for letter in string.ascii_uppercase: - if bitmask & 1: - drives.append(letter) - bitmask >>= 1 - - for drive in drives: - final_drive_name = drive + ':\\' - # print ('disc check: {}'.format(final_drive_name)) - try: - volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT)) - except Exception as e: - print ('error:{}'.format(e)) - continue - else: - if target_drive in volume_info and not target_file_found: # set upload if not found target file yet - target_drive_found = True - upload_disk = final_drive_name - if target_filename in volume_info: - if not target_file_found: - upload_disk = final_drive_name - target_file_found = True - - elif current_OS == 'Linux': - # - # platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive' - # - drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser())) - if target_drive in drives: # If target drive is found, use it. - target_drive_found = True - upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep - else: - for drive in drives: - try: - files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive)) - except: - continue - else: - if target_filename in files: - upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep - target_file_found = True - break - # - # set upload_port to drive if found - # - - if target_file_found or target_drive_found: - env.Replace( - UPLOAD_FLAGS="-P$UPLOAD_PORT" - ) - - elif current_OS == 'Darwin': # MAC - # - # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive' - # - drives = os.listdir('/Volumes') # human readable names - if target_drive in drives and not target_file_found: # set upload if not found target file yet - target_drive_found = True - upload_disk = '/Volumes/' + target_drive + '/' - for drive in drives: - try: - filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected - except: - continue - else: - if target_filename in filenames: - if not target_file_found: - upload_disk = '/Volumes/' + drive + '/' - target_file_found = True - - # - # Set upload_port to drive if found - # - if target_file_found or target_drive_found: - env.Replace(UPLOAD_PORT=upload_disk) - print('\nUpload disk: ', upload_disk, '\n') - else: - print_error('Autodetect Error') - - except Exception as e: - print_error(str(e)) - - env.AddPreAction("upload", before_upload) diff --git a/src/HAL/LPC1768/usb_serial.cpp b/src/HAL/LPC1768/usb_serial.cpp deleted file mode 100644 index 3c1fce5..0000000 --- a/src/HAL/LPC1768/usb_serial.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef TARGET_LPC1768 - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - -#include "../../feature/e_parser.h" - -EmergencyParser::State emergency_state; - -bool CDC_RecvCallback(const char c) { - emergency_parser.update(emergency_state, c); - return true; -} - -#endif // EMERGENCY_PARSER -#endif // TARGET_LPC1768 diff --git a/src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf b/src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf deleted file mode 100644 index 9727d7d..0000000 --- a/src/HAL/LPC1768/win_usb_driver/lpc176x_usb_driver.inf +++ /dev/null @@ -1,36 +0,0 @@ -[Version] -Signature="$Windows NT$" -Class=Ports -ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} -Provider=%PROVIDER% -DriverVer =04/14/2008, 5.1.2600.5512 - -[Manufacturer] -%PROVIDER%=DeviceList,ntamd64 - - -[DeviceList] -%DESCRIPTION%=LPC1768USB, USB\VID_1D50&PID_6029&MI_00 - -[DeviceList.ntamd64] -%DESCRIPTION%=LPC1768USB, USB\VID_1D50&PID_6029&MI_00 - - -[LPC1768USB] -include=mdmcpq.inf -CopyFiles=FakeModemCopyFileSection -AddReg=LowerFilterAddReg,SerialPropPageAddReg - -[LPC1768USB.Services] -include=mdmcpq.inf -AddService=usbser, 0x00000002, LowerFilter_Service_Inst - -[SerialPropPageAddReg] -HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" - - -[Strings] -PROVIDER = "marlinfw.org" -DRIVER.SVC = "Marlin USB Driver" -DESCRIPTION= "Marlin USB Serial" -COMPOSITE = "Marlin USB VCOM" \ No newline at end of file diff --git a/src/HAL/NATIVE_SIM/HAL.h b/src/HAL/NATIVE_SIM/HAL.h deleted file mode 100644 index 6620361..0000000 --- a/src/HAL/NATIVE_SIM/HAL.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include -#undef min -#undef max -#include -#include "pinmapping.h" - -void _printf (const char *format, ...); -void _putc(uint8_t c); -uint8_t _getc(); - -//arduino: Print.h -#define DEC 10 -#define HEX 16 -#define OCT 8 -#define BIN 2 -//arduino: binary.h (weird defines) -#define B01 1 -#define B10 2 - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "serial.h" - -// ------------------------ -// Defines -// ------------------------ - -#define CPU_32_BIT -#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp - -#define F_CPU 100000000 -#define SystemCoreClock F_CPU - -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -// ------------------------ -// Serial ports -// ------------------------ - -extern MSerialT serial_stream_0; -extern MSerialT serial_stream_1; -extern MSerialT serial_stream_2; -extern MSerialT serial_stream_3; - -#define _MSERIAL(X) serial_stream_##X -#define MSERIAL(X) _MSERIAL(X) - -#if WITHIN(SERIAL_PORT, 0, 3) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #error "SERIAL_PORT must be from 0 to 3. Please update your configuration." -#endif - -#ifdef SERIAL_PORT_2 - #if WITHIN(SERIAL_PORT_2, 0, 3) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #error "SERIAL_PORT_2 must be from 0 to 3. Please update your configuration." - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if WITHIN(MMU2_SERIAL_PORT, 0, 3) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #else - #error "MMU2_SERIAL_PORT must be from 0 to 3. Please update your configuration." - #endif -#endif - -#ifdef LCD_SERIAL_PORT - #if WITHIN(LCD_SERIAL_PORT, 0, 3) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #else - #error "LCD_SERIAL_PORT must be from 0 to 3. Please update your configuration." - #endif -#endif - -// ------------------------ -// Interrupts -// ------------------------ - -#define CRITICAL_SECTION_START() -#define CRITICAL_SECTION_END() - -// ------------------------ -// ADC -// ------------------------ - -#define HAL_ADC_VREF 5.0 -#define HAL_ADC_RESOLUTION 10 - -/* ---------------- Delay in cycles */ - -#define DELAY_CYCLES(x) Kernel::delayCycles(x) -#define SYSTEM_YIELD() Kernel::yield() - -// Maple Compatibility -typedef void (*systickCallback_t)(void); -void systick_attach_callback(systickCallback_t cb); -extern volatile uint32_t systick_uptime_millis; - -// Marlin uses strstr in constexpr context, this is not supported, workaround by defining constexpr versions of the required functions. -#define strstr(a, b) strstr_constexpr((a), (b)) - -constexpr inline std::size_t strlen_constexpr(const char* str) { - // https://github.com/gcc-mirror/gcc/blob/5c7634a0e5f202935aa6c11b6ea953b8bf80a00a/libstdc%2B%2B-v3/include/bits/char_traits.h#L329 - if (str != nullptr) { - std::size_t i = 0; - while (str[i] != '\0') ++i; - return i; - } - return 0; -} - -constexpr inline int strncmp_constexpr(const char* lhs, const char* rhs, std::size_t count) { - // https://github.com/gcc-mirror/gcc/blob/13b9cbfc32fe3ac4c81c4dd9c42d141c8fb95db4/libstdc%2B%2B-v3/include/bits/char_traits.h#L655 - if (lhs == nullptr || rhs == nullptr) - return rhs != nullptr ? -1 : 1; - - for (std::size_t i = 0; i < count; ++i) - if (lhs[i] != rhs[i]) - return lhs[i] < rhs[i] ? -1 : 1; - else if (lhs[i] == '\0') - return 0; - - return 0; -} - -constexpr inline const char* strstr_constexpr(const char* str, const char* target) { - // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c - if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) { - std::size_t len = strlen_constexpr(target); - do { - char sc = {}; - do { - if ((sc = *str++) == '\0') return nullptr; - } while (sc != c); - } while (strncmp_constexpr(str, target, len) != 0); - --str; - } - return str; -} - -constexpr inline char* strstr_constexpr(char* str, const char* target) { - // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c - if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) { - std::size_t len = strlen_constexpr(target); - do { - char sc = {}; - do { - if ((sc = *str++) == '\0') return nullptr; - } while (sc != c); - } while (strncmp_constexpr(str, target, len) != 0); - --str; - } - return str; -} - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init() {} // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return true; } - static void isr_on() {} - static void isr_off() {} - - static void delay_ms(const int ms) { _delay_ms(ms); } - - // Tasks, called from idle() - static void idletask(); - - // Reset - static constexpr uint8_t reset_reason = RST_POWER_ON; - static uint8_t get_reset_source() { return reset_reason; } - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint8_t active_ch; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const uint8_t ch); - - // Begin ADC sampling on the given channel. Called from Temperature::isr! - static void adc_start(const uint8_t ch); - - // Is the ADC ready for reading? - static bool adc_ready(); - - // The current value of the ADC register - static uint16_t adc_value(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -}; diff --git a/src/HAL/NATIVE_SIM/MarlinSPI.h b/src/HAL/NATIVE_SIM/MarlinSPI.h deleted file mode 100644 index b5cc6f0..0000000 --- a/src/HAL/NATIVE_SIM/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/NATIVE_SIM/fastio.h b/src/HAL/NATIVE_SIM/fastio.h deleted file mode 100644 index de8013b..0000000 --- a/src/HAL/NATIVE_SIM/fastio.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for X86_64 - */ - -#include "../shared/Marduino.h" -#include - -#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1) -#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0) - -#define SET_MODE(IO, mode) Gpio::setMode(IO, mode) - -#define WRITE_PIN_SET(IO) Gpio::set(IO) -#define WRITE_PIN_CLR(IO) Gpio::clear(IO) - -#define READ_PIN(IO) Gpio::get(IO) -#define WRITE_PIN(IO,V) Gpio::set(IO, V) - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); - * - * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html - */ - -/// Read a pin -#define _READ(IO) READ_PIN(IO) - -/// Write to a pin -#define _WRITE(IO,V) WRITE_PIN(IO,V) - -/// toggle a pin -#define _TOGGLE(IO) _WRITE(IO, !READ(IO)) - -/// set pin as input -#define _SET_INPUT(IO) SET_DIR_INPUT(IO) - -/// set pin as output -#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO) - -/// set pin as input with pullup mode -#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) - -/// set pin as input with pulldown mode -#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT) - -// hg42: all pins can be input or output (I hope) -// hg42: undefined pins create compile error (IO, is no pin) -// hg42: currently not used, but was used by pinsDebug - -/// check if pin is an input -#define _IS_INPUT(IO) (IO >= 0) - -/// check if pin is an output -#define _IS_OUTPUT(IO) (IO >= 0) - -/// 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 input with pullup wrapper -#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) -/// set pin as input with pulldown wrapper -#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0) -/// set pin as output wrapper - reads the pin and sets the output to that value -#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0) -// set pin as PWM -#define SET_PWM(IO) SET_OUTPUT(IO) - -/// check if pin is an input wrapper -#define IS_INPUT(IO) _IS_INPUT(IO) -/// check if pin is an output wrapper -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -// Shorthand -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h b/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h deleted file mode 100644 index 1ac02f1..0000000 --- a/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h b/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h deleted file mode 100644 index 69b6b48..0000000 --- a/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// Add strcmp_P if missing -#ifndef strcmp_P - #define strcmp_P(a, b) strcmp((a), (b)) -#endif - -#ifndef strcat_P - #define strcat_P(dest, src) strcat((dest), (src)) -#endif diff --git a/src/HAL/NATIVE_SIM/inc/Conditionals_post.h b/src/HAL/NATIVE_SIM/inc/Conditionals_post.h deleted file mode 100644 index 1ac02f1..0000000 --- a/src/HAL/NATIVE_SIM/inc/Conditionals_post.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/NATIVE_SIM/inc/SanityCheck.h b/src/HAL/NATIVE_SIM/inc/SanityCheck.h deleted file mode 100644 index 2d7bef2..0000000 --- a/src/HAL/NATIVE_SIM/inc/SanityCheck.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test X86_64-specific configuration values for errors at compile-time. - */ - -// Emulating RAMPS -#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) - #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on LINUX." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on LINUX." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on LINUX." -#endif diff --git a/src/HAL/NATIVE_SIM/pinsDebug.h b/src/HAL/NATIVE_SIM/pinsDebug.h deleted file mode 100644 index aa90eb3..0000000 --- a/src/HAL/NATIVE_SIM/pinsDebug.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Support routines for X86_64 - */ -#pragma once - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define pwm_details(pin) pin = pin // do nothing // print PWM details -#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin. -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) digitalRead(p) -#define PRINT_PORT(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin - -// active ADC function/mode/code values for PINSEL registers -inline constexpr int8_t ADC_pin_mode(pin_t pin) { - return (-1); -} - -inline int8_t get_pin_mode(pin_t pin) { - if (!VALID_PIN(pin)) return -1; - return 0; -} - -inline bool GET_PINMODE(pin_t pin) { - int8_t pin_mode = get_pin_mode(pin); - if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin - return false; - - return (Gpio::getMode(pin) != 0); //input/output state -} - -inline bool GET_ARRAY_IS_DIGITAL(pin_t pin) { - return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin)); -} diff --git a/src/HAL/NATIVE_SIM/servo_private.h b/src/HAL/NATIVE_SIM/servo_private.h deleted file mode 100644 index 06be189..0000000 --- a/src/HAL/NATIVE_SIM/servo_private.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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 - */ - -/** - * Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers - - * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. - * - * The only modification was to update/delete macros to match the LPC176x. - * - */ - -#include - -// Macros -//values in microseconds -#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 MAX_SERVOS 4 - -#define INVALID_SERVO 255 // flag indicating an invalid servo index - - -// Types - -typedef struct { - uint8_t nbr : 8 ; // a pin number from 0 to 254 (255 signals invalid pin) - uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false -} ServoPin_t; - -typedef struct { - ServoPin_t Pin; - unsigned int pulse_width; // pulse width in microseconds -} ServoInfo_t; - -// Global variables - -extern uint8_t ServoCount; -extern ServoInfo_t servo_info[MAX_SERVOS]; diff --git a/src/HAL/NATIVE_SIM/spi_pins.h b/src/HAL/NATIVE_SIM/spi_pins.h deleted file mode 100644 index a5138e0..0000000 --- a/src/HAL/NATIVE_SIM/spi_pins.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/macros.h" -#include "../../inc/MarlinConfigPre.h" - -#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN) - #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently - // needed due to the speed and mode required for communicating with each device being different. - // This requirement can be removed if the SPI access to these devices is updated to use - // spiBeginTransaction. -#endif - -// Onboard SD -//#define SD_SCK_PIN P0_07 -//#define SD_MISO_PIN P0_08 -//#define SD_MOSI_PIN P0_09 -//#define SD_SS_PIN P0_06 - -// External SD -#ifndef SD_SCK_PIN - #define SD_SCK_PIN 50 -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN 51 -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN 52 -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN 53 -#endif -#ifndef SDSS - #define SDSS SD_SS_PIN -#endif diff --git a/src/HAL/NATIVE_SIM/tft/tft_spi.h b/src/HAL/NATIVE_SIM/tft/tft_spi.h deleted file mode 100644 index b3e622f..0000000 --- a/src/HAL/NATIVE_SIM/tft/tft_spi.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#define DATASIZE_8BIT 8 -#define DATASIZE_16BIT 16 -#define TFT_IO_DRIVER TFT_SPI - -#define DMA_MINC_ENABLE 1 -#define DMA_MINC_DISABLE 0 - -class TFT_SPI { -private: - static uint32_t ReadID(uint16_t Reg); - static void Transmit(uint16_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - -public: - // static SPIClass SPIx; - - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort(); - - static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); - static void DataTransferEnd(); - static void DataTransferAbort(); - - static void WriteData(uint16_t Data); - static void WriteReg(uint16_t Reg); - - static void WriteSequence(uint16_t *Data, uint16_t Count); - // static void WriteMultiple(uint16_t Color, uint16_t Count); - static void WriteMultiple(uint16_t Color, uint32_t Count); -}; diff --git a/src/HAL/NATIVE_SIM/tft/xpt2046.h b/src/HAL/NATIVE_SIM/tft/xpt2046.h deleted file mode 100644 index b131853..0000000 --- a/src/HAL/NATIVE_SIM/tft/xpt2046.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - #include -#endif - -#ifndef TOUCH_MISO_PIN - #define TOUCH_MISO_PIN SD_MISO_PIN -#endif -#ifndef TOUCH_MOSI_PIN - #define TOUCH_MOSI_PIN SD_MOSI_PIN -#endif -#ifndef TOUCH_SCK_PIN - #define TOUCH_SCK_PIN SD_SCK_PIN -#endif -#ifndef TOUCH_CS_PIN - #define TOUCH_CS_PIN SD_SS_PIN -#endif -#ifndef TOUCH_INT_PIN - #define TOUCH_INT_PIN -1 -#endif - -#define XPT2046_DFR_MODE 0x00 -#define XPT2046_SER_MODE 0x04 -#define XPT2046_CONTROL 0x80 - -enum XPTCoordinate : uint8_t { - XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, -}; - -#if !defined(XPT2046_Z1_THRESHOLD) - #define XPT2046_Z1_THRESHOLD 10 -#endif - -class XPT2046 { -private: - static bool isBusy() { return false; } - - static uint16_t getRawData(const XPTCoordinate coordinate); - static bool isTouched(); - - static void DataTransferBegin(); - static void DataTransferEnd(); - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static uint16_t HardwareIO(uint16_t data); - #endif - static uint16_t SoftwareIO(uint16_t data); - static uint16_t IO(uint16_t data = 0); - -public: - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static SPIClass SPIx; - #endif - - static void Init(); - static bool getRawPoint(int16_t *x, int16_t *y); -}; diff --git a/src/HAL/NATIVE_SIM/timers.h b/src/HAL/NATIVE_SIM/timers.h deleted file mode 100644 index be38d58..0000000 --- a/src/HAL/NATIVE_SIM/timers.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL timers for Linux X86_64 - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint64_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFF - -#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif -#ifndef MF_TIMER_SYSTICK - #define MF_TIMER_SYSTICK 2 // Timer Index for Systick -#endif -#define SYSTICK_TIMER_FREQUENCY 1000 - -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler() -#endif - -void HAL_timer_init(); -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare); -hal_timer_t HAL_timer_get_compare(const uint8_t timer_num); -hal_timer_t HAL_timer_get_count(const uint8_t timer_num); - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp b/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp deleted file mode 100644 index 7454543..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// adapted from I2C/master/master.c example -// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html - -#ifdef __PLAT_NATIVE_SIM__ - -#include - -#ifdef __cplusplus - extern "C" { -#endif - -uint8_t u8g_i2c_start(const uint8_t sla) { - return 1; -} - -void u8g_i2c_init(const uint8_t clock_option) { -} - -uint8_t u8g_i2c_send_byte(uint8_t data) { - return 1; -} - -void u8g_i2c_stop() { -} - -#ifdef __cplusplus - } -#endif - -#endif // __PLAT_NATIVE_SIM__ diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h b/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h deleted file mode 100644 index 6d5f91d..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef __cplusplus - extern "C" { -#endif - -void u8g_i2c_init(const uint8_t clock_options); -//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos); -uint8_t u8g_i2c_start(uint8_t sla); -uint8_t u8g_i2c_send_byte(uint8_t data); -void u8g_i2c_stop(); - -#ifdef __cplusplus - } -#endif - diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_defines.h b/src/HAL/NATIVE_SIM/u8g/LCD_defines.h deleted file mode 100644 index 44ffbfe..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_defines.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void usleep(uint64_t microsec); -// The following are optional depending on the platform. - -// definitions of HAL specific com and device drivers. -uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); -uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); - -// connect U8g com generic com names to the desired driver -#define U8G_COM_SW_SPI u8g_com_sw_spi_fn -#define U8G_COM_ST7920_SW_SPI u8g_com_ST7920_sw_spi_fn - -// let these default for now -#define U8G_COM_HW_SPI u8g_com_null_fn -#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn -#define U8G_COM_SSD_I2C u8g_com_null_fn -#define U8G_COM_PARALLEL u8g_com_null_fn -#define U8G_COM_T6963 u8g_com_null_fn -#define U8G_COM_FAST_PARALLEL u8g_com_null_fn -#define U8G_COM_UC_I2C u8g_com_null_fn - - diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_delay.h b/src/HAL/NATIVE_SIM/u8g/LCD_delay.h deleted file mode 100644 index 297361c..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_delay.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * LCD delay routines - used by all the drivers. - * - * These are based on the LPC1768 routines. - * - * Couldn't just call exact copies because the overhead - * results in a one microsecond delay taking about 4µS. - */ - -#ifdef __cplusplus - extern "C" { -#endif - -void U8g_delay(int msec); -void u8g_MicroDelay(); -void u8g_10MicroDelay(); - -#ifdef __cplusplus - } -#endif diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp b/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp deleted file mode 100644 index 91b7e0f..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Low level pin manipulation routines - used by all the drivers. - * - * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. - * - * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. - */ - -#ifdef __PLAT_NATIVE_SIM__ - -#include "../fastio.h" -#include "LCD_pin_routines.h" - -#ifdef __cplusplus - extern "C" { -#endif - -void u8g_SetPinOutput(uint8_t internal_pin_number) { SET_DIR_OUTPUT(internal_pin_number); } -void u8g_SetPinInput(uint8_t internal_pin_number) { SET_DIR_INPUT(internal_pin_number); } -void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) { WRITE_PIN(pin, pin_status); } -uint8_t u8g_GetPinLevel(uint8_t pin) { return READ_PIN(pin); } -void usleep(uint64_t microsec) { assert(false); /* why we here? */ } - -#ifdef __cplusplus - } -#endif - -#endif // __PLAT_NATIVE_SIM__ diff --git a/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h b/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h deleted file mode 100644 index c27c84e..0000000 --- a/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Low level pin manipulation routines - used by all the drivers. - * - * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. - * - * Couldn't just call exact copies because the overhead killed the LCD update speed - * With an intermediate level the softspi was running in the 10-20kHz range which - * resulted in using about about 25% of the CPU's time. - */ - - -#ifdef __cplusplus - extern "C" { -#endif - -void u8g_SetPinOutput(uint8_t internal_pin_number); -void u8g_SetPinInput(uint8_t internal_pin_number); -void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status); -uint8_t u8g_GetPinLevel(uint8_t pin); - -#ifdef __cplusplus - } -#endif diff --git a/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp b/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp deleted file mode 100644 index c384cdd..0000000 --- a/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_st7920_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. - */ - -#ifdef __PLAT_NATIVE_SIM__ - -#include "../../../inc/MarlinConfig.h" - -#if IS_U8GLIB_ST7920 - -#include -#include "../../shared/Delay.h" - -#undef SPI_SPEED -#define SPI_SPEED 6 -#define SPI_DELAY_CYCLES (1 + SPI_SPEED * 10) - -static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL; -static uint8_t SPI_speed = 0; - -static uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) { - for (uint8_t i = 0; i < 8; i++) { - WRITE_PIN(mosi_pin, !!(b & 0x80)); - DELAY_CYCLES(SPI_SPEED); - WRITE_PIN(sck_pin, HIGH); - DELAY_CYCLES(SPI_SPEED); - b <<= 1; - if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1; - WRITE_PIN(sck_pin, LOW); - DELAY_CYCLES(SPI_SPEED); - } - return b; -} - -static uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) { - WRITE_PIN(mosi_pin, HIGH); - WRITE_PIN(sck_pin, LOW); - return spiRate; -} - -static void u8g_com_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) { - static uint8_t rs_last_state = 255; - if (rs != rs_last_state) { - // Transfer Data (FA) or Command (F8) - swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); - rs_last_state = rs; - DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe - } - swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); - swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); -} -#ifdef __cplusplus - extern "C" { -#endif - -uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK]; - MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI]; - - u8g_SetPIOutput(u8g, U8G_PI_CS); - u8g_SetPIOutput(u8g, U8G_PI_SCK); - u8g_SetPIOutput(u8g, U8G_PI_MOSI); - u8g_Delay(5); - - SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL); - - u8g_SetPILevel(u8g, U8G_PI_CS, 0); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); - u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); - - u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */ - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_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 (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t*) arg_ptr; - while (arg_val > 0) { - u8g_com_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); - arg_val--; - } - } - break; - } - return 1; -} -#ifdef __cplusplus - } -#endif - -#endif // IS_U8GLIB_ST7920 -#endif // TARGET_LPC1768 diff --git a/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp b/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp deleted file mode 100644 index 7be8458..0000000 --- a/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Based on u8g_com_std_sw_spi.c - * - * Universal 8bit Graphics Library - * - * Copyright (c) 2015, 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. - */ - -#ifdef __PLAT_NATIVE_SIM__ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 - -#undef SPI_SPEED -#define SPI_SPEED 2 // About 2 MHz - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - LOOP_L_N(i, 8) { - if (spi_speed == 0) { - WRITE_PIN(mosi_pin, !!(b & 0x80)); - WRITE_PIN(sck_pin, HIGH); - b <<= 1; - if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1; - WRITE_PIN(sck_pin, LOW); - } - else { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - LOOP_L_N(j, spi_speed) - WRITE_PIN(mosi_pin, state); - - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - WRITE_PIN(sck_pin, HIGH); - - b <<= 1; - if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1; - - LOOP_L_N(j, spi_speed) - WRITE_PIN(sck_pin, LOW); - } - } - - return b; -} - -uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { - - LOOP_L_N(i, 8) { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - if (spi_speed == 0) { - WRITE_PIN(sck_pin, LOW); - WRITE_PIN(mosi_pin, state); - WRITE_PIN(mosi_pin, state); // need some setup time - WRITE_PIN(sck_pin, HIGH); - } - else { - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - WRITE_PIN(sck_pin, LOW); - - LOOP_L_N(j, spi_speed) - WRITE_PIN(mosi_pin, state); - - LOOP_L_N(j, spi_speed) - WRITE_PIN(sck_pin, HIGH); - } - b <<= 1; - if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1; - } - - return b; -} - -static uint8_t SPI_speed = 0; - -static uint8_t swSpiInit(const uint8_t spi_speed, const uint8_t clk_pin, const uint8_t mosi_pin) { - return spi_speed; -} - -static void u8g_sw_spi_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) { - #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) - swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin); - #else - swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin); - #endif -} - -uint8_t u8g_com_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_CS); - u8g_SetPIOutput(u8g, U8G_PI_A0); - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET); - SPI_speed = swSpiInit(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); - u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); - break; - - case U8G_COM_MSG_CHIP_SELECT: - #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0 - if (arg_val) { // SCK idle state needs to be set to the proper idle state before - // the next chip select goes active - u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active - u8g_SetPILevel(u8g, U8G_PI_CS, LOW); - } - else { - u8g_SetPILevel(u8g, U8G_PI_CS, HIGH); - u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive - } - #else - u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val); - #endif - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_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: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_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: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_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_SetPILevel(u8g, U8G_PI_A0, arg_val); - break; - } - return 1; -} - -#ifdef __cplusplus - } -#endif - -#elif NONE(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB - - #include - uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {return 0;} - -#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 - -#endif // __PLAT_NATIVE_SIM__ diff --git a/src/HAL/SAMD51/HAL.cpp b/src/HAL/SAMD51/HAL.cpp deleted file mode 100644 index bd1c98b..0000000 --- a/src/HAL/SAMD51/HAL.cpp +++ /dev/null @@ -1,690 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" -#include -#include - -#ifdef ADAFRUIT_GRAND_CENTRAL_M4 - #if USING_HW_SERIALUSB - DefaultSerial1 MSerial0(false, Serial); - #endif - #if USING_HW_SERIAL0 - DefaultSerial2 MSerial1(false, Serial1); - #endif - #if USING_HW_SERIAL1 - DefaultSerial3 MSerial2(false, Serial2); - #endif - #if USING_HW_SERIAL2 - DefaultSerial4 MSerial3(false, Serial3); - #endif - #if USING_HW_SERIAL3 - DefaultSerial5 MSerial4(false, Serial4); - #endif -#endif - -#define GET_TEMP_0_ADC() TERN(HAS_TEMP_ADC_0, PIN_TO_ADC(TEMP_0_PIN), -1) -#define GET_TEMP_1_ADC() TERN(HAS_TEMP_ADC_1, PIN_TO_ADC(TEMP_1_PIN), -1) -#define GET_TEMP_2_ADC() TERN(HAS_TEMP_ADC_2, PIN_TO_ADC(TEMP_2_PIN), -1) -#define GET_TEMP_3_ADC() TERN(HAS_TEMP_ADC_3, PIN_TO_ADC(TEMP_3_PIN), -1) -#define GET_TEMP_4_ADC() TERN(HAS_TEMP_ADC_4, PIN_TO_ADC(TEMP_4_PIN), -1) -#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1) -#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1) -#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1) -#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1) -#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1) -#define GET_PROBE_ADC() TERN(HAS_TEMP_ADC_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1) -#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1) -#define GET_BOARD_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1) -#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1) -#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1) -#define GET_JOY_ADC_X() TERN(HAS_JOY_ADC_X, PIN_TO_ADC(JOY_X_PIN), -1) -#define GET_JOY_ADC_Y() TERN(HAS_JOY_ADC_Y, PIN_TO_ADC(JOY_Y_PIN), -1) -#define GET_JOY_ADC_Z() TERN(HAS_JOY_ADC_Z, PIN_TO_ADC(JOY_Z_PIN), -1) - -#define IS_ADC_REQUIRED(n) ( \ - GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \ - || GET_TEMP_4_ADC() == n || GET_TEMP_5_ADC() == n || GET_TEMP_6_ADC() == n || GET_TEMP_7_ADC() == n \ - || GET_BED_ADC() == n \ - || GET_CHAMBER_ADC() == n \ - || GET_PROBE_ADC() == n \ - || GET_COOLER_ADC() == n \ - || GET_BOARD_ADC() == n \ - || GET_FILAMENT_WIDTH_ADC() == n \ - || GET_BUTTONS_ADC() == n \ - || GET_JOY_ADC_X() == n || GET_JOY_ADC_Y() == n || GET_JOY_ADC_Z() == n \ -) - -#if IS_ADC_REQUIRED(0) - #define ADC0_IS_REQUIRED 1 - #define FIRST_ADC 0 -#else - #define FIRST_ADC 1 -#endif -#if IS_ADC_REQUIRED(1) - #define ADC1_IS_REQUIRED 1 - #define LAST_ADC 1 -#else - #define LAST_ADC 0 -#endif -#if ADC0_IS_REQUIRED || ADC1_IS_REQUIRED - #define ADC_IS_REQUIRED 1 - #define DMA_IS_REQUIRED 1 -#endif - -enum ADCIndex { - #if GET_TEMP_0_ADC() == 0 - TEMP_0, - #endif - #if GET_TEMP_1_ADC() == 0 - TEMP_1, - #endif - #if GET_TEMP_2_ADC() == 0 - TEMP_2, - #endif - #if GET_TEMP_3_ADC() == 0 - TEMP_3, - #endif - #if GET_TEMP_4_ADC() == 0 - TEMP_4, - #endif - #if GET_TEMP_5_ADC() == 0 - TEMP_5, - #endif - #if GET_TEMP_6_ADC() == 0 - TEMP_6, - #endif - #if GET_TEMP_7_ADC() == 0 - TEMP_7, - #endif - #if GET_BED_ADC() == 0 - TEMP_BED, - #endif - #if GET_CHAMBER_ADC() == 0 - TEMP_CHAMBER, - #endif - #if GET_PROBE_ADC() == 0 - TEMP_PROBE, - #endif - #if GET_COOLER_ADC() == 0 - TEMP_COOLER, - #endif - #if GET_BOARD_ADC() == 0 - TEMP_BOARD, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 0 - FILWIDTH, - #endif - #if GET_BUTTONS_ADC() == 0 - ADC_KEY, - #endif - #if GET_JOY_ADC_X() == 0 - JOY_X, - #endif - #if GET_JOY_ADC_Y() == 0 - JOY_Y, - #endif - #if GET_JOY_ADC_Z() == 0 - JOY_Z, - #endif - #if GET_TEMP_0_ADC() == 1 - TEMP_0, - #endif - #if GET_TEMP_1_ADC() == 1 - TEMP_1, - #endif - #if GET_TEMP_2_ADC() == 1 - TEMP_2, - #endif - #if GET_TEMP_3_ADC() == 1 - TEMP_3, - #endif - #if GET_TEMP_4_ADC() == 1 - TEMP_4, - #endif - #if GET_TEMP_5_ADC() == 1 - TEMP_5, - #endif - #if GET_TEMP_6_ADC() == 1 - TEMP_6, - #endif - #if GET_TEMP_7_ADC() == 1 - TEMP_7, - #endif - #if GET_BED_ADC() == 1 - TEMP_BED, - #endif - #if GET_CHAMBER_ADC() == 1 - TEMP_CHAMBER, - #endif - #if GET_PROBE_ADC() == 1 - TEMP_PROBE, - #endif - #if GET_COOLER_ADC() == 1 - TEMP_COOLER, - #endif - #if GET_BOARD_ADC() == 1 - TEMP_BOARD, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 1 - FILWIDTH, - #endif - #if GET_BUTTONS_ADC() == 1 - ADC_KEY, - #endif - #if GET_JOY_ADC_X() == 1 - JOY_X, - #endif - #if GET_JOY_ADC_Y() == 1 - JOY_Y, - #endif - #if GET_JOY_ADC_Z() == 1 - JOY_Z, - #endif - ADC_COUNT -}; - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT_REG TERN(WATCHDOG_DURATION_8S, WDT_CONFIG_PER_CYC8192, WDT_CONFIG_PER_CYC4096) // 4 or 8 second timeout - - void MarlinHAL::watchdog_init() { - // The low-power oscillator used by the WDT runs at 32,768 Hz with - // a 1:32 prescale, thus 1024 Hz, though probably not super precise. - - // Setup WDT clocks - MCLK->APBAMASK.bit.OSC32KCTRL_ = true; - MCLK->APBAMASK.bit.WDT_ = true; - OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses) - - WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config - SYNC(WDT->SYNCBUSY.bit.ENABLE); - - WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt - WDT->CONFIG.reg = WDT_TIMEOUT_REG; // Set a 4s or 8s period for chip reset - - hal.watchdog_refresh(); - - WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode - SYNC(WDT->SYNCBUSY.bit.ENABLE); - } - - // Reset watchdog. MUST be called at least every 4 seconds after the - // first watchdog_init or SAMD will go into emergency procedures. - void MarlinHAL::watchdog_refresh() { - SYNC(WDT->SYNCBUSY.bit.CLEAR); // Test first if previous is 'ongoing' to save time waiting for command execution - WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY; - } - -#endif - -// ------------------------ -// Types -// ------------------------ - -#if DMA_IS_REQUIRED - - // Struct must be 32 bits aligned because of DMA accesses but fields needs to be 8 bits packed - typedef struct __attribute__((aligned(4), packed)) { - ADC_INPUTCTRL_Type INPUTCTRL; - } HAL_DMA_DAC_Registers; // DMA transferred registers - -#endif - -// ------------------------ -// Private Variables -// ------------------------ - -#if ADC_IS_REQUIRED - - // Pins used by ADC inputs. Order must be ADC0 inputs first then ADC1 - static constexpr uint8_t adc_pins[ADC_COUNT] = { - // ADC0 pins - #if GET_TEMP_0_ADC() == 0 - TEMP_0_PIN, - #endif - #if GET_TEMP_1_ADC() == 0 - TEMP_1_PIN, - #endif - #if GET_TEMP_2_ADC() == 0 - TEMP_2_PIN, - #endif - #if GET_TEMP_3_ADC() == 0 - TEMP_3_PIN, - #endif - #if GET_TEMP_4_ADC() == 0 - TEMP_4_PIN, - #endif - #if GET_TEMP_5_ADC() == 0 - TEMP_5_PIN, - #endif - #if GET_TEMP_6_ADC() == 0 - TEMP_6_PIN, - #endif - #if GET_TEMP_7_ADC() == 0 - TEMP_7_PIN, - #endif - #if GET_BED_ADC() == 0 - TEMP_BED_PIN, - #endif - #if GET_CHAMBER_ADC() == 0 - TEMP_CHAMBER_PIN, - #endif - #if GET_PROBE_ADC() == 0 - TEMP_PROBE_PIN, - #endif - #if GET_COOLER_ADC() == 0 - TEMP_COOLER_PIN, - #endif - #if GET_BOARD_ADC() == 0 - TEMP_BOARD_PIN, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 0 - FILWIDTH_PIN, - #endif - #if GET_BUTTONS_ADC() == 0 - ADC_KEYPAD_PIN, - #endif - #if GET_JOY_ADC_X() == 0 - JOY_X_PIN, - #endif - #if GET_JOY_ADC_Y() == 0 - JOY_Y_PIN, - #endif - #if GET_JOY_ADC_Z() == 0 - JOY_Z_PIN, - #endif - // ADC1 pins - #if GET_TEMP_0_ADC() == 1 - TEMP_0_PIN, - #endif - #if GET_TEMP_1_ADC() == 1 - TEMP_1_PIN, - #endif - #if GET_TEMP_2_ADC() == 1 - TEMP_2_PIN, - #endif - #if GET_TEMP_3_ADC() == 1 - TEMP_3_PIN, - #endif - #if GET_TEMP_4_ADC() == 1 - TEMP_4_PIN, - #endif - #if GET_TEMP_5_ADC() == 1 - TEMP_5_PIN, - #endif - #if GET_TEMP_6_ADC() == 1 - TEMP_6_PIN, - #endif - #if GET_TEMP_7_ADC() == 1 - TEMP_7_PIN, - #endif - #if GET_BED_ADC() == 1 - TEMP_BED_PIN, - #endif - #if GET_CHAMBER_ADC() == 1 - TEMP_CHAMBER_PIN, - #endif - #if GET_PROBE_ADC() == 1 - TEMP_PROBE_PIN, - #endif - #if GET_COOLER_ADC() == 1 - TEMP_COOLER_PIN, - #endif - #if GET_BOARD_ADC() == 1 - TEMP_BOARD_PIN, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 1 - FILWIDTH_PIN, - #endif - #if GET_BUTTONS_ADC() == 1 - ADC_KEYPAD_PIN, - #endif - #if GET_JOY_ADC_X() == 1 - JOY_X_PIN, - #endif - #if GET_JOY_ADC_Y() == 1 - JOY_Y_PIN, - #endif - #if GET_JOY_ADC_Z() == 1 - JOY_Z_PIN, - #endif - }; - - static uint16_t adc_results[ADC_COUNT]; - - #if ADC0_IS_REQUIRED - Adafruit_ZeroDMA adc0DMAProgram, adc0DMARead; - - static constexpr HAL_DMA_DAC_Registers adc0_dma_regs_list[ADC_COUNT] = { - #if GET_TEMP_0_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_0_PIN) }, - #endif - #if GET_TEMP_1_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_1_PIN) }, - #endif - #if GET_TEMP_2_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_2_PIN) }, - #endif - #if GET_TEMP_3_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_3_PIN) }, - #endif - #if GET_TEMP_4_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_4_PIN) }, - #endif - #if GET_TEMP_5_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_5_PIN) }, - #endif - #if GET_TEMP_6_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_6_PIN) }, - #endif - #if GET_TEMP_7_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_7_PIN) }, - #endif - #if GET_BED_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_BED_PIN) }, - #endif - #if GET_CHAMBER_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) }, - #endif - #if GET_PROBE_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) }, - #endif - #if GET_COOLER_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) }, - #endif - #if GET_BOARD_ADC() == 0 - { PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) }, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 0 - { PIN_TO_INPUTCTRL(FILWIDTH_PIN) }, - #endif - #if GET_BUTTONS_ADC() == 0 - { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) }, - #endif - #if GET_JOY_ADC_X() == 0 - { PIN_TO_INPUTCTRL(JOY_X_PIN) }, - #endif - #if GET_JOY_ADC_Y() == 0 - { PIN_TO_INPUTCTRL(JOY_Y_PIN) }, - #endif - #if GET_JOY_ADC_Z() == 0 - { PIN_TO_INPUTCTRL(JOY_Z_PIN) }, - #endif - }; - - #define ADC0_AINCOUNT COUNT(adc0_dma_regs_list) - #endif // ADC0_IS_REQUIRED - - #if ADC1_IS_REQUIRED - Adafruit_ZeroDMA adc1DMAProgram, adc1DMARead; - - static constexpr HAL_DMA_DAC_Registers adc1_dma_regs_list[ADC_COUNT] = { - #if GET_TEMP_0_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_0_PIN) }, - #endif - #if GET_TEMP_1_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_1_PIN) }, - #endif - #if GET_TEMP_2_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_2_PIN) }, - #endif - #if GET_TEMP_3_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_3_PIN) }, - #endif - #if GET_TEMP_4_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_4_PIN) }, - #endif - #if GET_TEMP_5_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_5_PIN) }, - #endif - #if GET_TEMP_6_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_6_PIN) }, - #endif - #if GET_TEMP_7_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_7_PIN) }, - #endif - #if GET_BED_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_BED_PIN) }, - #endif - #if GET_CHAMBER_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) }, - #endif - #if GET_PROBE_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) }, - #endif - #if GET_COOLER_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) }, - #endif - #if GET_BOARD_ADC() == 1 - { PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) }, - #endif - #if GET_FILAMENT_WIDTH_ADC() == 1 - { PIN_TO_INPUTCTRL(FILWIDTH_PIN) }, - #endif - #if GET_BUTTONS_ADC() == 1 - { PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) }, - #endif - #if GET_JOY_ADC_X() == 1 - { PIN_TO_INPUTCTRL(JOY_X_PIN) }, - #endif - #if GET_JOY_ADC_Y() == 1 - { PIN_TO_INPUTCTRL(JOY_Y_PIN) }, - #endif - #if GET_JOY_ADC_Z() == 1 - { PIN_TO_INPUTCTRL(JOY_Z_PIN) }, - #endif - }; - - #define ADC1_AINCOUNT COUNT(adc1_dma_regs_list) - #endif // ADC1_IS_REQUIRED - -#endif // ADC_IS_REQUIRED - -// ------------------------ -// Private functions -// ------------------------ - -void MarlinHAL::dma_init() { - - #if DMA_IS_REQUIRED - - DmacDescriptor *descriptor; - - #if ADC0_IS_REQUIRED - adc0DMAProgram.setTrigger(ADC0_DMAC_ID_SEQ); - adc0DMAProgram.setAction(DMA_TRIGGER_ACTON_BEAT); - adc0DMAProgram.loop(true); - if (adc0DMAProgram.allocate() == DMA_STATUS_OK) { - descriptor = adc0DMAProgram.addDescriptor( - (void *)adc0_dma_regs_list, // SRC - (void *)&ADC0->DSEQDATA.reg, // DEST - sizeof(adc0_dma_regs_list) / 4, // CNT - DMA_BEAT_SIZE_WORD, - true, // SRCINC - false, // DSTINC - DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE - DMA_STEPSEL_SRC // STEPSEL - ); - if (descriptor) - descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT; - adc0DMAProgram.startJob(); - } - - adc0DMARead.setTrigger(ADC0_DMAC_ID_RESRDY); - adc0DMARead.setAction(DMA_TRIGGER_ACTON_BEAT); - adc0DMARead.loop(true); - if (adc0DMARead.allocate() == DMA_STATUS_OK) { - adc0DMARead.addDescriptor( - (void *)&ADC0->RESULT.reg, // SRC - &adc_results, // DEST - ADC0_AINCOUNT, // CNT - DMA_BEAT_SIZE_HWORD, - false, // SRCINC - true, // DSTINC - DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE - DMA_STEPSEL_DST // STEPSEL - ); - adc0DMARead.startJob(); - } - #endif - #if ADC1_IS_REQUIRED - adc1DMAProgram.setTrigger(ADC1_DMAC_ID_SEQ); - adc1DMAProgram.setAction(DMA_TRIGGER_ACTON_BEAT); - adc1DMAProgram.loop(true); - if (adc1DMAProgram.allocate() == DMA_STATUS_OK) { - descriptor = adc1DMAProgram.addDescriptor( - (void *)adc1_dma_regs_list, // SRC - (void *)&ADC1->DSEQDATA.reg, // DEST - sizeof(adc1_dma_regs_list) / 4, // CNT - DMA_BEAT_SIZE_WORD, - true, // SRCINC - false, // DSTINC - DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE - DMA_STEPSEL_SRC // STEPSEL - ); - if (descriptor) - descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT; - adc1DMAProgram.startJob(); - } - - adc1DMARead.setTrigger(ADC1_DMAC_ID_RESRDY); - adc1DMARead.setAction(DMA_TRIGGER_ACTON_BEAT); - adc1DMARead.loop(true); - if (adc1DMARead.allocate() == DMA_STATUS_OK) { - adc1DMARead.addDescriptor( - (void *)&ADC1->RESULT.reg, // SRC - &adc_results[ADC0_AINCOUNT], // DEST - ADC1_AINCOUNT, // CNT - DMA_BEAT_SIZE_HWORD, - false, // SRCINC - true, // DSTINC - DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE - DMA_STEPSEL_DST // STEPSEL - ); - adc1DMARead.startJob(); - } - #endif - - DMAC->PRICTRL0.bit.RRLVLEN0 = true; // Activate round robin for DMA channels required by ADCs - - #endif // DMA_IS_REQUIRED -} - -// ------------------------ -// Public functions -// ------------------------ - -// HAL initialization task -void MarlinHAL::init() { - TERN_(DMA_IS_REQUIRED, dma_init()); - #if ENABLED(SDSUPPORT) - #if HAS_SD_DETECT && SD_CONNECTION_IS(ONBOARD) - SET_INPUT_PULLUP(SD_DETECT_PIN); - #endif - OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up - #endif -} - -#pragma push_macro("WDT") -#undef WDT // Required to be able to use '.bit.WDT'. Compiler wrongly replace struct field with WDT define -uint8_t MarlinHAL::get_reset_source() { - RSTC_RCAUSE_Type resetCause; - - resetCause.reg = REG_RSTC_RCAUSE; - if (resetCause.bit.POR) return RST_POWER_ON; - else if (resetCause.bit.EXT) return RST_EXTERNAL; - else if (resetCause.bit.BODCORE || resetCause.bit.BODVDD) return RST_BROWN_OUT; - else if (resetCause.bit.WDT) return RST_WATCHDOG; - else if (resetCause.bit.SYST || resetCause.bit.NVM) return RST_SOFTWARE; - else if (resetCause.bit.BACKUP) return RST_BACKUP; - return 0; -} -#pragma pop_macro("WDT") - -void MarlinHAL::reboot() { NVIC_SystemReset(); } - -extern "C" { - void * _sbrk(int incr); - - extern unsigned int __bss_end__; // end of bss section -} - -// Return free memory between end of heap (or end bss) and whatever is current -int freeMemory() { - int free_memory, heap_end = (int)_sbrk(0); - return (int)&free_memory - (heap_end ?: (int)&__bss_end__); -} - -// ------------------------ -// ADC -// ------------------------ - -uint16_t MarlinHAL::adc_result; - -void MarlinHAL::adc_init() { - #if ADC_IS_REQUIRED - memset(adc_results, 0xFF, sizeof(adc_results)); // Fill result with invalid values - - LOOP_L_N(pi, COUNT(adc_pins)) - pinPeripheral(adc_pins[pi], PIO_ANALOG); - - LOOP_S_LE_N(ai, FIRST_ADC, LAST_ADC) { - Adc* adc = ((Adc*[])ADC_INSTS)[ai]; - - // ADC clock setup - GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN = false; - SYNC(GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN); - GCLK->PCHCTRL[ADC0_GCLK_ID + ai].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN; // 48MHz startup code programmed - SYNC(!GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN); - adc->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val; // 1.5MHZ adc clock - - // ADC setup - // Preloaded data (fixed for all ADC instances hence not loaded by DMA) - adc->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // VRefA pin - SYNC(adc->SYNCBUSY.bit.REFCTRL); - adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; // ... ADC_CTRLB_RESSEL_16BIT_Val - SYNC(adc->SYNCBUSY.bit.CTRLB); - adc->SAMPCTRL.bit.SAMPLEN = (6 - 1); // Sampling clocks - //adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_16 | ADC_AVGCTRL_ADJRES(4); // 16 Accumulated conversions and shift 4 to get oversampled 12 bits result - //SYNC(adc->SYNCBUSY.bit.AVGCTRL); - - // Registers loaded by DMA - adc->DSEQCTRL.bit.INPUTCTRL = true; - adc->DSEQCTRL.bit.AUTOSTART = true; // Start conversion after DMA sequence - - adc->CTRLA.bit.ENABLE = true; // Enable ADC - SYNC(adc->SYNCBUSY.bit.ENABLE); - } - #endif // ADC_IS_REQUIRED -} - -void MarlinHAL::adc_start(const pin_t pin) { - #if ADC_IS_REQUIRED - LOOP_L_N(pi, COUNT(adc_pins)) - if (pin == adc_pins[pi]) { adc_result = adc_results[pi]; return; } - #endif - - adc_result = 0xFFFF; -} - -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/HAL.h b/src/HAL/SAMD51/HAL.h deleted file mode 100644 index 79ba802..0000000 --- a/src/HAL/SAMD51/HAL.h +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CPU_32_BIT - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" - -#ifdef ADAFRUIT_GRAND_CENTRAL_M4 - #include "MarlinSerial_AGCM4.h" - - // Serial ports - typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1; - typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2; - typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3; - typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4; - typedef ForwardSerial1Class< decltype(Serial4) > DefaultSerial5; - extern DefaultSerial1 MSerial0; - extern DefaultSerial2 MSerial1; - extern DefaultSerial3 MSerial2; - extern DefaultSerial4 MSerial3; - extern DefaultSerial5 MSerial4; - - #define __MSERIAL(X) MSerial##X - #define _MSERIAL(X) __MSERIAL(X) - #define MSERIAL(X) _MSERIAL(INCREMENT(X)) - - #if SERIAL_PORT == -1 - #define MYSERIAL1 MSerial0 - #elif WITHIN(SERIAL_PORT, 0, 3) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) - #else - #error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif - - #ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == -1 - #define MYSERIAL2 MSerial0 - #elif WITHIN(SERIAL_PORT_2, 0, 3) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif - #endif - - #ifdef MMU2_SERIAL_PORT - #if MMU2_SERIAL_PORT == -1 - #define MMU2_SERIAL MSerial0 - #elif WITHIN(MMU2_SERIAL_PORT, 0, 3) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #else - #error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif - #endif - - #ifdef LCD_SERIAL_PORT - #if LCD_SERIAL_PORT == -1 - #define LCD_SERIAL MSerial0 - #elif WITHIN(LCD_SERIAL_PORT, 0, 3) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #else - #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." - #endif - #endif - -#endif // ADAFRUIT_GRAND_CENTRAL_M4 - -typedef int8_t pin_t; - -#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp - -class Servo; -typedef Servo hal_servo_t; - -// -// Interrupts -// -#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() - -#define cli() __disable_irq() // Disable interrupts -#define sei() __enable_irq() // Enable interrupts - -// -// ADC -// - -//#define HAL_ADC_FILTERED // Disable Marlin's oversampling. The HAL filters ADC values. -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 // ... 12 - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -// -// Tone -// -void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0); -void noTone(const pin_t _pin); - -// ------------------------ -// Class Utilities -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -#ifdef __cplusplus - extern "C" { -#endif - -char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s); - -extern "C" int freeMemory(); - -#ifdef __cplusplus - } -#endif - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init(); // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_PRIMASK(); } - static void isr_on() { sei(); } - static void isr_off() { cli(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint16_t adc_result; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const uint8_t ch) {} - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return adc_result; } - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -private: - static void dma_init(); -}; diff --git a/src/HAL/SAMD51/HAL_SPI.cpp b/src/HAL/SAMD51/HAL_SPI.cpp deleted file mode 100644 index 77f4d5e..0000000 --- a/src/HAL/SAMD51/HAL_SPI.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Hardware and software SPI implementations are included in this file. - * - * Control of the slave select pin(s) is handled by the calling routines and - * SAMD51 let hardware SPI handling to remove SS from its logic. - */ - -#ifdef __SAMD51__ - -// -------------------------------------------------------------------------- -// Includes -// -------------------------------------------------------------------------- - -#include "../../inc/MarlinConfig.h" -#include - -// -------------------------------------------------------------------------- -// Public functions -// -------------------------------------------------------------------------- - -#if EITHER(SOFTWARE_SPI, FORCE_SOFT_SPI) - - // ------------------------ - // Software SPI - // ------------------------ - #error "Software SPI not supported for SAMD51. Use Hardware SPI." - -#else // !SOFTWARE_SPI - - #ifdef ADAFRUIT_GRAND_CENTRAL_M4 - #if SD_CONNECTION_IS(ONBOARD) - #define sdSPI SDCARD_SPI - #else - #define sdSPI SPI - #endif - #endif - - static SPISettings spiConfig; - - // ------------------------ - // Hardware SPI - // ------------------------ - void spiBegin() { - spiInit(SPI_HALF_SPEED); - } - - void spiInit(uint8_t spiRate) { - // Use datarates Marlin uses - uint32_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = 8000000; break; - case SPI_HALF_SPEED: clock = 4000000; break; - case SPI_QUARTER_SPEED: clock = 2000000; break; - case SPI_EIGHTH_SPEED: clock = 1000000; break; - case SPI_SIXTEENTH_SPEED: clock = 500000; break; - case SPI_SPEED_5: clock = 250000; break; - case SPI_SPEED_6: clock = 125000; break; - default: clock = 4000000; break; // Default from the SPI library - } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - sdSPI.begin(); - } - - /** - * @brief Receives a single byte from the SPI port. - * - * @return Byte received - * - * @details - */ - uint8_t spiRec() { - sdSPI.beginTransaction(spiConfig); - uint8_t returnByte = sdSPI.transfer(0xFF); - sdSPI.endTransaction(); - return returnByte; - } - - /** - * @brief Receives a number of bytes from the SPI port to a buffer - * - * @param buf Pointer to starting address of buffer to write to. - * @param nbyte Number of bytes to receive. - * @return Nothing - */ - void spiRead(uint8_t *buf, uint16_t nbyte) { - if (nbyte == 0) return; - memset(buf, 0xFF, nbyte); - sdSPI.beginTransaction(spiConfig); - sdSPI.transfer(buf, nbyte); - sdSPI.endTransaction(); - } - - /** - * @brief Sends a single byte on SPI port - * - * @param b Byte to send - * - * @details - */ - void spiSend(uint8_t b) { - sdSPI.beginTransaction(spiConfig); - sdSPI.transfer(b); - sdSPI.endTransaction(); - } - - /** - * @brief Write token and then write from 512 byte buffer to SPI (for SD card) - * - * @param buf Pointer with buffer start address - * @return Nothing - * - * @details Uses DMA - */ - void spiSendBlock(uint8_t token, const uint8_t *buf) { - sdSPI.beginTransaction(spiConfig); - sdSPI.transfer(token); - sdSPI.transfer((uint8_t*)buf, nullptr, 512); - sdSPI.endTransaction(); - } - - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, (BitOrder)bitOrder, dataMode); - sdSPI.beginTransaction(spiConfig); - } -#endif // !SOFTWARE_SPI - -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/MarlinSPI.h b/src/HAL/SAMD51/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/SAMD51/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp b/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp deleted file mode 100644 index a16ea2f..0000000 --- a/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ADAFRUIT_GRAND_CENTRAL_M4 - -/** - * Framework doesn't define some serials to save sercom resources - * hence if these are used I need to define them - */ - -#include "../../inc/MarlinConfig.h" - -#if USING_HW_SERIAL1 - UartT Serial2(false, &sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); - void SERCOM4_0_Handler() { Serial2.IrqHandler(); } - void SERCOM4_1_Handler() { Serial2.IrqHandler(); } - void SERCOM4_2_Handler() { Serial2.IrqHandler(); } - void SERCOM4_3_Handler() { Serial2.IrqHandler(); } -#endif - -#if USING_HW_SERIAL2 - UartT Serial3(false, &sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX); - void SERCOM1_0_Handler() { Serial3.IrqHandler(); } - void SERCOM1_1_Handler() { Serial3.IrqHandler(); } - void SERCOM1_2_Handler() { Serial3.IrqHandler(); } - void SERCOM1_3_Handler() { Serial3.IrqHandler(); } -#endif - -#if USING_HW_SERIAL3 - UartT Serial4(false, &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX); - void SERCOM5_0_Handler() { Serial4.IrqHandler(); } - void SERCOM5_1_Handler() { Serial4.IrqHandler(); } - void SERCOM5_2_Handler() { Serial4.IrqHandler(); } - void SERCOM5_3_Handler() { Serial4.IrqHandler(); } -#endif - -#endif // ADAFRUIT_GRAND_CENTRAL_M4 diff --git a/src/HAL/SAMD51/MarlinSerial_AGCM4.h b/src/HAL/SAMD51/MarlinSerial_AGCM4.h deleted file mode 100644 index ac5a379..0000000 --- a/src/HAL/SAMD51/MarlinSerial_AGCM4.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/serial_hook.h" - -typedef Serial1Class UartT; - -extern UartT Serial2; -extern UartT Serial3; -extern UartT Serial4; diff --git a/src/HAL/SAMD51/QSPIFlash.cpp b/src/HAL/SAMD51/QSPIFlash.cpp deleted file mode 100644 index fc21a1a..0000000 --- a/src/HAL/SAMD51/QSPIFlash.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(QSPI_EEPROM) - -#include "QSPIFlash.h" - -#define INVALID_ADDR 0xFFFFFFFF -#define SECTOR_OF(a) (a & ~(SFLASH_SECTOR_SIZE - 1)) -#define OFFSET_OF(a) (a & (SFLASH_SECTOR_SIZE - 1)) - -Adafruit_SPIFlashBase * QSPIFlash::_flashBase = nullptr; -uint8_t QSPIFlash::_buf[SFLASH_SECTOR_SIZE]; -uint32_t QSPIFlash::_addr = INVALID_ADDR; - -void QSPIFlash::begin() { - if (_flashBase) return; - - _flashBase = new Adafruit_SPIFlashBase(new Adafruit_FlashTransport_QSPI()); - _flashBase->begin(nullptr); -} - -size_t QSPIFlash::size() { - return _flashBase->size(); -} - -uint8_t QSPIFlash::readByte(const uint32_t address) { - if (SECTOR_OF(address) == _addr) return _buf[OFFSET_OF(address)]; - - return _flashBase->read8(address); -} - -void QSPIFlash::writeByte(const uint32_t address, const uint8_t value) { - uint32_t const sector_addr = SECTOR_OF(address); - - // Page changes, flush old and update new cache - if (sector_addr != _addr) { - flush(); - _addr = sector_addr; - - // read a whole page from flash - _flashBase->readBuffer(sector_addr, _buf, SFLASH_SECTOR_SIZE); - } - - _buf[OFFSET_OF(address)] = value; -} - -void QSPIFlash::flush() { - if (_addr == INVALID_ADDR) return; - - _flashBase->eraseSector(_addr / SFLASH_SECTOR_SIZE); - _flashBase->writeBuffer(_addr, _buf, SFLASH_SECTOR_SIZE); - - _addr = INVALID_ADDR; -} - -#endif // QSPI_EEPROM diff --git a/src/HAL/SAMD51/QSPIFlash.h b/src/HAL/SAMD51/QSPIFlash.h deleted file mode 100644 index 58822fe..0000000 --- a/src/HAL/SAMD51/QSPIFlash.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @file QSPIFlash.h - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach and Dean Miller for Adafruit Industries LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Derived from Adafruit_SPIFlash class with no SdFat references - */ -#pragma once - -#include - -// This class extends Adafruit_SPIFlashBase by adding caching support. -// -// This class will use 4096 Bytes of RAM as a block cache. -class QSPIFlash { - public: - static void begin(); - static size_t size(); - static uint8_t readByte(const uint32_t address); - static void writeByte(const uint32_t address, const uint8_t v); - static void flush(); - - private: - static Adafruit_SPIFlashBase * _flashBase; - static uint8_t _buf[SFLASH_SECTOR_SIZE]; - static uint32_t _addr; -}; - -extern QSPIFlash qspi; diff --git a/src/HAL/SAMD51/SAMD51.h b/src/HAL/SAMD51/SAMD51.h deleted file mode 100644 index 7839561..0000000 --- a/src/HAL/SAMD51/SAMD51.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define SYNC(sc) while (sc) { \ - asm(""); \ - } - -// Get SAMD port/pin from specified arduino pin -#define GET_SAMD_PORT(P) _GET_SAMD_PORT(PIN_TO_SAMD_PIN(P)) -#define GET_SAMD_PIN(P) _GET_SAMD_PIN(PIN_TO_SAMD_PIN(P)) - -// Get external interrupt line associated to specified arduino pin -#define PIN_TO_EILINE(P) _SAMDPORTPIN_TO_EILINE(GET_SAMD_PORT(P), GET_SAMD_PIN(P)) - -// Get adc/ain associated to specified arduino pin -#define PIN_TO_ADC(P) (ANAPIN_TO_ADCAIN(P) >> 8) -#define PIN_TO_AIN(P) (ANAPIN_TO_ADCAIN(P) & 0xFF) - -// Private defines -#define PIN_TO_SAMD_PIN(P) DIO##P##_PIN - -#define _GET_SAMD_PORT(P) ((P) >> 5) -#define _GET_SAMD_PIN(P) ((P) & 0x1F) - -// Get external interrupt line -#define _SAMDPORTPIN_TO_EILINE(P,B) ((P == 0 && WITHIN(B, 0, 31) && B != 8 && B != 26 && B != 28 && B != 29) ? (B) & 0xF \ - : (P == 1 && (WITHIN(B, 0, 25) || WITHIN(B, 30, 31))) ? (B) & 0xF \ - : (P == 1 && WITHIN(B, 26, 29)) ? 12 + (B) - 26 \ - : (P == 2 && (WITHIN(B, 0, 6) || WITHIN(B, 10, 31)) && B != 29) ? (B) & 0xF \ - : (P == 2 && B == 7) ? 9 \ - : (P == 3 && WITHIN(B, 0, 1)) ? (B) \ - : (P == 3 && WITHIN(B, 8, 12)) ? 3 + (B) - 8 \ - : (P == 3 && WITHIN(B, 20, 21)) ? 10 + (B) - 20 \ - : -1) - -// Get adc/ain -#define ANAPIN_TO_ADCAIN(P) _PIN_TO_ADCAIN(ANAPIN_TO_SAMDPIN(P)) -#define _PIN_TO_ADCAIN(P) _SAMDPORTPIN_TO_ADCAIN(_GET_SAMD_PORT(P), _GET_SAMD_PIN(P)) - -#define _SAMDPORTPIN_TO_ADCAIN(P,B) ((P == 0 && WITHIN(B, 2, 3)) ? 0x000 + (B) - 2 \ - : (P == 0 && WITHIN(B, 4, 7)) ? 0x000 + (B) \ - : (P == 0 && WITHIN(B, 8, 9)) ? 0x100 + 2 + (B) - 8 \ - : (P == 0 && WITHIN(B, 10, 11)) ? 0x000 + (B) \ - : (P == 1 && WITHIN(B, 0, 3)) ? 0x000 + 12 + (B) \ - : (P == 1 && WITHIN(B, 4, 7)) ? 0x100 + 6 + (B) - 4 \ - : (P == 1 && WITHIN(B, 8, 9)) ? 0x100 + (B) - 8 \ - : (P == 2 && WITHIN(B, 0, 1)) ? 0x100 + 10 + (B) \ - : (P == 2 && WITHIN(B, 2, 3)) ? 0x100 + 4 + (B) - 2 \ - : (P == 2 && WITHIN(B, 30, 31)) ? 0x100 + 12 + (B) - 30 \ - : (P == 3 && WITHIN(B, 0, 1)) ? 0x100 + 14 + (B) \ - : -1) diff --git a/src/HAL/SAMD51/Servo.cpp b/src/HAL/SAMD51/Servo.cpp deleted file mode 100644 index 665322f..0000000 --- a/src/HAL/SAMD51/Servo.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * This comes from Arduino library which at the moment is buggy and uncompilable - */ - -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "../shared/servo.h" -#include "../shared/servo_private.h" -#include "SAMD51.h" - -#define __TC_GCLK_ID(t) TC##t##_GCLK_ID -#define _TC_GCLK_ID(t) __TC_GCLK_ID(t) -#define TC_GCLK_ID _TC_GCLK_ID(SERVO_TC) - -#define _TC_PRESCALER(d) TC_CTRLA_PRESCALER_DIV##d##_Val -#define TC_PRESCALER(d) _TC_PRESCALER(d) - -#define __SERVO_IRQn(t) TC##t##_IRQn -#define _SERVO_IRQn(t) __SERVO_IRQn(t) -#define SERVO_IRQn _SERVO_IRQn(SERVO_TC) - -#define HAL_SERVO_TIMER_ISR() TC_HANDLER(SERVO_TC) - -#define TIMER_TCCHANNEL(t) ((t) & 1) -#define TC_COUNTER_START_VAL 0xFFFF - - -static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) - -FORCE_INLINE static uint16_t getTimerCount() { - Tc * const tc = timer_config[SERVO_TC].pTc; - - tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC; - SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB || tc->COUNT16.SYNCBUSY.bit.COUNT); - - return tc->COUNT16.COUNT.reg; -} - -// ---------------------------- -// Interrupt handler for the TC -// ---------------------------- -HAL_SERVO_TIMER_ISR() { - Tc * const tc = timer_config[SERVO_TC].pTc; - const timer16_Sequence_t timer = - #ifndef _useTimer1 - _timer2 - #elif !defined(_useTimer2) - _timer1 - #else - (tc->COUNT16.INTFLAG.reg & tc->COUNT16.INTENSET.reg & TC_INTFLAG_MC0) ? _timer1 : _timer2 - #endif - ; - const uint8_t tcChannel = TIMER_TCCHANNEL(timer); - - int8_t cho = currentServoIndex[timer]; // Handle the prior servo first - if (cho < 0) { // Servo -1 indicates the refresh interval completed... - #if defined(_useTimer1) && defined(_useTimer2) - if (currentServoIndex[timer ^ 1] >= 0) { - // Wait for both channels - // Clear the interrupt - tc->COUNT16.INTFLAG.reg = (tcChannel == 0) ? TC_INTFLAG_MC0 : TC_INTFLAG_MC1; - return; - } - #endif - tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL; // ...so reset the timer - SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT); - } - else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled? - digitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW - - currentServoIndex[timer] = ++cho; // go to the next channel (or 0) - if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) { - if (SERVO(timer, cho).Pin.isActive) // activated? - digitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH - - tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)SERVO(timer, cho).ticks; - } - else { - // finished all channels so wait for the refresh period to expire before starting over - currentServoIndex[timer] = -1; // reset the timer COUNT.reg on the next call - const uint16_t cval = getTimerCount() - 256 / (SERVO_TIMER_PRESCALER), // allow 256 cycles to ensure the next CV not missed - ival = (TC_COUNTER_START_VAL) - (uint16_t)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed - tc->COUNT16.CC[tcChannel].reg = min(cval, ival); - } - if (tcChannel == 0) { - SYNC(tc->COUNT16.SYNCBUSY.bit.CC0); - tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; // Clear the interrupt - } - else { - SYNC(tc->COUNT16.SYNCBUSY.bit.CC1); - tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1; // Clear the interrupt - } -} - -void initISR(const timer16_Sequence_t timer) { - Tc * const tc = timer_config[SERVO_TC].pTc; - const uint8_t tcChannel = TIMER_TCCHANNEL(timer); - - static bool initialized = false; // Servo TC has been initialized - if (!initialized) { - NVIC_DisableIRQ(SERVO_IRQn); - - // Disable the timer - tc->COUNT16.CTRLA.bit.ENABLE = false; - SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE); - - // Select GCLK0 as timer/counter input clock source - GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN = false; - SYNC(GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN); - GCLK->PCHCTRL[TC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; // 120MHz startup code programmed - SYNC(!GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN); - - // Reset the timer - tc->COUNT16.CTRLA.bit.SWRST = true; - SYNC(tc->COUNT16.SYNCBUSY.bit.SWRST); - SYNC(tc->COUNT16.CTRLA.bit.SWRST); - - // Set timer counter mode to 16 bits - tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16; - - // Set timer counter mode as normal PWM - tc->COUNT16.WAVE.bit.WAVEGEN = TCC_WAVE_WAVEGEN_NPWM_Val; - - // Set the prescaler factor - tc->COUNT16.CTRLA.bit.PRESCALER = TC_PRESCALER(SERVO_TIMER_PRESCALER); - - // Count down - tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_DIR; - SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB); - - // Reset all servo indexes - memset((void *)currentServoIndex, 0xFF, sizeof(currentServoIndex)); - - // Configure interrupt request - NVIC_ClearPendingIRQ(SERVO_IRQn); - NVIC_SetPriority(SERVO_IRQn, 5); - NVIC_EnableIRQ(SERVO_IRQn); - - initialized = true; - } - - if (!tc->COUNT16.CTRLA.bit.ENABLE) { - // Reset the timer counter - tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL; - SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT); - - // Enable the timer and start it - tc->COUNT16.CTRLA.bit.ENABLE = true; - SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE); - } - // First interrupt request after 1 ms - tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)usToTicks(1000UL); - - if (tcChannel == 0 ) { - SYNC(tc->COUNT16.SYNCBUSY.bit.CC0); - - // Clear pending match interrupt - tc->COUNT16.INTFLAG.reg = TC_INTENSET_MC0; - // Enable the match channel interrupt request - tc->COUNT16.INTENSET.reg = TC_INTENSET_MC0; - } - else { - SYNC(tc->COUNT16.SYNCBUSY.bit.CC1); - - // Clear pending match interrupt - tc->COUNT16.INTFLAG.reg = TC_INTENSET_MC1; - // Enable the match channel interrupt request - tc->COUNT16.INTENSET.reg = TC_INTENSET_MC1; - } -} - -void finISR(const timer16_Sequence_t timer_index) { - Tc * const tc = timer_config[SERVO_TC].pTc; - const uint8_t tcChannel = TIMER_TCCHANNEL(timer_index); - - // Disable the match channel interrupt request - tc->COUNT16.INTENCLR.reg = (tcChannel == 0) ? TC_INTENCLR_MC0 : TC_INTENCLR_MC1; - - if (true - #if defined(_useTimer1) && defined(_useTimer2) - && (tc->COUNT16.INTENCLR.reg & (TC_INTENCLR_MC0|TC_INTENCLR_MC1)) == 0 - #endif - ) { - // Disable the timer if not used - tc->COUNT16.CTRLA.bit.ENABLE = false; - SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE); - } -} - -#endif // HAS_SERVOS - -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/ServoTimers.h b/src/HAL/SAMD51/ServoTimers.h deleted file mode 100644 index 948d515..0000000 --- a/src/HAL/SAMD51/ServoTimers.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define _useTimer1 -#define _useTimer2 - -#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays -#define SERVO_TIMER_PRESCALER 64 // timer prescaler factor to 64 (avoid overflowing 16-bit clock counter, at 120MHz this is 1831 ticks per millisecond - -#define SERVO_TC 3 - -typedef enum { - #ifdef _useTimer1 - _timer1, - #endif - #ifdef _useTimer2 - _timer2, - #endif - _Nbr_16timers -} timer16_Sequence_t; diff --git a/src/HAL/SAMD51/eeprom_flash.cpp b/src/HAL/SAMD51/eeprom_flash.cpp deleted file mode 100644 index 871bf22..0000000 --- a/src/HAL/SAMD51/eeprom_flash.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(FLASH_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" - -#define NVMCTRL_CMD(c) do{ \ - SYNC(!NVMCTRL->STATUS.bit.READY); \ - NVMCTRL->INTFLAG.bit.DONE = true; \ - NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \ - SYNC(NVMCTRL->INTFLAG.bit.DONE); \ - }while(0) -#define NVMCTRL_FLUSH() do{ \ - if (NVMCTRL->SEESTAT.bit.LOAD) \ - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \ - }while(0) - -size_t PersistentStore::capacity() { - const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ, - sblk = NVMCTRL->SEESTAT.bit.SBLK; - - return (!psz && !sblk) ? 0 - : (psz <= 2) ? (0x200 << psz) - : (sblk == 1 || psz == 3) ? 4096 - : (sblk == 2 || psz == 4) ? 8192 - : (sblk <= 4 || psz == 5) ? 16384 - : (sblk >= 9 && psz == 7) ? 65536 - : 32768; -} - -bool PersistentStore::access_start() { - NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active - if (NVMCTRL->SEESTAT.bit.RLOCK) - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access - return true; -} - -bool PersistentStore::access_finish() { - NVMCTRL_FLUSH(); - if (!NVMCTRL->SEESTAT.bit.LOCK) - NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - while (size--) { - const uint8_t v = *value; - SYNC(NVMCTRL->SEESTAT.bit.BUSY); - if (NVMCTRL->INTFLAG.bit.SEESFULL) - NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer' - ((volatile uint8_t *)SEEPROM_ADDR)[pos] = v; - SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC); - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - while (size--) { - SYNC(NVMCTRL->SEESTAT.bit.BUSY); - uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos]; - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } - return false; -} - -#endif // FLASH_EEPROM_EMULATION -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/eeprom_qspi.cpp b/src/HAL/SAMD51/eeprom_qspi.cpp deleted file mode 100644 index faa7637..0000000 --- a/src/HAL/SAMD51/eeprom_qspi.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(QSPI_EEPROM) - -#include "../shared/eeprom_api.h" - -#include "QSPIFlash.h" - -static bool initialized; - -size_t PersistentStore::capacity() { return qspi.size(); } - -bool PersistentStore::access_start() { - if (!initialized) { - qspi.begin(); - initialized = true; - } - return true; -} - -bool PersistentStore::access_finish() { - qspi.flush(); - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - while (size--) { - const uint8_t v = *value; - qspi.writeByte(pos, v); - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - while (size--) { - uint8_t c = qspi.readByte(pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } - return false; -} - -#endif // QSPI_EEPROM -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/eeprom_wired.cpp b/src/HAL/SAMD51/eeprom_wired.cpp deleted file mode 100644 index 3481fe5..0000000 --- a/src/HAL/SAMD51/eeprom_wired.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __SAMD51__ - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -/** - * PersistentStore for Arduino-style EEPROM interface - * with simple implementations supplied by Marlin. - */ - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - const uint8_t v = *value; - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - while (size--) { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/endstop_interrupts.h b/src/HAL/SAMD51/endstop_interrupts.h deleted file mode 100644 index 61a06c0..0000000 --- a/src/HAL/SAMD51/endstop_interrupts.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop interrupts for ATMEL SAMD51 based targets. - * - * On SAMD51, all pins support external interrupt capability. - * Any pin can be used for external interrupts, but there are some restrictions. - * At most 16 different external interrupts can be used at one time. - * Further, you can’t just pick any 16 pins to use. This is because every pin on the SAMD51 - * connects to what is called an EXTINT line, and only one pin per EXTINT line can be used for external - * interrupts at a time - */ - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -#define MATCH_EILINE(P1,P2) (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2)) -#define MATCH_X_MAX_EILINE(P) TERN0(HAS_X_MAX, DEFER4(MATCH_EILINE)(P, X_MAX_PIN)) -#define MATCH_X_MIN_EILINE(P) TERN0(HAS_X_MIN, DEFER4(MATCH_EILINE)(P, X_MIN_PIN)) -#define MATCH_Y_MAX_EILINE(P) TERN0(HAS_Y_MAX, DEFER4(MATCH_EILINE)(P, Y_MAX_PIN)) -#define MATCH_Y_MIN_EILINE(P) TERN0(HAS_Y_MIN, DEFER4(MATCH_EILINE)(P, Y_MIN_PIN)) -#define MATCH_Z_MAX_EILINE(P) TERN0(HAS_Z_MAX, DEFER4(MATCH_EILINE)(P, Z_MAX_PIN)) -#define MATCH_Z_MIN_EILINE(P) TERN0(HAS_Z_MIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PIN)) -#define MATCH_I_MAX_EILINE(P) TERN0(HAS_I_MAX, DEFER4(MATCH_EILINE)(P, I_MAX_PIN)) -#define MATCH_I_MIN_EILINE(P) TERN0(HAS_I_MIN, DEFER4(MATCH_EILINE)(P, I_MIN_PIN)) -#define MATCH_J_MAX_EILINE(P) TERN0(HAS_J_MAX, DEFER4(MATCH_EILINE)(P, J_MAX_PIN)) -#define MATCH_J_MIN_EILINE(P) TERN0(HAS_J_MIN, DEFER4(MATCH_EILINE)(P, J_MIN_PIN)) -#define MATCH_K_MAX_EILINE(P) TERN0(HAS_K_MAX, DEFER4(MATCH_EILINE)(P, K_MAX_PIN)) -#define MATCH_K_MIN_EILINE(P) TERN0(HAS_K_MIN, DEFER4(MATCH_EILINE)(P, K_MIN_PIN)) -#define MATCH_Z2_MAX_EILINE(P) TERN0(HAS_Z2_MAX, DEFER4(MATCH_EILINE)(P, Z2_MAX_PIN)) -#define MATCH_Z2_MIN_EILINE(P) TERN0(HAS_Z2_MIN, DEFER4(MATCH_EILINE)(P, Z2_MIN_PIN)) -#define MATCH_Z3_MAX_EILINE(P) TERN0(HAS_Z3_MAX, DEFER4(MATCH_EILINE)(P, Z3_MAX_PIN)) -#define MATCH_Z3_MIN_EILINE(P) TERN0(HAS_Z3_MIN, DEFER4(MATCH_EILINE)(P, Z3_MIN_PIN)) -#define MATCH_Z4_MAX_EILINE(P) TERN0(HAS_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN)) -#define MATCH_Z4_MIN_EILINE(P) TERN0(HAS_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN)) -#define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(HAS_Z_MIN_PROBE_PIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN)) - -#define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \ - && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \ - && !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P) \ - && !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P) \ - && !MATCH_I_MAX_EILINE(P) && !MATCH_I_MIN_EILINE(P) \ - && !MATCH_J_MAX_EILINE(P) && !MATCH_J_MIN_EILINE(P) \ - && !MATCH_K_MAX_EILINE(P) && !MATCH_K_MIN_EILINE(P) \ - && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \ - && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \ - && !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \ - && !MATCH_Z_MIN_PROBE_EILINE(P) ) - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) - #if HAS_X_MAX - #if !AVAILABLE_EILINE(X_MAX_PIN) - #error "X_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(X_MAX_PIN); - #endif - #if HAS_X_MIN - #if !AVAILABLE_EILINE(X_MIN_PIN) - #error "X_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(X_MIN_PIN); - #endif - #if HAS_Y_MAX - #if !AVAILABLE_EILINE(Y_MAX_PIN) - #error "Y_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(Y_MAX_PIN); - #endif - #if HAS_Y_MIN - #if !AVAILABLE_EILINE(Y_MIN_PIN) - #error "Y_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(Y_MIN_PIN); - #endif - #if HAS_Z_MAX - #if !AVAILABLE_EILINE(Z_MAX_PIN) - #error "Z_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(Z_MAX_PIN); - #endif - #if HAS_Z_MIN - #if !AVAILABLE_EILINE(Z_MIN_PIN) - #error "Z_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(Z_MIN_PIN); - #endif - #if HAS_Z2_MAX - #if !AVAILABLE_EILINE(Z2_MAX_PIN) - #error "Z2_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(Z2_MAX_PIN); - #endif - #if HAS_Z2_MIN - #if !AVAILABLE_EILINE(Z2_MIN_PIN) - #error "Z2_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(Z2_MIN_PIN); - #endif - #if HAS_Z3_MAX - #if !AVAILABLE_EILINE(Z3_MAX_PIN) - #error "Z3_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(Z3_MAX_PIN); - #endif - #if HAS_Z3_MIN - #if !AVAILABLE_EILINE(Z3_MIN_PIN) - #error "Z3_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(Z3_MIN_PIN); - #endif - #if HAS_Z4_MAX - #if !AVAILABLE_EILINE(Z4_MAX_PIN) - #error "Z4_MAX_PIN has no EXTINT line available." - #endif - _ATTACH(Z4_MAX_PIN); - #endif - #if HAS_Z4_MIN - #if !AVAILABLE_EILINE(Z4_MIN_PIN) - #error "Z4_MIN_PIN has no EXTINT line available." - #endif - _ATTACH(Z4_MIN_PIN); - #endif - #if HAS_Z_MIN_PROBE_PIN - #if !AVAILABLE_EILINE(Z_MIN_PROBE_PIN) - #error "Z_MIN_PROBE_PIN has no EXTINT line available." - #endif - _ATTACH(Z_MIN_PROBE_PIN); - #endif - #if HAS_I_MAX - #if !AVAILABLE_EILINE(I_MAX_PIN) - #error "I_MAX_PIN has no EXTINT line available." - #endif - attachInterrupt(I_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_I_MIN - #if !AVAILABLE_EILINE(I_MIN_PIN) - #error "I_MIN_PIN has no EXTINT line available." - #endif - attachInterrupt(I_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_J_MAX - #if !AVAILABLE_EILINE(J_MAX_PIN) - #error "J_MAX_PIN has no EXTINT line available." - #endif - attachInterrupt(J_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_J_MIN - #if !AVAILABLE_EILINE(J_MIN_PIN) - #error "J_MIN_PIN has no EXTINT line available." - #endif - attachInterrupt(J_MIN_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_K_MAX - #if !AVAILABLE_EILINE(K_MAX_PIN) - #error "K_MAX_PIN has no EXTINT line available." - #endif - attachInterrupt(K_MAX_PIN, endstop_ISR, CHANGE); - #endif - #if HAS_K_MIN - #if !AVAILABLE_EILINE(K_MIN_PIN) - #error "K_MIN_PIN has no EXTINT line available." - #endif - attachInterrupt(K_MIN_PIN, endstop_ISR, CHANGE); - #endif -} diff --git a/src/HAL/SAMD51/fastio.h b/src/HAL/SAMD51/fastio.h deleted file mode 100644 index 79aede5..0000000 --- a/src/HAL/SAMD51/fastio.h +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast IO functions for SAMD51 - */ - -#include "SAMD51.h" - -/** - * Utility functions - */ - -#ifndef MASK - #define MASK(PIN) _BV(PIN) -#endif - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(IO); WRITE(IO, HIGH); WRITE(IO, LOW); - */ - -// Read a pin -#define READ(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].IN.reg & MASK(GET_SAMD_PIN(IO))) != 0) - -// Write to a pin -#define WRITE(IO,V) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t mask = MASK(GET_SAMD_PIN(IO)); \ - \ - if (V) PORT->Group[port].OUTSET.reg = mask; \ - else PORT->Group[port].OUTCLR.reg = mask; \ - }while(0) - -// Toggle a pin -#define TOGGLE(IO) PORT->Group[(EPortType)GET_SAMD_PORT(IO)].OUTTGL.reg = MASK(GET_SAMD_PIN(IO)); - -// Set pin as input -#define SET_INPUT(IO) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t pin = GET_SAMD_PIN(IO); \ - \ - PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN); \ - PORT->Group[port].DIRCLR.reg = MASK(pin); \ - }while(0) -// Set pin as input with pullup -#define SET_INPUT_PULLUP(IO) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t pin = GET_SAMD_PIN(IO); \ - const uint32_t mask = MASK(pin); \ - \ - PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); \ - PORT->Group[port].DIRCLR.reg = mask; \ - PORT->Group[port].OUTSET.reg = mask; \ - }while(0) -// Set pin as input with pulldown -#define SET_INPUT_PULLDOWN(IO) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t pin = GET_SAMD_PIN(IO); \ - const uint32_t mask = MASK(pin); \ - \ - PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); \ - PORT->Group[port].DIRCLR.reg = mask; \ - PORT->Group[port].OUTCLR.reg = mask; \ - }while(0) -// Set pin as output (push pull) -#define SET_OUTPUT(IO) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t pin = GET_SAMD_PIN(IO); \ - \ - PORT->Group[port].DIRSET.reg = MASK(pin); \ - PORT->Group[port].PINCFG[pin].reg = 0; \ - }while(0) -// Set pin as output (open drain) -#define SET_OUTPUT_OD(IO) do{ \ - const EPortType port = (EPortType)GET_SAMD_PORT(IO); \ - const uint32_t pin = GET_SAMD_PIN(IO); \ - \ - PORT->Group[port].PINCFG[pin].reg = (uint8_t)(PORT_PINCFG_PULLEN); \ - PORT->Group[port].DIRCLR.reg = MASK(pin); \ - }while(0) -// Set pin as PWM (push pull) -#define SET_PWM SET_OUTPUT -// Set pin as PWM (open drain) -#define SET_PWM_OD SET_OUTPUT_OD - -// check if pin is an output -#define IS_OUTPUT(IO) ((PORT->Group[(EPortType)GET_SAMD_PORT(IO)].DIR.reg & MASK(GET_SAMD_PIN(IO))) \ - || (PORT->Group[(EPortType)GET_SAMD_PORT(IO)].PINCFG[GET_SAMD_PIN(IO)].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN) -// check if pin is an input -#define IS_INPUT(IO) !IS_OUTPUT(IO) - -// Shorthand -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) -#define OUT_WRITE_OD(IO,V) do{ SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -/** - * Ports and functions - * Added as necessary or if I feel like it- not a comprehensive list! - */ - -#ifdef ADAFRUIT_GRAND_CENTRAL_M4 - - /* - * Adafruit Grand Central M4 has a lot of PWMs the availables are listed here. - * Some of these share the same source and so can't be used in the same time - */ - #define PWM_PIN(P) (WITHIN(P, 2, 13) || WITHIN(P, 22, 23) || WITHIN(P, 44, 45) || P == 48) - - // Return fulfilled ADCx->INPUTCTRL.reg - #define PIN_TO_INPUTCTRL(P) ( (PIN_TO_AIN(P) == 0) ? ADC_INPUTCTRL_MUXPOS_AIN0 \ - : (PIN_TO_AIN(P) == 1) ? ADC_INPUTCTRL_MUXPOS_AIN1 \ - : (PIN_TO_AIN(P) == 2) ? ADC_INPUTCTRL_MUXPOS_AIN2 \ - : (PIN_TO_AIN(P) == 3) ? ADC_INPUTCTRL_MUXPOS_AIN3 \ - : (PIN_TO_AIN(P) == 4) ? ADC_INPUTCTRL_MUXPOS_AIN4 \ - : (PIN_TO_AIN(P) == 5) ? ADC_INPUTCTRL_MUXPOS_AIN5 \ - : (PIN_TO_AIN(P) == 6) ? ADC_INPUTCTRL_MUXPOS_AIN6 \ - : (PIN_TO_AIN(P) == 7) ? ADC_INPUTCTRL_MUXPOS_AIN7 \ - : (PIN_TO_AIN(P) == 8) ? ADC_INPUTCTRL_MUXPOS_AIN8 \ - : (PIN_TO_AIN(P) == 9) ? ADC_INPUTCTRL_MUXPOS_AIN9 \ - : (PIN_TO_AIN(P) == 10) ? ADC_INPUTCTRL_MUXPOS_AIN10 \ - : (PIN_TO_AIN(P) == 11) ? ADC_INPUTCTRL_MUXPOS_AIN11 \ - : (PIN_TO_AIN(P) == 12) ? ADC_INPUTCTRL_MUXPOS_AIN12 \ - : (PIN_TO_AIN(P) == 13) ? ADC_INPUTCTRL_MUXPOS_AIN13 \ - : (PIN_TO_AIN(P) == 14) ? ADC_INPUTCTRL_MUXPOS_AIN14 \ - : ADC_INPUTCTRL_MUXPOS_AIN15) - - #define ANAPIN_TO_SAMDPIN(P) ( (P == 0) ? PIN_TO_SAMD_PIN(67) \ - : (P == 1) ? PIN_TO_SAMD_PIN(68) \ - : (P == 2) ? PIN_TO_SAMD_PIN(69) \ - : (P == 3) ? PIN_TO_SAMD_PIN(70) \ - : (P == 4) ? PIN_TO_SAMD_PIN(71) \ - : (P == 5) ? PIN_TO_SAMD_PIN(72) \ - : (P == 6) ? PIN_TO_SAMD_PIN(73) \ - : (P == 7) ? PIN_TO_SAMD_PIN(74) \ - : (P == 8) ? PIN_TO_SAMD_PIN(54) \ - : (P == 9) ? PIN_TO_SAMD_PIN(55) \ - : (P == 10) ? PIN_TO_SAMD_PIN(56) \ - : (P == 11) ? PIN_TO_SAMD_PIN(57) \ - : (P == 12) ? PIN_TO_SAMD_PIN(58) \ - : (P == 13) ? PIN_TO_SAMD_PIN(59) \ - : (P == 14) ? PIN_TO_SAMD_PIN(60) \ - : (P == 15) ? PIN_TO_SAMD_PIN(61) \ - : (P == 16) ? PIN_TO_SAMD_PIN(12) \ - : (P == 17) ? PIN_TO_SAMD_PIN(13) \ - : PIN_TO_SAMD_PIN(9)) - - #define digitalPinToAnalogInput(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) - - /* - * pins - */ - - // PORTA - #define DIO67_PIN PIN_PA02 // A0 - #define DIO59_PIN PIN_PA04 // A13 - #define DIO68_PIN PIN_PA05 // A1 - #define DIO60_PIN PIN_PA06 // A14 - #define DIO61_PIN PIN_PA07 // A15 - #define DIO26_PIN PIN_PA12 - #define DIO27_PIN PIN_PA13 - #define DIO28_PIN PIN_PA14 - #define DIO23_PIN PIN_PA15 - #define DIO37_PIN PIN_PA16 - #define DIO36_PIN PIN_PA17 - #define DIO35_PIN PIN_PA18 - #define DIO34_PIN PIN_PA19 - #define DIO33_PIN PIN_PA20 - #define DIO32_PIN PIN_PA21 - #define DIO31_PIN PIN_PA22 - #define DIO30_PIN PIN_PA23 - // PORTB - #define DIO12_PIN PIN_PB00 // A16 - #define DIO13_PIN PIN_PB01 // A17 - #define DIO9_PIN PIN_PB02 // A18 - #define DIO69_PIN PIN_PB03 // A2 - #define DIO74_PIN PIN_PB04 // A7 - #define DIO54_PIN PIN_PB05 // A8 - #define DIO55_PIN PIN_PB06 // A9 - #define DIO56_PIN PIN_PB07 // A10 - #define DIO57_PIN PIN_PB08 // A11 - #define DIO58_PIN PIN_PB09 // A12 - #define DIO18_PIN PIN_PB12 - #define DIO19_PIN PIN_PB13 - #define DIO39_PIN PIN_PB14 - #define DIO38_PIN PIN_PB15 - #define DIO14_PIN PIN_PB16 - #define DIO15_PIN PIN_PB17 - #define DIO8_PIN PIN_PB18 - #define DIO29_PIN PIN_PB19 - #define DIO20_PIN PIN_PB20 - #define DIO21_PIN PIN_PB21 - #define DIO10_PIN PIN_PB22 - #define DIO11_PIN PIN_PB23 - #define DIO1_PIN PIN_PB24 - #define DIO0_PIN PIN_PB25 - #define DIO83_PIN PIN_PB28 // SD_CS - #define DIO95_PIN PIN_PB31 // SD_CD - // PORTC - #define DIO70_PIN PIN_PC00 // A3 - #define DIO71_PIN PIN_PC01 // A4 - #define DIO72_PIN PIN_PC02 // A5 - #define DIO73_PIN PIN_PC03 // A6 - #define DIO48_PIN PIN_PC04 - #define DIO49_PIN PIN_PC05 - #define DIO46_PIN PIN_PC06 - #define DIO47_PIN PIN_PC07 - #define DIO45_PIN PIN_PC10 - #define DIO44_PIN PIN_PC11 - #define DIO41_PIN PIN_PC12 - #define DIO40_PIN PIN_PC13 - #define DIO43_PIN PIN_PC14 - #define DIO42_PIN PIN_PC15 - #define DIO25_PIN PIN_PC16 - #define DIO24_PIN PIN_PC17 - #define DIO2_PIN PIN_PC18 - #define DIO3_PIN PIN_PC19 - #define DIO4_PIN PIN_PC20 - #define DIO5_PIN PIN_PC21 - #define DIO16_PIN PIN_PC22 - #define DIO17_PIN PIN_PC23 - #define DIO88_PIN PIN_PC24 // NEOPIXEL - // PORTD - #define DIO53_PIN PIN_PD10 - #define DIO22_PIN PIN_PD12 - #define DIO6_PIN PIN_PD20 - #define DIO7_PIN PIN_PD21 - -#endif // ADAFRUIT_GRAND_CENTRAL_M4 diff --git a/src/HAL/SAMD51/inc/Conditionals_LCD.h b/src/HAL/SAMD51/inc/Conditionals_LCD.h deleted file mode 100644 index 932348c..0000000 --- a/src/HAL/SAMD51/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/SAMD51." -#endif diff --git a/src/HAL/SAMD51/inc/Conditionals_adv.h b/src/HAL/SAMD51/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/SAMD51/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/SAMD51/inc/Conditionals_post.h b/src/HAL/SAMD51/inc/Conditionals_post.h deleted file mode 100644 index ce6d3fd..0000000 --- a/src/HAL/SAMD51/inc/Conditionals_post.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define FLASH_EEPROM_EMULATION -#elif EITHER(I2C_EEPROM, SPI_EEPROM) - #define USE_SHARED_EEPROM 1 -#endif diff --git a/src/HAL/SAMD51/inc/SanityCheck.h b/src/HAL/SAMD51/inc/SanityCheck.h deleted file mode 100644 index 1b876c9..0000000 --- a/src/HAL/SAMD51/inc/SanityCheck.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Test SAMD51 specific configuration values for errors at compile-time. - */ - -#if ENABLED(FLASH_EEPROM_EMULATION) - #warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Manager/releases" -#endif - -#if defined(ADAFRUIT_GRAND_CENTRAL_M4) && SD_CONNECTION_IS(CUSTOM_CABLE) - #error "No custom SD drive cable defined for this board." -#endif - -#if (defined(TEMP_0_SCK_PIN) && defined(TEMP_0_MISO_PIN) && (TEMP_0_SCK_PIN == SCK1 || TEMP_0_MISO_PIN == MISO1)) || \ - (defined(TEMP_1_SCK_PIN) && defined(TEMP_1_MISO_PIN) && (TEMP_1_SCK_PIN == SCK1 || TEMP_1_MISO_PIN == MISO1)) - #error "OnBoard SPI BUS can't be shared with other devices." -#endif - -#if SERVO_TC == MF_TIMER_RTC - #error "Servos can't use RTC timer" -#endif - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for SAMD51. Disable EMERGENCY_PARSER to continue." -#endif - -#if ENABLED(SDIO_SUPPORT) - #error "SDIO_SUPPORT is not supported on SAMD51." -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on SAMD51." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on AGCM4." -#endif diff --git a/src/HAL/SAMD51/pinsDebug.h b/src/HAL/SAMD51/pinsDebug.h deleted file mode 100644 index f0a46fd..0000000 --- a/src/HAL/SAMD51/pinsDebug.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define NUMBER_PINS_TOTAL PINS_COUNT - -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PORT(p) do{ SERIAL_ECHOPGM(" Port: "); sprintf_P(buffer, PSTR("%c%02ld"), 'A' + g_APinDescription[p].ulPort, g_APinDescription[p].ulPin); SERIAL_ECHO(buffer); }while (0) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p) -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1) -#define pwm_status(pin) digitalPinHasPWM(pin) -#define MULTI_NAME_PAD 27 // space needed to be pretty if not first name assigned to a pin - -// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities -// uses pin index -#define M43_NEVER_TOUCH(Q) ((Q) >= 75) - -bool GET_PINMODE(int8_t pin) { // 1: output, 0: input - const EPortType samdport = g_APinDescription[pin].ulPort; - const uint32_t samdpin = g_APinDescription[pin].ulPin; - return PORT->Group[samdport].DIR.reg & MASK(samdpin) || (PORT->Group[samdport].PINCFG[samdpin].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN; -} - -void pwm_details(int32_t pin) { - if (pwm_status(pin)) { - //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative; - //SERIAL_ECHOPGM("PWM = ", duty); - } -} - -/** - * AGCM4 Board pin | PORT | Label - * ----------------+--------+------- - * 0 | PB25 | "RX0" - * 1 | PB24 | "TX0" - * 2 | PC18 | - * 3 | PC19 | - * 4 | PC20 | - * 5 | PC21 | - * 6 | PD20 | - * 7 | PD21 | - * 8 | PB18 | - * 9 | PB2 | - * 10 | PB22 | - * 11 | PB23 | - * 12 | PB0 | "A16" - * 13 | PB1 | LED AMBER "L" / "A17" - * 14 | PB16 | "TX3" - * 15 | PB17 | "RX3" - * 16 | PC22 | "TX2" - * 17 | PC23 | "RX2" - * 18 | PB12 | "TX1" / "A18" - * 19 | PB13 | "RX1" - * 20 | PB20 | "SDA" - * 21 | PB21 | "SCL" - * 22 | PD12 | - * 23 | PA15 | - * 24 | PC17 | - * 25 | PC16 | - * 26 | PA12 | - * 27 | PA13 | - * 28 | PA14 | - * 29 | PB19 | - * 30 | PA23 | - * 31 | PA22 | - * 32 | PA21 | - * 33 | PA20 | - * 34 | PA19 | - * 35 | PA18 | - * 36 | PA17 | - * 37 | PA16 | - * 38 | PB15 | - * 39 | PB14 | - * 40 | PC13 | - * 41 | PC12 | - * 42 | PC15 | - * 43 | PC14 | - * 44 | PC11 | - * 45 | PC10 | - * 46 | PC6 | - * 47 | PC7 | - * 48 | PC4 | - * 49 | PC5 | - * 50 | PD11 | - * 51 | PD8 | - * 52 | PD9 | - * 53 | PD10 | - * 54 | PB5 | "A8" - * 55 | PB6 | "A9" - * 56 | PB7 | "A10" - * 57 | PB8 | "A11" - * 58 | PB9 | "A12" - * 69 | PA4 | "A13" - * 60 | PA6 | "A14" - * 61 | PA7 | "A15" - * 62 | PB17 | - * 63 | PB20 | - * 64 | PD11 | - * 65 | PD8 | - * 66 | PD9 | - * 67 | PA2 | "A0" / "DAC0" - * 68 | PA5 | "A1" / "DAC1" - * 69 | PB3 | "A2" - * 70 | PC0 | "A3" - * 71 | PC1 | "A4" - * 72 | PC2 | "A5" - * 73 | PC3 | "A6" - * 74 | PB4 | "A7" - * 75 | PC31 | LED GREEN "RX" - * 76 | PC30 | LED GREEN "TX" - * 77 | PA27 | USB: Host enable - * 78 | PA24 | USB: D- - * 79 | PA25 | USB: D+ - * 80 | PB29 | SD: MISO - * 81 | PB27 | SD: SCK - * 82 | PB26 | SD: MOSI - * 83 | PB28 | SD: CS - * 84 | PA3 | AREF - * 85 | PA2 | DAC0 (Duplicate) - * 86 | PA5 | DAC1 (Duplicate) - * 87 | PB1 | LED AMBER "L" (Duplicate) - * 88 | PC24 | NeoPixel - * 89 | PB10 | QSPI: SCK - * 90 | PB11 | QSPI: CS - * 91 | PA8 | QSPI: IO0 - * 92 | PA9 | QSPI: IO1 - * 93 | PA10 | QSPI: IO2 - * 94 | PA11 | QSPI: IO3 - * 95 | PB31 | SD: DETECT - */ diff --git a/src/HAL/SAMD51/spi_pins.h b/src/HAL/SAMD51/spi_pins.h deleted file mode 100644 index 2a667bc..0000000 --- a/src/HAL/SAMD51/spi_pins.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef ADAFRUIT_GRAND_CENTRAL_M4 - - /* - * AGCM4 Default SPI Pins - * - * SS SCK MISO MOSI - * +-------------------------+ - * SPI | 53 52 50 51 | - * SPI1 | 83 81 80 82 | - * +-------------------------+ - * Any pin can be used for Chip Select (SD_SS_PIN) - */ - #ifndef SD_SCK_PIN - #define SD_SCK_PIN 52 - #endif - #ifndef SD_MISO_PIN - #define SD_MISO_PIN 50 - #endif - #ifndef SD_MOSI_PIN - #define SD_MOSI_PIN 51 - #endif - #ifndef SDSS - #define SDSS 53 - #endif - -#else - - #error "Unsupported board!" - -#endif - -#define SD_SS_PIN SDSS diff --git a/src/HAL/SAMD51/timers.cpp b/src/HAL/SAMD51/timers.cpp deleted file mode 100644 index 1ad0e36..0000000 --- a/src/HAL/SAMD51/timers.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __SAMD51__ - -// -------------------------------------------------------------------------- -// Includes -// -------------------------------------------------------------------------- - -#include "../../inc/MarlinConfig.h" -#include "ServoTimers.h" // for SERVO_TC - -// -------------------------------------------------------------------------- -// Local defines -// -------------------------------------------------------------------------- - -#define NUM_HARDWARE_TIMERS 9 - -// -------------------------------------------------------------------------- -// Private Variables -// -------------------------------------------------------------------------- - -const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = { - { {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper (assigned priority 2) - { {.pTc=TC1}, TC1_IRQn, TC_PRIORITY(1) }, // 1 - stepper (needed by 32 bit timers) - { {.pTc=TC2}, TC2_IRQn, 5 }, // 2 - tone (reserved by framework and fixed assigned priority 5) - { {.pTc=TC3}, TC3_IRQn, TC_PRIORITY(3) }, // 3 - servo (assigned priority 1) - { {.pTc=TC4}, TC4_IRQn, TC_PRIORITY(4) }, // 4 - software serial (no interrupts used) - { {.pTc=TC5}, TC5_IRQn, TC_PRIORITY(5) }, - { {.pTc=TC6}, TC6_IRQn, TC_PRIORITY(6) }, - { {.pTc=TC7}, TC7_IRQn, TC_PRIORITY(7) }, - { {.pRtc=RTC}, RTC_IRQn, TC_PRIORITY(8) } // 8 - temperature (assigned priority 6) -}; - -// -------------------------------------------------------------------------- -// Private functions -// -------------------------------------------------------------------------- - -FORCE_INLINE void Disable_Irq(IRQn_Type irq) { - NVIC_DisableIRQ(irq); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); -} - -// -------------------------------------------------------------------------- -// Public functions -// -------------------------------------------------------------------------- - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - IRQn_Type irq = timer_config[timer_num].IRQ_Id; - - // Disable interrupt, just in case it was already enabled - Disable_Irq(irq); - - if (timer_num == MF_TIMER_RTC) { - Rtc * const rtc = timer_config[timer_num].pRtc; - - // Disable timer interrupt - rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; - - // RTC clock setup - OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768kHz oscillator - - // Stop timer, just in case, to be able to reconfigure it - rtc->MODE0.CTRLA.bit.ENABLE = false; - SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE); - - // Mode, reset counter on match - rtc->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_MODE_COUNT32 | RTC_MODE0_CTRLA_MATCHCLR; - - // Set compare value - rtc->MODE0.COMP[0].reg = (32768 + frequency / 2) / frequency; - SYNC(rtc->MODE0.SYNCBUSY.bit.COMP0); - - // Enable interrupt on compare - rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; // reset pending interrupt - rtc->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; // enable compare 0 interrupt - - // And start timer - rtc->MODE0.CTRLA.bit.ENABLE = true; - SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE); - } - else { - Tc * const tc = timer_config[timer_num].pTc; - - // Disable timer interrupt - tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt - - // TCn clock setup - const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num]; // TC clock are preceded by TCC ones - GCLK->PCHCTRL[clockID].bit.CHEN = false; - SYNC(GCLK->PCHCTRL[clockID].bit.CHEN); - GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; // 120MHz startup code programmed - SYNC(!GCLK->PCHCTRL[clockID].bit.CHEN); - - // Stop timer, just in case, to be able to reconfigure it - tc->COUNT32.CTRLA.bit.ENABLE = false; - SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE); - - // Reset timer - tc->COUNT32.CTRLA.bit.SWRST = true; - SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST); - - // Wave mode, reset counter on compare match - tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; - tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1; - tc->COUNT32.CTRLBCLR.reg = TC_CTRLBCLR_DIR; - SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB); - - // Set compare value - tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency; - tc->COUNT32.COUNT.reg = 0; - - // Enable interrupt on compare - tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; // reset pending interrupt - tc->COUNT32.INTENSET.reg = TC_INTENSET_OVF; // enable overflow interrupt - - // And start timer - tc->COUNT32.CTRLA.bit.ENABLE = true; - SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE); - } - - // Finally, enable IRQ - NVIC_SetPriority(irq, timer_config[timer_num].priority); - NVIC_EnableIRQ(irq); -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - const IRQn_Type irq = timer_config[timer_num].IRQ_Id; - NVIC_EnableIRQ(irq); -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - const IRQn_Type irq = timer_config[timer_num].IRQ_Id; - Disable_Irq(irq); -} - -// missing from CMSIS: Check if interrupt is enabled or not -static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) { - return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - const IRQn_Type irq = timer_config[timer_num].IRQ_Id; - return NVIC_GetEnabledIRQ(irq); -} - -#endif // __SAMD51__ diff --git a/src/HAL/SAMD51/timers.h b/src/HAL/SAMD51/timers.h deleted file mode 100644 index 86e980c..0000000 --- a/src/HAL/SAMD51/timers.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -// -------------------------------------------------------------------------- -// Defines -// -------------------------------------------------------------------------- - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals - -#define MF_TIMER_RTC 8 // This is not a TC but a RTC - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature -#endif - -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) -#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#define TC_PRIORITY(t) ( t == SERVO_TC ? 1 \ - : (t == MF_TIMER_STEP || t == MF_TIMER_PULSE) ? 2 \ - : (t == MF_TIMER_TEMP) ? 6 : 7 ) - -#define _TC_HANDLER(t) void TC##t##_Handler() -#define TC_HANDLER(t) _TC_HANDLER(t) -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() TC_HANDLER(MF_TIMER_STEP) -#endif -#if MF_TIMER_STEP != MF_TIMER_PULSE - #define HAL_PULSE_TIMER_ISR() TC_HANDLER(MF_TIMER_PULSE) -#endif -#if MF_TIMER_TEMP == MF_TIMER_RTC - #define HAL_TEMP_TIMER_ISR() void RTC_Handler() -#else - #define HAL_TEMP_TIMER_ISR() TC_HANDLER(MF_TIMER_TEMP) -#endif - -// -------------------------------------------------------------------------- -// Types -// -------------------------------------------------------------------------- - -typedef struct { - union { - Tc *pTc; - Rtc *pRtc; - }; - IRQn_Type IRQ_Id; - uint8_t priority; -} tTimerConfig; - -// -------------------------------------------------------------------------- -// Public Variables -// -------------------------------------------------------------------------- - -extern const tTimerConfig timer_config[]; - -// -------------------------------------------------------------------------- -// Public functions -// -------------------------------------------------------------------------- - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - // Should never be called with timer MF_TIMER_RTC - Tc * const tc = timer_config[timer_num].pTc; - tc->COUNT32.CC[0].reg = compare; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - // Should never be called with timer MF_TIMER_RTC - Tc * const tc = timer_config[timer_num].pTc; - return (hal_timer_t)tc->COUNT32.CC[0].reg; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - // Should never be called with timer MF_TIMER_RTC - Tc * const tc = timer_config[timer_num].pTc; - tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC; - SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT); - return tc->COUNT32.COUNT.reg; -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { - if (timer_num == MF_TIMER_RTC) { - Rtc * const rtc = timer_config[timer_num].pRtc; - // Clear interrupt flag - rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; - } - else { - Tc * const tc = timer_config[timer_num].pTc; - // Clear interrupt flag - tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; - } -} - -#define HAL_timer_isr_epilogue(timer_num) diff --git a/src/HAL/STM32/HAL.cpp b/src/HAL/STM32/HAL.cpp deleted file mode 100644 index aff52f5..0000000 --- a/src/HAL/STM32/HAL.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" -#include "../shared/Delay.h" - -#include "usb_serial.h" - -#ifdef USBCON - DefaultSerial1 MSerialUSB(false, SerialUSB); -#endif - -#if ENABLED(SRAM_EEPROM_EMULATION) - #if STM32F7xx - #include - #elif STM32F4xx - #include - #else - #error "SRAM_EEPROM_EMULATION is currently only supported for STM32F4xx and STM32F7xx" - #endif -#endif - -#if HAS_SD_HOST_DRIVE - #include "msc_sd.h" - #include "usbd_cdc_if.h" -#endif - -// ------------------------ -// Public Variables -// ------------------------ - -uint16_t MarlinHAL::adc_result; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(POSTMORTEM_DEBUGGING) - extern void install_min_serial(); -#endif - -// HAL initialization task -void MarlinHAL::init() { - // Ensure F_CPU is a constant expression. - // If the compiler breaks here, it means that delay code that should compute at compile time will not work. - // So better safe than sorry here. - constexpr int cpuFreq = F_CPU; - UNUSED(cpuFreq); - - #if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1) - OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up - #endif - - #if PIN_EXISTS(LED) - OUT_WRITE(LED_PIN, LOW); - #endif - - #if ENABLED(SRAM_EEPROM_EMULATION) - __HAL_RCC_PWR_CLK_ENABLE(); - HAL_PWR_EnableBkUpAccess(); // Enable access to backup SRAM - __HAL_RCC_BKPSRAM_CLK_ENABLE(); - LL_PWR_EnableBkUpRegulator(); // Enable backup regulator - while (!LL_PWR_IsActiveFlag_BRR()); // Wait until backup regulator is initialized - #endif - - SetTimerInterruptPriorities(); - - #if ENABLED(EMERGENCY_PARSER) && (USBD_USE_CDC || USBD_USE_CDC_MSC) - USB_Hook_init(); - #endif - - TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler - - TERN_(HAS_SD_HOST_DRIVE, MSC_SD_init()); // Enable USB SD card access - - #if PIN_EXISTS(USB_CONNECT) - OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection - delay(1000); // Give OS time to notice - WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); - #endif -} - -// HAL idle task -void MarlinHAL::idletask() { - #if HAS_SHARED_MEDIA - // Stm32duino currently doesn't have a "loop/idle" method - CDC_resume_receive(); - CDC_continue_transmit(); - #endif -} - -void MarlinHAL::reboot() { NVIC_SystemReset(); } - -uint8_t MarlinHAL::get_reset_source() { - return - #ifdef RCC_FLAG_IWDGRST // Some sources may not exist... - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG : - #endif - #ifdef RCC_FLAG_IWDG1RST - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDG1RST) ? RST_WATCHDOG : - #endif - #ifdef RCC_FLAG_IWDG2RST - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDG2RST) ? RST_WATCHDOG : - #endif - #ifdef RCC_FLAG_SFTRST - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) ? RST_SOFTWARE : - #endif - #ifdef RCC_FLAG_PINRST - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) ? RST_EXTERNAL : - #endif - #ifdef RCC_FLAG_PORRST - RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) ? RST_POWER_ON : - #endif - 0 - ; -} - -void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); } - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout - - #include - - void MarlinHAL::watchdog_init() { - IF_DISABLED(DISABLE_WATCHDOG_INIT, IWatchdog.begin(WDT_TIMEOUT_US)); - } - - void MarlinHAL::watchdog_refresh() { - IWatchdog.reload(); - #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) - TOGGLE(LED_PIN); // heartbeat indicator - #endif - } - -#endif - -extern "C" { - extern unsigned int _ebss; // end of bss section -} - -// Reset the system to initiate a firmware flash -WEAK void flashFirmware(const int16_t) { hal.reboot(); } - -// Maple Compatibility -volatile uint32_t systick_uptime_millis = 0; -systickCallback_t systick_user_callback; -void systick_attach_callback(systickCallback_t cb) { systick_user_callback = cb; } -void HAL_SYSTICK_Callback() { - systick_uptime_millis++; - if (systick_user_callback) systick_user_callback(); -} - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/HAL.h b/src/HAL/STM32/HAL.h deleted file mode 100644 index 3e85aca..0000000 --- a/src/HAL/STM32/HAL.h +++ /dev/null @@ -1,281 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define CPU_32_BIT - -#include "../../core/macros.h" -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" -#include "fastio.h" -#include "Servo.h" -#include "MarlinSerial.h" - -#include "../../inc/MarlinConfigPre.h" - -#include - -// -// Default graphical display delays -// -#define CPU_ST7920_DELAY_1 300 -#define CPU_ST7920_DELAY_2 40 -#define CPU_ST7920_DELAY_3 340 - -// ------------------------ -// Serial ports -// ------------------------ -#ifdef USBCON - #include - #include "../../core/serial_hook.h" - typedef ForwardSerial1Class< decltype(SerialUSB) > DefaultSerial1; - extern DefaultSerial1 MSerialUSB; -#endif - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if WITHIN(SERIAL_PORT, 1, 6) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#elif !defined(USBCON) - #error "SERIAL_PORT must be from 1 to 6." -#elif SERIAL_PORT == -1 - #define MYSERIAL1 MSerialUSB -#else - #error "SERIAL_PORT must be from 1 to 6, or -1 for Native USB." -#endif - -#ifdef SERIAL_PORT_2 - #if WITHIN(SERIAL_PORT_2, 1, 6) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #elif !defined(USBCON) - #error "SERIAL_PORT must be from 1 to 6." - #elif SERIAL_PORT_2 == -1 - #define MYSERIAL2 MSerialUSB - #else - #error "SERIAL_PORT_2 must be from 1 to 6, or -1 for Native USB." - #endif -#endif - -#ifdef SERIAL_PORT_3 - #if WITHIN(SERIAL_PORT_3, 1, 6) - #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) - #elif !defined(USBCON) - #error "SERIAL_PORT must be from 1 to 6." - #elif SERIAL_PORT_3 == -1 - #define MYSERIAL3 MSerialUSB - #else - #error "SERIAL_PORT_3 must be from 1 to 6, or -1 for Native USB." - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if WITHIN(MMU2_SERIAL_PORT, 1, 6) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #elif !defined(USBCON) - #error "SERIAL_PORT must be from 1 to 6." - #elif MMU2_SERIAL_PORT == -1 - #define MMU2_SERIAL MSerialUSB - #else - #error "MMU2_SERIAL_PORT must be from 1 to 6, or -1 for Native USB." - #endif -#endif - -#ifdef LCD_SERIAL_PORT - #if WITHIN(LCD_SERIAL_PORT, 1, 6) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #elif !defined(USBCON) - #error "SERIAL_PORT must be from 1 to 6." - #elif LCD_SERIAL_PORT == -1 - #define LCD_SERIAL MSerialUSB - #else - #error "LCD_SERIAL_PORT must be from 1 to 6, or -1 for Native USB." - #endif - #if HAS_DGUS_LCD - #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite() - #endif -#endif - -/** - * TODO: review this to return 1 for pins that are not analog input - */ -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) (p) -#endif - -// -// Interrupts -// -#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() -#define cli() __disable_irq() -#define sei() __enable_irq() - -// ------------------------ -// Types -// ------------------------ - -typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs. - -#ifdef STM32G0B1xx - typedef int32_t pin_t; -#else - typedef int16_t pin_t; -#endif - -class libServo; -typedef libServo hal_servo_t; -#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos() -#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos() - -// ------------------------ -// ADC -// ------------------------ - -#ifdef ADC_RESOLUTION - #define HAL_ADC_RESOLUTION ADC_RESOLUTION -#else - #define HAL_ADC_RESOLUTION 12 -#endif - -#define HAL_ADC_VREF 3.3 - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -#ifdef STM32F1xx - #define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE) - #define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE) - #define JTAGSWD_RESET() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET); // Reset: FULL SWD+JTAG -#endif - -#define PLATFORM_M997_SUPPORT -void flashFirmware(const int16_t); - -// Maple Compatibility -typedef void (*systickCallback_t)(void); -void systick_attach_callback(systickCallback_t cb); -void HAL_SYSTICK_Callback(); - -extern volatile uint32_t systick_uptime_millis; - -#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment - -// ------------------------ -// Class Utilities -// ------------------------ - -// Memory related -#define __bss_end __bss_end__ - -extern "C" char* _sbrk(int incr); - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -static inline int freeMemory() { - volatile char top; - return &top - reinterpret_cast(_sbrk(0)); -} - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init(); // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_PRIMASK(); } - static void isr_on() { sei(); } - static void isr_off() { cli(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask(); - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source(); - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint16_t adc_result; - - // Called by Temperature::init once at startup - static void adc_init() { - analogReadResolution(HAL_ADC_RESOLUTION); - } - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t pin) { pinMode(pin, INPUT); } - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin) { adc_result = analogRead(pin); } - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return adc_result; } - - /** - * Set the PWM duty cycle for the pin to the given value. - * Optionally invert the duty cycle [default = false] - * Optionally change the maximum size of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); - - /** - * Set the frequency of the timer for the given pin. - * All Timer PWM pins run at the same frequency. - */ - static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); - -}; diff --git a/src/HAL/STM32/HAL_SPI.cpp b/src/HAL/STM32/HAL_SPI.cpp deleted file mode 100644 index 40d320d..0000000 --- a/src/HAL/STM32/HAL_SPI.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#include - -// ------------------------ -// Public Variables -// ------------------------ - -static SPISettings spiConfig; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(SOFTWARE_SPI) - - // ------------------------ - // Software SPI - // ------------------------ - - #include "../shared/Delay.h" - - void spiBegin(void) { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - OUT_WRITE(SD_SCK_PIN, HIGH); - SET_INPUT(SD_MISO_PIN); - OUT_WRITE(SD_MOSI_PIN, HIGH); - } - - // Use function with compile-time value so we can actually reach the desired frequency - // Need to adjust this a little bit: on a 72MHz clock, we have 14ns/clock - // and we'll use ~3 cycles to jump to the method and going back, so it'll take ~40ns from the given clock here - #define CALLING_COST_NS (3U * 1000000000U) / (F_CPU) - void (*delaySPIFunc)(); - void delaySPI_125() { DELAY_NS(125 - CALLING_COST_NS); } - void delaySPI_250() { DELAY_NS(250 - CALLING_COST_NS); } - void delaySPI_500() { DELAY_NS(500 - CALLING_COST_NS); } - void delaySPI_1000() { DELAY_NS(1000 - CALLING_COST_NS); } - void delaySPI_2000() { DELAY_NS(2000 - CALLING_COST_NS); } - void delaySPI_4000() { DELAY_NS(4000 - CALLING_COST_NS); } - - void spiInit(uint8_t spiRate) { - // Use datarates Marlin uses - switch (spiRate) { - case SPI_FULL_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 8,000,000 actual: ~1.1M - case SPI_HALF_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 4,000,000 actual: ~1.1M - case SPI_QUARTER_SPEED:delaySPIFunc = &delaySPI_250; break; // desired: 2,000,000 actual: ~890K - case SPI_EIGHTH_SPEED: delaySPIFunc = &delaySPI_500; break; // desired: 1,000,000 actual: ~590K - case SPI_SPEED_5: delaySPIFunc = &delaySPI_1000; break; // desired: 500,000 actual: ~360K - case SPI_SPEED_6: delaySPIFunc = &delaySPI_2000; break; // desired: 250,000 actual: ~210K - default: delaySPIFunc = &delaySPI_4000; break; // desired: 125,000 actual: ~123K - } - SPI.begin(); - } - - // Begin SPI transaction, set clock, bit order, data mode - void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { /* do nothing */ } - - uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3 - for (uint8_t bits = 8; bits--;) { - WRITE(SD_SCK_PIN, LOW); - WRITE(SD_MOSI_PIN, b & 0x80); - - delaySPIFunc(); - WRITE(SD_SCK_PIN, HIGH); - delaySPIFunc(); - - b <<= 1; // little setup time - b |= (READ(SD_MISO_PIN) != 0); - } - DELAY_NS(125); - return b; - } - - // Soft SPI receive byte - uint8_t spiRec() { - hal.isr_off(); // No interrupts during byte receive - const uint8_t data = HAL_SPI_STM32_SpiTransfer_Mode_3(0xFF); - hal.isr_on(); // Enable interrupts - return data; - } - - // Soft SPI read data - void spiRead(uint8_t *buf, uint16_t nbyte) { - for (uint16_t i = 0; i < nbyte; i++) - buf[i] = spiRec(); - } - - // Soft SPI send byte - void spiSend(uint8_t data) { - hal.isr_off(); // No interrupts during byte send - HAL_SPI_STM32_SpiTransfer_Mode_3(data); // Don't care what is received - hal.isr_on(); // Enable interrupts - } - - // 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]); - } - -#else - - // ------------------------ - // Hardware SPI - // ------------------------ - - /** - * VGPV SPI speed start and PCLK2/2, by default 108/2 = 54Mhz - */ - - /** - * @brief Begin SPI port setup - * - * @return Nothing - * - * @details Only configures SS pin since stm32duino creates and initialize the SPI object - */ - void spiBegin() { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - } - - // Configure SPI for specified SPI speed - void spiInit(uint8_t spiRate) { - // Use datarates Marlin uses - uint32_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = 20000000; break; // 13.9mhz=20000000 6.75mhz=10000000 3.38mhz=5000000 .833mhz=1000000 - case SPI_HALF_SPEED: clock = 5000000; break; - case SPI_QUARTER_SPEED: clock = 2500000; break; - case SPI_EIGHTH_SPEED: clock = 1250000; break; - case SPI_SPEED_5: clock = 625000; break; - case SPI_SPEED_6: clock = 300000; break; - default: - clock = 4000000; // Default from the SPI library - } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - - SPI.setMISO(SD_MISO_PIN); - SPI.setMOSI(SD_MOSI_PIN); - SPI.setSCLK(SD_SCK_PIN); - - SPI.begin(); - } - - /** - * @brief Receives a single byte from the SPI port. - * - * @return Byte received - * - * @details - */ - uint8_t spiRec() { - uint8_t returnByte = SPI.transfer(0xFF); - return returnByte; - } - - /** - * @brief Receive a number of bytes from the SPI port to a buffer - * - * @param buf Pointer to starting address of buffer to write to. - * @param nbyte Number of bytes to receive. - * @return Nothing - * - * @details Uses DMA - */ - void spiRead(uint8_t *buf, uint16_t nbyte) { - if (nbyte == 0) return; - memset(buf, 0xFF, nbyte); - SPI.transfer(buf, nbyte); - } - - /** - * @brief Send a single byte on SPI port - * - * @param b Byte to send - * - * @details - */ - void spiSend(uint8_t b) { - SPI.transfer(b); - } - - /** - * @brief Write token and then write from 512 byte buffer to SPI (for SD card) - * - * @param buf Pointer with buffer start address - * @return Nothing - * - * @details Use DMA - */ - void spiSendBlock(uint8_t token, const uint8_t *buf) { - uint8_t rxBuf[512]; - SPI.transfer(token); - SPI.transfer((uint8_t*)buf, &rxBuf, 512); - } - -#endif // SOFTWARE_SPI - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/MarlinSPI.cpp b/src/HAL/STM32/MarlinSPI.cpp deleted file mode 100644 index f7c603d..0000000 --- a/src/HAL/STM32/MarlinSPI.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#if defined(HAL_STM32) && !defined(STM32H7xx) - -#include "MarlinSPI.h" - -static void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb, uint32_t dataSize) { - spi_init(obj, speed, mode, msb); - // spi_init set 8bit always - // TODO: copy the code from spi_init and handle data size, to avoid double init always!! - if (dataSize != SPI_DATASIZE_8BIT) { - obj->handle.Init.DataSize = dataSize; - HAL_SPI_Init(&obj->handle); - __HAL_SPI_ENABLE(&obj->handle); - } -} - -void MarlinSPI::setClockDivider(uint8_t _div) { - _speed = spi_getClkFreq(&_spi);// / _div; - _clockDivider = _div; -} - -void MarlinSPI::begin(void) { - //TODO: only call spi_init if any parameter changed!! - spi_init(&_spi, _speed, _dataMode, _bitOrder, _dataSize); -} - -void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc) { - _dmaHandle.Init.Direction = direction; - _dmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; - _dmaHandle.Init.Mode = DMA_NORMAL; - _dmaHandle.Init.Priority = DMA_PRIORITY_LOW; - _dmaHandle.Init.MemInc = minc ? DMA_MINC_ENABLE : DMA_MINC_DISABLE; - - if (_dataSize == DATA_SIZE_8BIT) { - _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - } - else { - _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; - _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - } - #ifdef STM32F4xx - _dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - #endif - - // start DMA hardware - // TODO: check if hardware is already enabled - #ifdef SPI1_BASE - if (_spiHandle.Instance == SPI1) { - #ifdef STM32F1xx - __HAL_RCC_DMA1_CLK_ENABLE(); - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2; - #elif defined(STM32F4xx) - __HAL_RCC_DMA2_CLK_ENABLE(); - _dmaHandle.Init.Channel = DMA_CHANNEL_3; - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0; - #endif - } - #endif - #ifdef SPI2_BASE - if (_spiHandle.Instance == SPI2) { - #ifdef STM32F1xx - __HAL_RCC_DMA1_CLK_ENABLE(); - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4; - #elif defined(STM32F4xx) - __HAL_RCC_DMA1_CLK_ENABLE(); - _dmaHandle.Init.Channel = DMA_CHANNEL_0; - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3; - #endif - } - #endif - #ifdef SPI3_BASE - if (_spiHandle.Instance == SPI3) { - #ifdef STM32F1xx - __HAL_RCC_DMA2_CLK_ENABLE(); - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1; - #elif defined(STM32F4xx) - __HAL_RCC_DMA1_CLK_ENABLE(); - _dmaHandle.Init.Channel = DMA_CHANNEL_0; - _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2; - #endif - } - #endif - - HAL_DMA_Init(&_dmaHandle); -} - -byte MarlinSPI::transfer(uint8_t _data) { - uint8_t rxData = 0xFF; - HAL_SPI_TransmitReceive(&_spi.handle, &_data, &rxData, 1, HAL_MAX_DELAY); - return rxData; -} - -__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN); } -__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN); } - -uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) { - const uint8_t ff = 0xFF; - - //if (!LL_SPI_IsEnabled(_spi.handle)) // only enable if disabled - __HAL_SPI_ENABLE(&_spi.handle); - - if (receiveBuf) { - setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true); - HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length); - LL_SPI_EnableDMAReq_RX(_spi.handle.Instance); // Enable Rx DMA Request - } - - // check for 2 lines transfer - bool mincTransmit = true; - if (transmitBuf == nullptr && _spi.handle.Init.Direction == SPI_DIRECTION_2LINES && _spi.handle.Init.Mode == SPI_MODE_MASTER) { - transmitBuf = &ff; - mincTransmit = false; - } - - if (transmitBuf) { - setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit); - HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length); - LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request - } - - if (transmitBuf) { - HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); - HAL_DMA_Abort(&_dmaTx); - HAL_DMA_DeInit(&_dmaTx); - } - - // while ((_spi.handle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {} - - if (receiveBuf) { - HAL_DMA_PollForTransfer(&_dmaRx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); - HAL_DMA_Abort(&_dmaRx); - HAL_DMA_DeInit(&_dmaRx); - } - - return 1; -} - -uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc) { - setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc); - HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length); - __HAL_SPI_ENABLE(&_spi.handle); - LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request - HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); - HAL_DMA_Abort(&_dmaTx); - // DeInit objects - HAL_DMA_DeInit(&_dmaTx); - return 1; -} - -#endif // HAL_STM32 && !STM32H7xx diff --git a/src/HAL/STM32/MarlinSPI.h b/src/HAL/STM32/MarlinSPI.h deleted file mode 100644 index fbd3585..0000000 --- a/src/HAL/STM32/MarlinSPI.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "HAL.h" -#include - -extern "C" { - #include -} - -/** - * Marlin currently requires 3 SPI classes: - * - * SPIClass: - * This class is normally provided by frameworks and has a semi-default interface. - * This is needed because some libraries reference it globally. - * - * SPISettings: - * Container for SPI configs for SPIClass. As above, libraries may reference it globally. - * - * These two classes are often provided by frameworks so we cannot extend them to add - * useful methods for Marlin. - * - * MarlinSPI: - * Provides the default SPIClass interface plus some Marlin goodies such as a simplified - * interface for SPI DMA transfer. - * - */ - -#define DATA_SIZE_8BIT SPI_DATASIZE_8BIT -#define DATA_SIZE_16BIT SPI_DATASIZE_16BIT - -class MarlinSPI { -public: - MarlinSPI() : MarlinSPI(NC, NC, NC, NC) {} - - MarlinSPI(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)NC) : _mosiPin(mosi), _misoPin(miso), _sckPin(sclk), _ssPin(ssel) { - _spi.pin_miso = digitalPinToPinName(_misoPin); - _spi.pin_mosi = digitalPinToPinName(_mosiPin); - _spi.pin_sclk = digitalPinToPinName(_sckPin); - _spi.pin_ssel = digitalPinToPinName(_ssPin); - _dataSize = DATA_SIZE_8BIT; - _bitOrder = MSBFIRST; - _dataMode = SPI_MODE_0; - _spi.handle.State = HAL_SPI_STATE_RESET; - setClockDivider(SPI_SPEED_CLOCK_DIV2_MHZ); - } - - void begin(void); - void end(void) {} - - byte transfer(uint8_t _data); - uint8_t dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length); - uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = true); - - /* These methods are deprecated and kept for compatibility. - * Use SPISettings with SPI.beginTransaction() to configure SPI parameters. - */ - void setBitOrder(BitOrder _order) { _bitOrder = _order; } - - void setDataMode(uint8_t _mode) { - switch (_mode) { - case SPI_MODE0: _dataMode = SPI_MODE_0; break; - case SPI_MODE1: _dataMode = SPI_MODE_1; break; - case SPI_MODE2: _dataMode = SPI_MODE_2; break; - case SPI_MODE3: _dataMode = SPI_MODE_3; break; - } - } - - void setClockDivider(uint8_t _div); - -private: - void setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc = false); - - spi_t _spi; - DMA_HandleTypeDef _dmaTx; - DMA_HandleTypeDef _dmaRx; - BitOrder _bitOrder; - spi_mode_e _dataMode; - uint8_t _clockDivider; - uint32_t _speed; - uint32_t _dataSize; - pin_t _mosiPin; - pin_t _misoPin; - pin_t _sckPin; - pin_t _ssPin; -}; diff --git a/src/HAL/STM32/MarlinSerial.cpp b/src/HAL/STM32/MarlinSerial.cpp deleted file mode 100644 index 37a8f40..0000000 --- a/src/HAL/STM32/MarlinSerial.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" -#include "MarlinSerial.h" - -#if ENABLED(EMERGENCY_PARSER) - #include "../../feature/e_parser.h" -#endif - -#ifndef USART4 - #define USART4 UART4 -#endif -#ifndef USART5 - #define USART5 UART5 -#endif - -#define DECLARE_SERIAL_PORT(ser_num) \ - void _rx_complete_irq_ ## ser_num (serial_t * obj); \ - MSerialT MSerial ## ser_num (true, USART ## ser_num, &_rx_complete_irq_ ## ser_num); \ - void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); } - -#if USING_HW_SERIAL1 - DECLARE_SERIAL_PORT(1) -#endif -#if USING_HW_SERIAL2 - DECLARE_SERIAL_PORT(2) -#endif -#if USING_HW_SERIAL3 - DECLARE_SERIAL_PORT(3) -#endif -#if USING_HW_SERIAL4 - DECLARE_SERIAL_PORT(4) -#endif -#if USING_HW_SERIAL5 - DECLARE_SERIAL_PORT(5) -#endif -#if USING_HW_SERIAL6 - DECLARE_SERIAL_PORT(6) -#endif -#if USING_HW_SERIAL7 - DECLARE_SERIAL_PORT(7) -#endif -#if USING_HW_SERIAL8 - DECLARE_SERIAL_PORT(8) -#endif -#if USING_HW_SERIAL9 - DECLARE_SERIAL_PORT(9) -#endif -#if USING_HW_SERIAL10 - DECLARE_SERIAL_PORT(10) -#endif -#if USING_HW_SERIALLP1 - DECLARE_SERIAL_PORT(LP1) -#endif - -void MarlinSerial::begin(unsigned long baud, uint8_t config) { - HardwareSerial::begin(baud, config); - // Replace the IRQ callback with the one we have defined - TERN_(EMERGENCY_PARSER, _serial.rx_callback = _rx_callback); -} - -// This function is Copyright (c) 2006 Nicholas Zambetti. -void MarlinSerial::_rx_complete_irq(serial_t *obj) { - // No Parity error, read byte and store it in the buffer if there is room - unsigned char c; - - if (uart_getc(obj, &c) == 0) { - - rx_buffer_index_t i = (unsigned int)(obj->rx_head + 1) % SERIAL_RX_BUFFER_SIZE; - - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - if (i != obj->rx_tail) { - obj->rx_buff[obj->rx_head] = c; - obj->rx_head = i; - } - - #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(static_cast(this)->emergency_state, c); - #endif - } -} - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/MarlinSerial.h b/src/HAL/STM32/MarlinSerial.h deleted file mode 100644 index bf861fb..0000000 --- a/src/HAL/STM32/MarlinSerial.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - #include "../../feature/e_parser.h" -#endif - -#include "../../core/serial_hook.h" - -typedef void (*usart_rx_callback_t)(serial_t * obj); - -struct MarlinSerial : public HardwareSerial { - MarlinSerial(void *peripheral, usart_rx_callback_t rx_callback) : - HardwareSerial(peripheral), _rx_callback(rx_callback) - { } - - void begin(unsigned long baud, uint8_t config); - inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } - - void _rx_complete_irq(serial_t *obj); - -protected: - usart_rx_callback_t _rx_callback; -}; - -typedef Serial1Class MSerialT; -extern MSerialT MSerial1; -extern MSerialT MSerial2; -extern MSerialT MSerial3; -extern MSerialT MSerial4; -extern MSerialT MSerial5; -extern MSerialT MSerial6; -extern MSerialT MSerial7; -extern MSerialT MSerial8; -extern MSerialT MSerial9; -extern MSerialT MSerial10; -extern MSerialT MSerialLP1; diff --git a/src/HAL/STM32/MinSerial.cpp b/src/HAL/STM32/MinSerial.cpp deleted file mode 100644 index b0fcff2..0000000 --- a/src/HAL/STM32/MinSerial.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - -#include "../shared/MinSerial.h" - -/* Instruction Synchronization Barrier */ -#define isb() __asm__ __volatile__ ("isb" : : : "memory") - -/* Data Synchronization Barrier */ -#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") - -// Dumb mapping over the registers of a USART device on STM32 -struct USARTMin { - volatile uint32_t SR; - volatile uint32_t DR; - volatile uint32_t BRR; - volatile uint32_t CR1; - volatile uint32_t CR2; -}; - -#if WITHIN(SERIAL_PORT, 1, 6) - // Depending on the CPU, the serial port is different for USART1 - static const uintptr_t regsAddr[] = { - TERN(STM32F1xx, 0x40013800, 0x40011000), // USART1 - 0x40004400, // USART2 - 0x40004800, // USART3 - 0x40004C00, // UART4_BASE - 0x40005000, // UART5_BASE - 0x40011400 // USART6 - }; - static USARTMin * regs = (USARTMin*)regsAddr[SERIAL_PORT - 1]; -#endif - -static void TXBegin() { - #if !WITHIN(SERIAL_PORT, 1, 6) - #warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error." - #warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port." - #else - // This is common between STM32F1/STM32F2 and STM32F4 - const int nvicUART[] = { /* NVIC_USART1 */ 37, /* NVIC_USART2 */ 38, /* NVIC_USART3 */ 39, /* NVIC_UART4 */ 52, /* NVIC_UART5 */ 53, /* NVIC_USART6 */ 71 }; - int nvicIndex = nvicUART[SERIAL_PORT - 1]; - - struct NVICMin { - volatile uint32_t ISER[32]; - volatile uint32_t ICER[32]; - }; - - NVICMin *nvicBase = (NVICMin*)0xE000E100; - SBI32(nvicBase->ICER[nvicIndex >> 5], nvicIndex & 0x1F); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - dsb(); - isb(); - - // Example for USART1 disable: (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN)) - // Too difficult to reimplement here, let's query the STM32duino macro here - #if SERIAL_PORT == 1 - __HAL_RCC_USART1_CLK_DISABLE(); - __HAL_RCC_USART1_CLK_ENABLE(); - #elif SERIAL_PORT == 2 - __HAL_RCC_USART2_CLK_DISABLE(); - __HAL_RCC_USART2_CLK_ENABLE(); - #elif SERIAL_PORT == 3 - __HAL_RCC_USART3_CLK_DISABLE(); - __HAL_RCC_USART3_CLK_ENABLE(); - #elif SERIAL_PORT == 4 - __HAL_RCC_UART4_CLK_DISABLE(); // BEWARE: UART4 and not USART4 here - __HAL_RCC_UART4_CLK_ENABLE(); - #elif SERIAL_PORT == 5 - __HAL_RCC_UART5_CLK_DISABLE(); // BEWARE: UART5 and not USART5 here - __HAL_RCC_UART5_CLK_ENABLE(); - #elif SERIAL_PORT == 6 - __HAL_RCC_USART6_CLK_DISABLE(); - __HAL_RCC_USART6_CLK_ENABLE(); - #endif - - uint32_t brr = regs->BRR; - regs->CR1 = 0; // Reset the USART - regs->CR2 = 0; // 1 stop bit - - // If we don't touch the BRR (baudrate register), we don't need to recompute. - regs->BRR = brr; - - regs->CR1 = _BV(3) | _BV(13); // 8 bits, no parity, 1 stop bit (TE | UE) - #endif -} - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() __asm__ volatile("": : :"memory"); -static void TX(char c) { - #if WITHIN(SERIAL_PORT, 1, 6) - constexpr uint32_t usart_sr_txe = _BV(7); - while (!(regs->SR & usart_sr_txe)) { - hal.watchdog_refresh(); - sw_barrier(); - } - regs->DR = c; - #else - // Let's hope a mystical guru will fix this, one day by writing interrupt-free USB CDC ACM code (or, at least, by polling the registers since interrupt will be queued but will never trigger) - // For now, it's completely lost to oblivion. - #endif -} - -void install_min_serial() { - HAL_min_serial_init = &TXBegin; - HAL_min_serial_out = &TX; -} - -#if NONE(DYNAMIC_VECTORTABLE, STM32F0xx, STM32G0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp -extern "C" { - __attribute__((naked)) void JumpHandler_ASM() { - __asm__ __volatile__ ( - "b CommonHandler_ASM\n" - ); - } - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) HardFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) BusFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) UsageFault_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) MemManage_Handler(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) NMI_Handler(); -} -#endif - -#endif // POSTMORTEM_DEBUGGING -#endif // HAL_STM32 diff --git a/src/HAL/STM32/README.md b/src/HAL/STM32/README.md deleted file mode 100644 index 0eb026f..0000000 --- a/src/HAL/STM32/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Generic STM32 HAL based on the stm32duino core - -This HAL is intended to act as the generic STM32 HAL for all STM32 chips (The whole F, H and L family). - -Currently it supports: - * STM32F0xx - * STM32F1xx - * STM32F4xx - * STM32F7xx - -Targeting the official [Arduino STM32 Core](https://github.com/stm32duino/Arduino_Core_STM32). diff --git a/src/HAL/STM32/Servo.cpp b/src/HAL/STM32/Servo.cpp deleted file mode 100644 index a00186e..0000000 --- a/src/HAL/STM32/Servo.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "Servo.h" - -static uint_fast8_t servoCount = 0; -static libServo *servos[NUM_SERVOS] = {0}; -constexpr millis_t servoDelay[] = SERVO_DELAY; -static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - -// Initialize to the default timer priority. This will be overridden by a call from timers.cpp. -// This allows all timer interrupt priorities to be managed from a single location in the HAL. -static uint32_t servo_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO); - -// This must be called after the STM32 Servo class has initialized the timer. -// It may only be needed after the first call to attach(), but it is possible -// that is is necessary after every detach() call. To be safe this is currently -// called after every call to attach(). -static void fixServoTimerInterruptPriority() { - NVIC_SetPriority(getTimerUpIrq(TIMER_SERVO), servo_interrupt_priority); -} - -libServo::libServo() -: delay(servoDelay[servoCount]), - was_attached_before_pause(false), - value_before_pause(0) -{ - servos[servoCount++] = this; -} - -int8_t libServo::attach(const int pin) { - if (servoCount >= MAX_SERVOS) return -1; - if (pin > 0) servo_pin = pin; - auto result = stm32_servo.attach(servo_pin); - fixServoTimerInterruptPriority(); - return result; -} - -int8_t libServo::attach(const int pin, const int min, const int max) { - if (servoCount >= MAX_SERVOS) return -1; - if (pin > 0) servo_pin = pin; - auto result = stm32_servo.attach(servo_pin, min, max); - fixServoTimerInterruptPriority(); - return result; -} - -void libServo::move(const int value) { - if (attach(0) >= 0) { - stm32_servo.write(value); - safe_delay(delay); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -void libServo::pause() { - was_attached_before_pause = stm32_servo.attached(); - if (was_attached_before_pause) { - value_before_pause = stm32_servo.read(); - stm32_servo.detach(); - } -} - -void libServo::resume() { - if (was_attached_before_pause) { - attach(); - move(value_before_pause); - } -} - -void libServo::pause_all_servos() { - for (auto& servo : servos) - if (servo) servo->pause(); -} - -void libServo::resume_all_servos() { - for (auto& servo : servos) - if (servo) servo->resume(); -} - -void libServo::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) { - servo_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority); -} - -#endif // HAS_SERVOS -#endif // HAL_STM32 diff --git a/src/HAL/STM32/Servo.h b/src/HAL/STM32/Servo.h deleted file mode 100644 index 1527e75..0000000 --- a/src/HAL/STM32/Servo.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -#include "../../core/millis_t.h" - -// Inherit and expand on the official library -class libServo { - public: - libServo(); - int8_t attach(const int pin = 0); // pin == 0 uses value from previous call - int8_t attach(const int pin, const int min, const int max); - void detach() { stm32_servo.detach(); } - int read() { return stm32_servo.read(); } - void move(const int value); - - void pause(); - void resume(); - - static void pause_all_servos(); - static void resume_all_servos(); - static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority); - - private: - Servo stm32_servo; - - int servo_pin = 0; - millis_t delay = 0; - - bool was_attached_before_pause; - int value_before_pause; -}; diff --git a/src/HAL/STM32/eeprom_bl24cxx.cpp b/src/HAL/STM32/eeprom_bl24cxx.cpp deleted file mode 100644 index f30b3de..0000000 --- a/src/HAL/STM32/eeprom_bl24cxx.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -/** - * PersistentStore for Arduino-style EEPROM interface - * with simple implementations supplied by Marlin. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(IIC_BL24CXX_EEPROM) - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -// -// PersistentStore -// - -#ifndef MARLIN_EEPROM_SIZE - #error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM." -#endif - -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t v = *value; - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t * const p = (uint8_t * const)pos; - uint8_t c = eeprom_read_byte(p); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // IIC_BL24CXX_EEPROM -#endif // HAL_STM32 diff --git a/src/HAL/STM32/eeprom_flash.cpp b/src/HAL/STM32/eeprom_flash.cpp deleted file mode 100644 index 7c8cc8d..0000000 --- a/src/HAL/STM32/eeprom_flash.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(FLASH_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" - -// Better: "utility/stm32_eeprom.h", but only after updating stm32duino to 2.0.0 -// Use EEPROM.h for compatibility, for now. -#include - -/** - * The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that - * even have multiple "banks" of flash. - * - * This code is a bit of a mashup of - * framework-arduinoststm32/cores/arduino/stm32/stm32_eeprom.c - * hal/hal_lpc1768/persistent_store_flash.cpp - * - * This has only be written against those that use a single "sector" design. - * - * Those that deal with "pages" could be made to work. Looking at the STM32F07 for example, there are - * 128 "pages", each 2kB in size. If we continued with our EEPROM being 4Kb, we'd always need to operate - * on 2 of these pages. Each write, we'd use 2 different pages from a pool of pages until we are done. - */ - -#if ENABLED(FLASH_EEPROM_LEVELING) - - #include "stm32_def.h" - - #define DEBUG_OUT ENABLED(EEPROM_CHITCHAT) - #include "../../core/debug_out.h" - - #ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB - #endif - - #ifndef FLASH_SECTOR - #define FLASH_SECTOR (FLASH_SECTOR_TOTAL - 1) - #endif - #ifndef FLASH_UNIT_SIZE - #define FLASH_UNIT_SIZE 0x20000 // 128kB - #endif - - #ifndef FLASH_ADDRESS_START - #define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1) - #endif - #define FLASH_ADDRESS_END (FLASH_ADDRESS_START + FLASH_UNIT_SIZE - 1) - - #define EEPROM_SLOTS ((FLASH_UNIT_SIZE) / (MARLIN_EEPROM_SIZE)) - #define SLOT_ADDRESS(slot) (FLASH_ADDRESS_START + (slot * (MARLIN_EEPROM_SIZE))) - - #define UNLOCK_FLASH() if (!flash_unlocked) { \ - HAL_FLASH_Unlock(); \ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \ - FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); \ - flash_unlocked = true; \ - } - #define LOCK_FLASH() if (flash_unlocked) { HAL_FLASH_Lock(); flash_unlocked = false; } - - #define EMPTY_UINT32 ((uint32_t)-1) - #define EMPTY_UINT8 ((uint8_t)-1) - - static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; - static int current_slot = -1; - - static_assert(0 == MARLIN_EEPROM_SIZE % 4, "MARLIN_EEPROM_SIZE must be a multiple of 4"); // Ensure copying as uint32_t is safe - static_assert(0 == FLASH_UNIT_SIZE % MARLIN_EEPROM_SIZE, "MARLIN_EEPROM_SIZE must divide evenly into your FLASH_UNIT_SIZE"); - static_assert(FLASH_UNIT_SIZE >= MARLIN_EEPROM_SIZE, "FLASH_UNIT_SIZE must be greater than or equal to your MARLIN_EEPROM_SIZE"); - static_assert(IS_FLASH_SECTOR(FLASH_SECTOR), "FLASH_SECTOR is invalid"); - static_assert(IS_POWER_OF_2(FLASH_UNIT_SIZE), "FLASH_UNIT_SIZE should be a power of 2, please check your chip's spec sheet"); - -#endif - -static bool eeprom_data_written = false; - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { - - EEPROM.begin(); // Avoid STM32 EEPROM.h warning (do nothing) - - #if ENABLED(FLASH_EEPROM_LEVELING) - - if (current_slot == -1 || eeprom_data_written) { - // This must be the first time since power on that we have accessed the storage, or someone - // loaded and called write_data and never called access_finish. - // Lets go looking for the slot that holds our configuration. - if (eeprom_data_written) DEBUG_ECHOLNPGM("Dangling EEPROM write_data"); - uint32_t address = FLASH_ADDRESS_START; - while (address <= FLASH_ADDRESS_END) { - uint32_t address_value = (*(__IO uint32_t*)address); - if (address_value != EMPTY_UINT32) { - current_slot = (address - (FLASH_ADDRESS_START)) / (MARLIN_EEPROM_SIZE); - break; - } - address += sizeof(uint32_t); - } - if (current_slot == -1) { - // We didn't find anything, so we'll just initialize to empty - for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EMPTY_UINT8; - current_slot = EEPROM_SLOTS; - } - else { - // load current settings - uint8_t *eeprom_data = (uint8_t *)SLOT_ADDRESS(current_slot); - for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i]; - DEBUG_ECHOLNPGM("EEPROM loaded from slot ", current_slot, "."); - } - eeprom_data_written = false; - } - - #else - eeprom_buffer_fill(); - #endif - - return true; -} - -bool PersistentStore::access_finish() { - - if (eeprom_data_written) { - #ifdef STM32F4xx - // MCU may come up with flash error bits which prevent some flash operations. - // Clear flags prior to flash operations to prevent errors. - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); - #endif - - #if ENABLED(FLASH_EEPROM_LEVELING) - - HAL_StatusTypeDef status = HAL_ERROR; - bool flash_unlocked = false; - - if (--current_slot < 0) { - // all slots have been used, erase everything and start again - - FLASH_EraseInitTypeDef EraseInitStruct; - uint32_t SectorError = 0; - - EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; - EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; - EraseInitStruct.Sector = FLASH_SECTOR; - EraseInitStruct.NbSectors = 1; - - current_slot = EEPROM_SLOTS - 1; - UNLOCK_FLASH(); - - TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT()); - hal.isr_off(); - status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError); - hal.isr_on(); - TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); - if (status != HAL_OK) { - DEBUG_ECHOLNPGM("HAL_FLASHEx_Erase=", status); - DEBUG_ECHOLNPGM("GetError=", HAL_FLASH_GetError()); - DEBUG_ECHOLNPGM("SectorError=", SectorError); - LOCK_FLASH(); - return false; - } - } - - UNLOCK_FLASH(); - - uint32_t offset = 0; - uint32_t address = SLOT_ADDRESS(current_slot); - uint32_t address_end = address + MARLIN_EEPROM_SIZE; - uint32_t data = 0; - - bool success = true; - - while (address < address_end) { - memcpy(&data, ram_eeprom + offset, sizeof(uint32_t)); - status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data); - if (status == HAL_OK) { - address += sizeof(uint32_t); - offset += sizeof(uint32_t); - } - else { - DEBUG_ECHOLNPGM("HAL_FLASH_Program=", status); - DEBUG_ECHOLNPGM("GetError=", HAL_FLASH_GetError()); - DEBUG_ECHOLNPGM("address=", address); - success = false; - break; - } - } - - LOCK_FLASH(); - - if (success) { - eeprom_data_written = false; - DEBUG_ECHOLNPGM("EEPROM saved to slot ", current_slot, "."); - } - - return success; - - #else - // The following was written for the STM32F4 but may work with other MCUs as well. - // Most STM32F4 flash does not allow reading from flash during erase operations. - // This takes about a second on a STM32F407 with a 128kB sector used as EEPROM. - // Interrupts during this time can have unpredictable results, such as killing Servo - // output. Servo output still glitches with interrupts disabled, but recovers after the - // erase. - TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT()); - hal.isr_off(); - eeprom_buffer_flush(); - hal.isr_on(); - TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); - - eeprom_data_written = false; - #endif - } - - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - while (size--) { - uint8_t v = *value; - #if ENABLED(FLASH_EEPROM_LEVELING) - if (v != ram_eeprom[pos]) { - ram_eeprom[pos] = v; - eeprom_data_written = true; - } - #else - if (v != eeprom_buffered_read_byte(pos)) { - eeprom_buffered_write_byte(pos, v); - eeprom_data_written = true; - } - #endif - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - const uint8_t c = TERN(FLASH_EEPROM_LEVELING, ram_eeprom[pos], eeprom_buffered_read_byte(pos)); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // FLASH_EEPROM_EMULATION -#endif // HAL_STM32 diff --git a/src/HAL/STM32/eeprom_if_iic.cpp b/src/HAL/STM32/eeprom_if_iic.cpp deleted file mode 100644 index ad8712c..0000000 --- a/src/HAL/STM32/eeprom_if_iic.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -/** - * Platform-independent Arduino functions for I2C EEPROM. - * Enable USE_SHARED_EEPROM if not supplied by the framework. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(IIC_BL24CXX_EEPROM) - -#include "../../libs/BL24CXX.h" -#include "../shared/eeprom_if.h" - -void eeprom_init() { BL24CXX::init(); } - -// ------------------------ -// Public functions -// ------------------------ - -void eeprom_write_byte(uint8_t *pos, uint8_t value) { - const unsigned eeprom_address = (unsigned)pos; - return BL24CXX::writeOneByte(eeprom_address, value); -} - -uint8_t eeprom_read_byte(uint8_t *pos) { - const unsigned eeprom_address = (unsigned)pos; - return BL24CXX::readOneByte(eeprom_address); -} - -#endif // IIC_BL24CXX_EEPROM -#endif // HAL_STM32 diff --git a/src/HAL/STM32/eeprom_sdcard.cpp b/src/HAL/STM32/eeprom_sdcard.cpp deleted file mode 100644 index 473b656..0000000 --- a/src/HAL/STM32/eeprom_sdcard.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -/** - * Implementation of EEPROM settings in SD Card - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SDCARD_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" -#include "../../sd/cardreader.h" - -#define EEPROM_FILENAME "eeprom.dat" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -#define _ALIGN(x) __attribute__ ((aligned(x))) -static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE]; - -bool PersistentStore::access_start() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) - return true; - - int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE); - if (bytes_read < 0) return false; - for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++) - HAL_eeprom_data[bytes_read] = 0xFF; - file.close(); - return true; -} - -bool PersistentStore::access_finish() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - int bytes_written = 0; - if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { - bytes_written = file.write(HAL_eeprom_data, MARLIN_EEPROM_SIZE); - file.close(); - } - return (bytes_written == MARLIN_EEPROM_SIZE); -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - for (size_t i = 0; i < size; i++) - HAL_eeprom_data[pos + i] = value[i]; - crc16(crc, value, size); - pos += size; - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) { - for (size_t i = 0; i < size; i++) { - uint8_t c = HAL_eeprom_data[pos + i]; - if (writing) value[i] = c; - crc16(crc, &c, 1); - } - pos += size; - return false; -} - -#endif // SDCARD_EEPROM_EMULATION -#endif // HAL_STM32 diff --git a/src/HAL/STM32/eeprom_sram.cpp b/src/HAL/STM32/eeprom_sram.cpp deleted file mode 100644 index 687e7f5..0000000 --- a/src/HAL/STM32/eeprom_sram.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SRAM_EEPROM_EMULATION) - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - while (size--) { - uint8_t v = *value; - - // Save to Backup SRAM - *(__IO uint8_t *)(BKPSRAM_BASE + (uint8_t * const)pos) = v; - - crc16(crc, &v, 1); - pos++; - value++; - }; - - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - // Read from either external EEPROM, program flash or Backup SRAM - const uint8_t c = ( *(__IO uint8_t *)(BKPSRAM_BASE + ((uint8_t*)pos)) ); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // SRAM_EEPROM_EMULATION -#endif // HAL_STM32 diff --git a/src/HAL/STM32/eeprom_wired.cpp b/src/HAL/STM32/eeprom_wired.cpp deleted file mode 100644 index cf04681..0000000 --- a/src/HAL/STM32/eeprom_wired.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -/** - * PersistentStore for Arduino-style EEPROM interface - * with simple implementations supplied by Marlin. - */ - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t v = *value; - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - // Read from either external EEPROM, program flash or Backup SRAM - const uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // HAL_STM32 diff --git a/src/HAL/STM32/endstop_interrupts.h b/src/HAL/STM32/endstop_interrupts.h deleted file mode 100644 index 9087088..0000000 --- a/src/HAL/STM32/endstop_interrupts.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/STM32/fast_pwm.cpp b/src/HAL/STM32/fast_pwm.cpp deleted file mode 100644 index a0d8ecc..0000000 --- a/src/HAL/STM32/fast_pwm.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -// Array to support sticky frequency sets per timer -static uint16_t timer_freq[TIMER_NUM]; - -void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { - const uint16_t duty = invert ? v_size - v : v; - if (PWM_PIN(pin)) { - const PinName pin_name = digitalPinToPinName(pin); - TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); - - const timer_index_t index = get_timer_index(Instance); - const bool needs_freq = (HardwareTimer_Handle[index] == nullptr); - if (needs_freq) // A new instance must be set to the default frequency of PWM_FREQUENCY - HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM)); - - HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this); - const uint32_t channel = STM_PIN_CHANNEL(pinmap_function(pin_name, PinMap_PWM)); - const TimerModes_t previousMode = HT->getMode(channel); - if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) - HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin); - - if (needs_freq && timer_freq[index] == 0) // If the timer is unconfigured and no freq is set then default PWM_FREQUENCY - set_pwm_frequency(pin_name, PWM_FREQUENCY); // Set the frequency and save the value to the assigned index no. - - // Note the resolution is sticky here, the input can be upto 16 bits and that would require RESOLUTION_16B_COMPARE_FORMAT (16) - // If such a need were to manifest then we would need to calc the resolution based on the v_size parameter and add code for it. - HT->setCaptureCompare(channel, duty, RESOLUTION_8B_COMPARE_FORMAT); // Set the duty, the calc is done in the library :) - pinmap_pinout(pin_name, PinMap_PWM); // Make sure the pin output state is set. - if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) HT->resume(); - } - else { - pinMode(pin, OUTPUT); - digitalWrite(pin, duty < v_size / 2 ? LOW : HIGH); - } -} - -void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { - if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer - const PinName pin_name = digitalPinToPinName(pin); - TIM_TypeDef * const Instance = (TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM); // Get HAL timer instance - const timer_index_t index = get_timer_index(Instance); - - // Protect used timers. - #ifdef STEP_TIMER - if (index == TIMER_INDEX(STEP_TIMER)) return; - #endif - #ifdef TEMP_TIMER - if (index == TIMER_INDEX(TEMP_TIMER)) return; - #endif - #if defined(PULSE_TIMER) && MF_TIMER_PULSE != MF_TIMER_STEP - if (index == TIMER_INDEX(PULSE_TIMER)) return; - #endif - - if (HardwareTimer_Handle[index] == nullptr) // If frequency is set before duty we need to create a handle here. - HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin_name, PinMap_PWM)); - HardwareTimer * const HT = (HardwareTimer *)(HardwareTimer_Handle[index]->__this); - HT->setOverflow(f_desired, HERTZ_FORMAT); - timer_freq[index] = f_desired; // Save the last frequency so duty will not set the default for this timer number. -} - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/fastio.cpp b/src/HAL/STM32/fastio.cpp deleted file mode 100644 index b34555b..0000000 --- a/src/HAL/STM32/fastio.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -GPIO_TypeDef* FastIOPortMap[LastPort + 1] = { 0 }; - -void FastIO_init() { - LOOP_L_N(i, NUM_DIGITAL_PINS) - FastIOPortMap[STM_PORT(digitalPin[i])] = get_GPIO_Port(STM_PORT(digitalPin[i])); -} - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/fastio.h b/src/HAL/STM32/fastio.h deleted file mode 100644 index 4a48954..0000000 --- a/src/HAL/STM32/fastio.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O interfaces for STM32 - * These use GPIO register access for fast port manipulation. - */ - -// ------------------------ -// Public Variables -// ------------------------ - -extern GPIO_TypeDef * FastIOPortMap[]; - -// ------------------------ -// Public functions -// ------------------------ - -void FastIO_init(); // Must be called before using fast io macros -#define FASTIO_INIT() FastIO_init() - -// ------------------------ -// Defines -// ------------------------ - -#define _BV32(b) (1UL << (b)) - -#ifndef PWM - #define PWM OUTPUT -#endif - -#if defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32L0xx) || defined(STM32L4xx) - #define _WRITE(IO, V) do { \ - if (V) FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \ - else FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BRR = _BV32(STM_PIN(digitalPinToPinName(IO))) ; \ - }while(0) -#else - #define _WRITE(IO, V) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->BSRR = _BV32(STM_PIN(digitalPinToPinName(IO)) + ((V) ? 0 : 16))) -#endif - -#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO))))) -#define _TOGGLE(IO) TBI32(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR, STM_PIN(digitalPinToPinName(IO))) - -#define _GET_MODE(IO) -#define _SET_MODE(IO,M) pinMode(IO, M) -#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) //!< Output Push Pull Mode & GPIO_NOPULL -#define _SET_OUTPUT_OD(IO) pinMode(IO, OUTPUT_OPEN_DRAIN) - -#define WRITE(IO,V) _WRITE(IO,V) -#define READ(IO) _READ(IO) -#define TOGGLE(IO) _TOGGLE(IO) - -#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) -#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0) - -#define SET_INPUT(IO) _SET_MODE(IO, INPUT) //!< Input Floating Mode -#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) //!< Input with Pull-up activation -#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) //!< Input with Pull-down activation -#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW) -#define SET_PWM(IO) _SET_MODE(IO, PWM) - -#define IS_INPUT(IO) -#define IS_OUTPUT(IO) - -#define PWM_PIN(P) digitalPinHasPWM(P) -#define NO_COMPILE_TIME_PWM - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/src/HAL/STM32/inc/Conditionals_LCD.h b/src/HAL/STM32/inc/Conditionals_LCD.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/STM32/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/STM32/inc/Conditionals_adv.h b/src/HAL/STM32/inc/Conditionals_adv.h deleted file mode 100644 index 451c94f..0000000 --- a/src/HAL/STM32/inc/Conditionals_adv.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if BOTH(SDSUPPORT, USBD_USE_CDC_MSC) && DISABLED(NO_SD_HOST_DRIVE) - #define HAS_SD_HOST_DRIVE 1 -#endif - -// Fix F_CPU not being a compile-time constant in STSTM32 framework -#ifdef BOARD_F_CPU - #undef F_CPU - #define F_CPU BOARD_F_CPU -#endif - -// The Sensitive Pins array is not optimizable -#define RUNTIME_ONLY_ANALOG_TO_DIGITAL diff --git a/src/HAL/STM32/inc/Conditionals_post.h b/src/HAL/STM32/inc/Conditionals_post.h deleted file mode 100644 index 18826e1..0000000 --- a/src/HAL/STM32/inc/Conditionals_post.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// If no real or emulated EEPROM selected, fall back to SD emulation -#if USE_FALLBACK_EEPROM - #define SDCARD_EEPROM_EMULATION -#elif EITHER(I2C_EEPROM, SPI_EEPROM) - #define USE_SHARED_EEPROM 1 -#endif diff --git a/src/HAL/STM32/inc/SanityCheck.h b/src/HAL/STM32/inc/SanityCheck.h deleted file mode 100644 index 0f1a2ac..0000000 --- a/src/HAL/STM32/inc/SanityCheck.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test STM32-specific configuration values for errors at compile-time. - */ -//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) -// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" -//#endif - - -#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT) - #undef SDCARD_EEPROM_EMULATION // Avoid additional error noise - #if USE_FALLBACK_EEPROM - #warning "EEPROM type not specified. Fallback is SDCARD_EEPROM_EMULATION." - #endif - #error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation." -#endif - -#if defined(STM32F4xx) && BOTH(PRINTCOUNTER, FLASH_EEPROM_EMULATION) - #warning "FLASH_EEPROM_EMULATION may cause long delays when writing and should not be used while printing." - #error "Disable PRINTCOUNTER or choose another EEPROM emulation." -#endif - -#if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING) - #error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware." -#endif - -#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on STM32." -#elif ENABLED(SERIAL_STATS_DROPPED_RX) - #error "SERIAL_STATS_DROPPED_RX is not supported on STM32." -#endif - -#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32H7xx, STM32F4xx, STM32F1xx) - #error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32H7, STM32F4 and STM32F1 hardware." -#endif diff --git a/src/HAL/STM32/msc_sd.cpp b/src/HAL/STM32/msc_sd.cpp deleted file mode 100644 index a40bec9..0000000 --- a/src/HAL/STM32/msc_sd.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_SD_HOST_DRIVE - -#include "../shared/Marduino.h" -#include "msc_sd.h" -#include "usbd_core.h" - -#include "../../sd/cardreader.h" - -#include -#include - -#define BLOCK_SIZE 512 -#define PRODUCT_ID 0x29 - -class Sd2CardUSBMscHandler : public USBMscHandler { -public: - DiskIODriver* diskIODriver() { - #if ENABLED(MULTI_VOLUME) - #if SHARED_VOLUME_IS(SD_ONBOARD) - return &card.media_driver_sdcard; - #elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) - return &card.media_driver_usbFlash; - #endif - #else - return card.diskIODriver(); - #endif - } - - bool GetCapacity(uint32_t *pBlockNum, uint16_t *pBlockSize) { - *pBlockNum = diskIODriver()->cardSize(); - *pBlockSize = BLOCK_SIZE; - return true; - } - - bool Write(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { - auto sd2card = diskIODriver(); - // single block - if (blkLen == 1) { - hal.watchdog_refresh(); - sd2card->writeBlock(blkAddr, pBuf); - return true; - } - - // multi block optimization - sd2card->writeStart(blkAddr, blkLen); - while (blkLen--) { - hal.watchdog_refresh(); - sd2card->writeData(pBuf); - pBuf += BLOCK_SIZE; - } - sd2card->writeStop(); - return true; - } - - bool Read(uint8_t *pBuf, uint32_t blkAddr, uint16_t blkLen) { - auto sd2card = diskIODriver(); - // single block - if (blkLen == 1) { - hal.watchdog_refresh(); - sd2card->readBlock(blkAddr, pBuf); - return true; - } - - // multi block optimization - sd2card->readStart(blkAddr); - while (blkLen--) { - hal.watchdog_refresh(); - sd2card->readData(pBuf); - pBuf += BLOCK_SIZE; - } - sd2card->readStop(); - return true; - } - - bool IsReady() { - return diskIODriver()->isReady(); - } -}; - -Sd2CardUSBMscHandler usbMscHandler; - -/* USB Mass storage Standard Inquiry Data */ -uint8_t Marlin_STORAGE_Inquirydata[] = { /* 36 */ - /* LUN 0 */ - 0x00, - 0x80, - 0x02, - 0x02, - (STANDARD_INQUIRY_DATA_LEN - 5), - 0x00, - 0x00, - 0x00, - 'M', 'A', 'R', 'L', 'I', 'N', ' ', ' ', /* Manufacturer : 8 bytes */ - 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '0', '.', '0', '1', /* Version : 4 Bytes */ -}; - -USBMscHandler *pSingleMscHandler = &usbMscHandler; - -void MSC_SD_init() { - USBDevice.end(); - delay(200); - USBDevice.registerMscHandlers(1, &pSingleMscHandler, Marlin_STORAGE_Inquirydata); - USBDevice.begin(); -} - -#endif // HAS_SD_HOST_DRIVE -#endif // HAL_STM32 diff --git a/src/HAL/STM32/msc_sd.h b/src/HAL/STM32/msc_sd.h deleted file mode 100644 index a8e5349..0000000 --- a/src/HAL/STM32/msc_sd.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void MSC_SD_init(); diff --git a/src/HAL/STM32/pinsDebug.h b/src/HAL/STM32/pinsDebug.h deleted file mode 100644 index 55c64c8..0000000 --- a/src/HAL/STM32/pinsDebug.h +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -#ifndef NUM_DIGITAL_PINS - // Only in ST's Arduino core (STM32duino, STM32Core) - #error "Expected NUM_DIGITAL_PINS not found" -#endif - -/** - * Life gets complicated if you want an easy to use 'M43 I' output (in port/pin order) - * because the variants in this platform do not always define all the I/O port/pins - * that a CPU has. - * - * VARIABLES: - * Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and - * digitalWrite commands and by M42. - * - does not contain port/pin info - * - is not in port/pin order - * - typically a variant will only assign Ard_num to port/pins that are actually used - * Index - M43 counter - only used to get Ard_num - * x - a parameter/argument used to search the pin_array to try to find a signal name - * associated with a Ard_num - * Port_pin - port number and pin number for use with CPU registers and printing reports - * - * Since M43 uses digitalRead and digitalWrite commands, only the Port_pins with an Ard_num - * are accessed and/or displayed. - * - * Three arrays are used. - * - * digitalPin[] is provided by the platform. It consists of the Port_pin numbers in - * Arduino pin number order. - * - * pin_array is a structure generated by the pins/pinsDebug.h header file. It is generated by - * the preprocessor. Only the signals associated with enabled options are in this table. - * It contains: - * - name of the signal - * - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines. - * EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the - * argument to digitalPinToPinName(IO) to get the Port_pin number - * - if it is a digital or analog signal. PWMs are considered digital here. - * - * pin_xref is a structure generated by this header file. It is generated by the - * preprocessor. It is in port/pin order. It contains just the port/pin numbers defined by the - * platform for this variant. - * - Ard_num - * - printable version of Port_pin - * - * Routines with an "x" as a parameter/argument are used to search the pin_array to try to - * find a signal name associated with a port/pin. - * - * NOTE - the Arduino pin number is what is used by the M42 command, NOT the port/pin for that - * signal. The Arduino pin number is listed by the M43 I command. - */ - -//////////////////////////////////////////////////////// -// -// make a list of the Arduino pin numbers in the Port/Pin order -// - -#define _PIN_ADD(NAME_ALPHA, ARDUINO_NUM) { NAME_ALPHA, ARDUINO_NUM }, -#define PIN_ADD(NAME) _PIN_ADD(#NAME, NAME) - -typedef struct { - char Port_pin_alpha[5]; - pin_t Ard_num; -} XrefInfo; - -const XrefInfo pin_xref[] PROGMEM = { - #include "pins_Xref.h" -}; - -//////////////////////////////////////////////////////////// - -#define MODE_PIN_INPUT 0 // Input mode (reset state) -#define MODE_PIN_OUTPUT 1 // General purpose output mode -#define MODE_PIN_ALT 2 // Alternate function mode -#define MODE_PIN_ANALOG 3 // Analog mode - -#define PIN_NUM(P) (P & 0x000F) -#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1') -#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 ) -#define PORT_NUM(P) ((P >> 4) & 0x0007) -#define PORT_ALPHA(P) ('A' + (P >> 4)) - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#if PA0 >= NUM_DIGITAL_PINS - #define HAS_HIGH_ANALOG_PINS 1 -#endif -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS) -#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL) -#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads -#define PRINT_PIN(Q) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PORT(ANUM) port_print(ANUM) -#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine - -// x is a variable used to search pin_array -#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) -#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].pin) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin - -// -// Pin Mapping for M43 -// -#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num - -#ifndef M43_NEVER_TOUCH - #define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP) - #ifdef KILL_PIN - #define M43_NEVER_TOUCH(Index) m43_never_touch(Index) - - bool m43_never_touch(const pin_t Index) { - static pin_t M43_kill_index = -1; - if (M43_kill_index < 0) - for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++) - if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break; - return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB - } - #else - #define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index) - #endif -#endif - -uint8_t get_pin_mode(const pin_t Ard_num) { - const PinName dp = digitalPinToPinName(Ard_num); - uint32_t ll_pin = STM_LL_GPIO_PIN(dp); - GPIO_TypeDef *port = get_GPIO_Port(STM_PORT(dp)); - uint32_t mode = LL_GPIO_GetPinMode(port, ll_pin); - switch (mode) { - case LL_GPIO_MODE_ANALOG: return MODE_PIN_ANALOG; - case LL_GPIO_MODE_INPUT: return MODE_PIN_INPUT; - case LL_GPIO_MODE_OUTPUT: return MODE_PIN_OUTPUT; - case LL_GPIO_MODE_ALTERNATE: return MODE_PIN_ALT; - TERN_(STM32F1xx, case LL_GPIO_MODE_FLOATING:) - default: return 0; - } -} - -bool GET_PINMODE(const pin_t Ard_num) { - const uint8_t pin_mode = get_pin_mode(Ard_num); - return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM -} - -int8_t digital_pin_to_analog_pin(const pin_t Ard_num) { - if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_FIRST + NUM_ANALOG_INPUTS - 1)) - return Ard_num - NUM_ANALOG_FIRST; - - const uint32_t ind = digitalPinToAnalogInput(Ard_num); - return (ind < NUM_ANALOG_INPUTS) ? ind : -1; -} - -bool IS_ANALOG(const pin_t Ard_num) { - return get_pin_mode(Ard_num) == MODE_PIN_ANALOG; -} - -bool is_digital(const pin_t Ard_num) { - const uint8_t pin_mode = get_pin_mode(pin_array[Ard_num].pin); - return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT; -} - -void port_print(const pin_t Ard_num) { - char buffer[16]; - pin_t Index; - for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++) - if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break; - - const char * ppa = pin_xref[Index].Port_pin_alpha; - sprintf_P(buffer, PSTR("%s"), ppa); - SERIAL_ECHO(buffer); - if (ppa[3] == '\0') SERIAL_CHAR(' '); - - // print analog pin number - const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num); - if (Port_pin >= 0) { - sprintf_P(buffer, PSTR(" (A%d) "), Port_pin); - SERIAL_ECHO(buffer); - if (Port_pin < 10) SERIAL_CHAR(' '); - } - else - SERIAL_ECHO_SP(7); - - // Print number to be used with M42 - int calc_p = Ard_num % (NUM_DIGITAL_PINS + 1); - if (Ard_num > NUM_DIGITAL_PINS && calc_p > 7) calc_p += 8; - SERIAL_ECHOPGM(" M42 P", calc_p); - SERIAL_CHAR(' '); - if (calc_p < 100) { - SERIAL_CHAR(' '); - if (calc_p < 10) - SERIAL_CHAR(' '); - } -} - -bool pwm_status(const pin_t Ard_num) { - return get_pin_mode(Ard_num) == MODE_PIN_ALT; -} - -void pwm_details(const pin_t Ard_num) { - #ifndef STM32F1xx - if (pwm_status(Ard_num)) { - uint32_t alt_all = 0; - const PinName dp = digitalPinToPinName(Ard_num); - pin_t pin_number = uint8_t(PIN_NUM(dp)); - const bool over_7 = pin_number >= 8; - const uint8_t ind = over_7 ? 1 : 0; - switch (PORT_ALPHA(dp)) { // get alt function - case 'A' : alt_all = GPIOA->AFR[ind]; break; - case 'B' : alt_all = GPIOB->AFR[ind]; break; - case 'C' : alt_all = GPIOC->AFR[ind]; break; - case 'D' : alt_all = GPIOD->AFR[ind]; break; - #ifdef PE_0 - case 'E' : alt_all = GPIOE->AFR[ind]; break; - #elif defined(PF_0) - case 'F' : alt_all = GPIOF->AFR[ind]; break; - #elif defined(PG_0) - case 'G' : alt_all = GPIOG->AFR[ind]; break; - #elif defined(PH_0) - case 'H' : alt_all = GPIOH->AFR[ind]; break; - #elif defined(PI_0) - case 'I' : alt_all = GPIOI->AFR[ind]; break; - #elif defined(PJ_0) - case 'J' : alt_all = GPIOJ->AFR[ind]; break; - #elif defined(PK_0) - case 'K' : alt_all = GPIOK->AFR[ind]; break; - #elif defined(PL_0) - case 'L' : alt_all = GPIOL->AFR[ind]; break; - #endif - } - if (over_7) pin_number -= 8; - - uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F; - SERIAL_ECHOPGM("Alt Function: ", alt_func); - if (alt_func < 10) SERIAL_CHAR(' '); - SERIAL_ECHOPGM(" - "); - switch (alt_func) { - case 0 : SERIAL_ECHOPGM("system (misc. I/O)"); break; - case 1 : SERIAL_ECHOPGM("TIM1/TIM2 (probably PWM)"); break; - case 2 : SERIAL_ECHOPGM("TIM3..5 (probably PWM)"); break; - case 3 : SERIAL_ECHOPGM("TIM8..11 (probably PWM)"); break; - case 4 : SERIAL_ECHOPGM("I2C1..3"); break; - case 5 : SERIAL_ECHOPGM("SPI1/SPI2"); break; - case 6 : SERIAL_ECHOPGM("SPI3"); break; - case 7 : SERIAL_ECHOPGM("USART1..3"); break; - case 8 : SERIAL_ECHOPGM("USART4..6"); break; - case 9 : SERIAL_ECHOPGM("CAN1/CAN2, TIM12..14 (probably PWM)"); break; - case 10 : SERIAL_ECHOPGM("OTG"); break; - case 11 : SERIAL_ECHOPGM("ETH"); break; - case 12 : SERIAL_ECHOPGM("FSMC, SDIO, OTG"); break; - case 13 : SERIAL_ECHOPGM("DCMI"); break; - case 14 : SERIAL_ECHOPGM("unused (shouldn't see this)"); break; - case 15 : SERIAL_ECHOPGM("EVENTOUT"); break; - } - } - #else - // TODO: F1 doesn't support changing pins function, so we need to check the function of the PIN and if it's enabled - #endif -} // pwm_details diff --git a/src/HAL/STM32/pins_Xref.h b/src/HAL/STM32/pins_Xref.h deleted file mode 100644 index 890e561..0000000 --- a/src/HAL/STM32/pins_Xref.h +++ /dev/null @@ -1,612 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// -// make a list of the Arduino pin numbers in the Port/Pin order -// -#ifdef PA0 - PIN_ADD(PA0) -#endif -#ifdef PA1 - PIN_ADD(PA1) -#endif -#ifdef PA2 - PIN_ADD(PA2) -#endif -#ifdef PA3 - PIN_ADD(PA3) -#endif -#ifdef PA4 - PIN_ADD(PA4) -#endif -#ifdef PA5 - PIN_ADD(PA5) -#endif -#ifdef PA6 - PIN_ADD(PA6) -#endif -#ifdef PA7 - PIN_ADD(PA7) -#endif -#ifdef PA8 - PIN_ADD(PA8) -#endif -#ifdef PA9 - PIN_ADD(PA9) -#endif -#ifdef PA10 - PIN_ADD(PA10) -#endif -#ifdef PA11 - PIN_ADD(PA11) -#endif -#ifdef PA12 - PIN_ADD(PA12) -#endif -#ifdef PA13 - PIN_ADD(PA13) -#endif -#ifdef PA14 - PIN_ADD(PA14) -#endif -#ifdef PA15 - PIN_ADD(PA15) -#endif - -#ifdef PB0 - PIN_ADD(PB0) -#endif -#ifdef PB1 - PIN_ADD(PB1) -#endif -#ifdef PB2 - PIN_ADD(PB2) -#endif -#ifdef PB3 - PIN_ADD(PB3) -#endif -#ifdef PB4 - PIN_ADD(PB4) -#endif -#ifdef PB5 - PIN_ADD(PB5) -#endif -#ifdef PB6 - PIN_ADD(PB6) -#endif -#ifdef PB7 - PIN_ADD(PB7) -#endif -#ifdef PB8 - PIN_ADD(PB8) -#endif -#ifdef PB9 - PIN_ADD(PB9) -#endif -#ifdef PB10 - PIN_ADD(PB10) -#endif -#ifdef PB11 - PIN_ADD(PB11) -#endif -#ifdef PB12 - PIN_ADD(PB12) -#endif -#ifdef PB13 - PIN_ADD(PB13) -#endif -#ifdef PB14 - PIN_ADD(PB14) -#endif -#ifdef PB15 - PIN_ADD(PB15) -#endif - -#ifdef PC0 - PIN_ADD(PC0) -#endif -#ifdef PC1 - PIN_ADD(PC1) -#endif -#ifdef PC2 - PIN_ADD(PC2) -#endif -#ifdef PC3 - PIN_ADD(PC3) -#endif -#ifdef PC4 - PIN_ADD(PC4) -#endif -#ifdef PC5 - PIN_ADD(PC5) -#endif -#ifdef PC6 - PIN_ADD(PC6) -#endif -#ifdef PC7 - PIN_ADD(PC7) -#endif -#ifdef PC8 - PIN_ADD(PC8) -#endif -#ifdef PC9 - PIN_ADD(PC9) -#endif -#ifdef PC10 - PIN_ADD(PC10) -#endif -#ifdef PC11 - PIN_ADD(PC11) -#endif -#ifdef PC12 - PIN_ADD(PC12) -#endif -#ifdef PC13 - PIN_ADD(PC13) -#endif -#ifdef PC14 - PIN_ADD(PC14) -#endif -#ifdef PC15 - PIN_ADD(PC15) -#endif - -#ifdef PD0 - PIN_ADD(PD0) -#endif -#ifdef PD1 - PIN_ADD(PD1) -#endif -#ifdef PD2 - PIN_ADD(PD2) -#endif -#ifdef PD3 - PIN_ADD(PD3) -#endif -#ifdef PD4 - PIN_ADD(PD4) -#endif -#ifdef PD5 - PIN_ADD(PD5) -#endif -#ifdef PD6 - PIN_ADD(PD6) -#endif -#ifdef PD7 - PIN_ADD(PD7) -#endif -#ifdef PD8 - PIN_ADD(PD8) -#endif -#ifdef PD9 - PIN_ADD(PD9) -#endif -#ifdef PD10 - PIN_ADD(PD10) -#endif -#ifdef PD11 - PIN_ADD(PD11) -#endif -#ifdef PD12 - PIN_ADD(PD12) -#endif -#ifdef PD13 - PIN_ADD(PD13) -#endif -#ifdef PD14 - PIN_ADD(PD14) -#endif -#ifdef PD15 - PIN_ADD(PD15) -#endif - -#ifdef PE0 - PIN_ADD(PE0) -#endif -#ifdef PE1 - PIN_ADD(PE1) -#endif -#ifdef PE2 - PIN_ADD(PE2) -#endif -#ifdef PE3 - PIN_ADD(PE3) -#endif -#ifdef PE4 - PIN_ADD(PE4) -#endif -#ifdef PE5 - PIN_ADD(PE5) -#endif -#ifdef PE6 - PIN_ADD(PE6) -#endif -#ifdef PE7 - PIN_ADD(PE7) -#endif -#ifdef PE8 - PIN_ADD(PE8) -#endif -#ifdef PE9 - PIN_ADD(PE9) -#endif -#ifdef PE10 - PIN_ADD(PE10) -#endif -#ifdef PE11 - PIN_ADD(PE11) -#endif -#ifdef PE12 - PIN_ADD(PE12) -#endif -#ifdef PE13 - PIN_ADD(PE13) -#endif -#ifdef PE14 - PIN_ADD(PE14) -#endif -#ifdef PE15 - PIN_ADD(PE15) -#endif - -#ifdef PF0 - PIN_ADD(PF0) -#endif -#ifdef PF1 - PIN_ADD(PF1) -#endif -#ifdef PF2 - PIN_ADD(PF2) -#endif -#ifdef PF3 - PIN_ADD(PF3) -#endif -#ifdef PF4 - PIN_ADD(PF4) -#endif -#ifdef PF5 - PIN_ADD(PF5) -#endif -#ifdef PF6 - PIN_ADD(PF6) -#endif -#ifdef PF7 - PIN_ADD(PF7) -#endif -#ifdef PF8 - PIN_ADD(PF8) -#endif -#ifdef PF9 - PIN_ADD(PF9) -#endif -#ifdef PF10 - PIN_ADD(PF10) -#endif -#ifdef PF11 - PIN_ADD(PF11) -#endif -#ifdef PF12 - PIN_ADD(PF12) -#endif -#ifdef PF13 - PIN_ADD(PF13) -#endif -#ifdef PF14 - PIN_ADD(PF14) -#endif -#ifdef PF15 - PIN_ADD(PF15) -#endif - -#ifdef PG0 - PIN_ADD(PG0) -#endif -#ifdef PG1 - PIN_ADD(PG1) -#endif -#ifdef PG2 - PIN_ADD(PG2) -#endif -#ifdef PG3 - PIN_ADD(PG3) -#endif -#ifdef PG4 - PIN_ADD(PG4) -#endif -#ifdef PG5 - PIN_ADD(PG5) -#endif -#ifdef PG6 - PIN_ADD(PG6) -#endif -#ifdef PG7 - PIN_ADD(PG7) -#endif -#ifdef PG8 - PIN_ADD(PG8) -#endif -#ifdef PG9 - PIN_ADD(PG9) -#endif -#ifdef PG10 - PIN_ADD(PG10) -#endif -#ifdef PG11 - PIN_ADD(PG11) -#endif -#ifdef PG12 - PIN_ADD(PG12) -#endif -#ifdef PG13 - PIN_ADD(PG13) -#endif -#ifdef PG14 - PIN_ADD(PG14) -#endif -#ifdef PG15 - PIN_ADD(PG15) -#endif - -#ifdef PH0 - PIN_ADD(PH0) -#endif -#ifdef PH1 - PIN_ADD(PH1) -#endif -#ifdef PH2 - PIN_ADD(PH2) -#endif -#ifdef PH3 - PIN_ADD(PH3) -#endif -#ifdef PH4 - PIN_ADD(PH4) -#endif -#ifdef PH5 - PIN_ADD(PH5) -#endif -#ifdef PH6 - PIN_ADD(PH6) -#endif -#ifdef PH7 - PIN_ADD(PH7) -#endif -#ifdef PH8 - PIN_ADD(PH8) -#endif -#ifdef PH9 - PIN_ADD(PH9) -#endif -#ifdef PH10 - PIN_ADD(PH10) -#endif -#ifdef PH11 - PIN_ADD(PH11) -#endif -#ifdef PH12 - PIN_ADD(PH12) -#endif -#ifdef PH13 - PIN_ADD(PH13) -#endif -#ifdef PH14 - PIN_ADD(PH14) -#endif -#ifdef PH15 - PIN_ADD(PH15) -#endif - -#ifdef PI0 - PIN_ADD(PI0) -#endif -#ifdef PI1 - PIN_ADD(PI1) -#endif -#ifdef PI2 - PIN_ADD(PI2) -#endif -#ifdef PI3 - PIN_ADD(PI3) -#endif -#ifdef PI4 - PIN_ADD(PI4) -#endif -#ifdef PI5 - PIN_ADD(PI5) -#endif -#ifdef PI6 - PIN_ADD(PI6) -#endif -#ifdef PI7 - PIN_ADD(PI7) -#endif -#ifdef PI8 - PIN_ADD(PI8) -#endif -#ifdef PI9 - PIN_ADD(PI9) -#endif -#ifdef PI10 - PIN_ADD(PI10) -#endif -#ifdef PI11 - PIN_ADD(PI11) -#endif -#ifdef PI12 - PIN_ADD(PI12) -#endif -#ifdef PI13 - PIN_ADD(PI13) -#endif -#ifdef PI14 - PIN_ADD(PI14) -#endif -#ifdef PI15 - PIN_ADD(PI15) -#endif - -#ifdef PJ0 - PIN_ADD(PJ0) -#endif -#ifdef PJ1 - PIN_ADD(PJ1) -#endif -#ifdef PJ2 - PIN_ADD(PJ2) -#endif -#ifdef PJ3 - PIN_ADD(PJ3) -#endif -#ifdef PJ4 - PIN_ADD(PJ4) -#endif -#ifdef PJ5 - PIN_ADD(PJ5) -#endif -#ifdef PJ6 - PIN_ADD(PJ6) -#endif -#ifdef PJ7 - PIN_ADD(PJ7) -#endif -#ifdef PJ8 - PIN_ADD(PJ8) -#endif -#ifdef PJ9 - PIN_ADD(PJ9) -#endif -#ifdef PJ10 - PIN_ADD(PJ10) -#endif -#ifdef PJ11 - PIN_ADD(PJ11) -#endif -#ifdef PJ12 - PIN_ADD(PJ12) -#endif -#ifdef PJ13 - PIN_ADD(PJ13) -#endif -#ifdef PJ14 - PIN_ADD(PJ14) -#endif -#ifdef PJ15 - PIN_ADD(PJ15) -#endif - -#ifdef PK0 - PIN_ADD(PK0) -#endif -#ifdef PK1 - PIN_ADD(PK1) -#endif -#ifdef PK2 - PIN_ADD(PK2) -#endif -#ifdef PK3 - PIN_ADD(PK3) -#endif -#ifdef PK4 - PIN_ADD(PK4) -#endif -#ifdef PK5 - PIN_ADD(PK5) -#endif -#ifdef PK6 - PIN_ADD(PK6) -#endif -#ifdef PK7 - PIN_ADD(PK7) -#endif -#ifdef PK8 - PIN_ADD(PK8) -#endif -#ifdef PK9 - PIN_ADD(PK9) -#endif -#ifdef PK10 - PIN_ADD(PK10) -#endif -#ifdef PK11 - PIN_ADD(PK11) -#endif -#ifdef PK12 - PIN_ADD(PK12) -#endif -#ifdef PK13 - PIN_ADD(PK13) -#endif -#ifdef PK14 - PIN_ADD(PK14) -#endif -#ifdef PK15 - PIN_ADD(PK15) -#endif - -#ifdef PL0 - PIN_ADD(PL0) -#endif -#ifdef PL1 - PIN_ADD(PL1) -#endif -#ifdef PL2 - PIN_ADD(PL2) -#endif -#ifdef PL3 - PIN_ADD(PL3) -#endif -#ifdef PL4 - PIN_ADD(PL4) -#endif -#ifdef PL5 - PIN_ADD(PL5) -#endif -#ifdef PL6 - PIN_ADD(PL6) -#endif -#ifdef PL7 - PIN_ADD(PL7) -#endif -#ifdef PL8 - PIN_ADD(PL8) -#endif -#ifdef PL9 - PIN_ADD(PL9) -#endif -#ifdef PL10 - PIN_ADD(PL10) -#endif -#ifdef PL11 - PIN_ADD(PL11) -#endif -#ifdef PL12 - PIN_ADD(PL12) -#endif -#ifdef PL13 - PIN_ADD(PL13) -#endif -#ifdef PL14 - PIN_ADD(PL14) -#endif -#ifdef PL15 - PIN_ADD(PL15) -#endif diff --git a/src/HAL/STM32/sdio.cpp b/src/HAL/STM32/sdio.cpp deleted file mode 100644 index 41fe90b..0000000 --- a/src/HAL/STM32/sdio.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SDIO_SUPPORT) - -#include "sdio.h" - -#include -#include - -#if defined(STM32F103xE) || defined(STM32F103xG) - #include - #include -#elif defined(STM32F4xx) - #include - #include - #include - #include -#elif defined(STM32F7xx) - #include - #include - #include - #include -#elif defined(STM32H7xx) - #define SDIO_FOR_STM32H7 - #include - #include - #include - #include -#else - #error "SDIO is only supported with STM32F103xE, STM32F103xG, STM32F4xx, STM32F7xx, and STM32H7xx." -#endif - -// SDIO Max Clock (naming from STM Manual, don't change) -#define SDIOCLK 48000000 - -// Target Clock, configurable. Default is 18MHz, from STM32F1 -#ifndef SDIO_CLOCK - #define SDIO_CLOCK 18000000 // 18 MHz -#endif - -SD_HandleTypeDef hsd; // SDIO structure - -static uint32_t clock_to_divider(uint32_t clk) { - #ifdef SDIO_FOR_STM32H7 - // SDMMC_CK frequency = sdmmc_ker_ck / [2 * CLKDIV]. - uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC); - return sdmmc_clk / (2U * SDIO_CLOCK) + (sdmmc_clk % (2U * SDIO_CLOCK) != 0); - #else - // limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals - // Also limited to no more than 48Mhz (SDIOCLK). - const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq(); - clk = min(clk, (uint32_t)(pclk2 * 8 / 3)); - clk = min(clk, (uint32_t)SDIOCLK); - // Round up divider, so we don't run the card over the speed supported, - // and subtract by 2, because STM32 will add 2, as written in the manual: - // SDIO_CK frequency = SDIOCLK / [CLKDIV + 2] - return pclk2 / clk + (pclk2 % clk != 0) - 2; - #endif -} - -// Start the SDIO clock -void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { - UNUSED(hsd); - #ifdef SDIO_FOR_STM32H7 - pinmap_pinout(PC_12, PinMap_SD); - pinmap_pinout(PD_2, PinMap_SD); - pinmap_pinout(PC_8, PinMap_SD); - #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // Define D1-D3 only for 4-bit wide SDIO bus - pinmap_pinout(PC_9, PinMap_SD); - pinmap_pinout(PC_10, PinMap_SD); - pinmap_pinout(PC_11, PinMap_SD); - #endif - __HAL_RCC_SDMMC1_CLK_ENABLE(); - HAL_NVIC_EnableIRQ(SDMMC1_IRQn); - #else - __HAL_RCC_SDIO_CLK_ENABLE(); - #endif -} - -#ifdef SDIO_FOR_STM32H7 - - #define SD_TIMEOUT 1000 // ms - - extern "C" void SDMMC1_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); } - - uint8_t waitingRxCplt = 0, waitingTxCplt = 0; - void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsdio) { waitingTxCplt = 0; } - void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsdio) { waitingRxCplt = 0; } - - void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) { - __HAL_RCC_SDMMC1_FORCE_RESET(); delay(10); - __HAL_RCC_SDMMC1_RELEASE_RESET(); delay(10); - } - - bool SDIO_Init() { - HAL_StatusTypeDef sd_state = HAL_OK; - if (hsd.Instance == SDMMC1) HAL_SD_DeInit(&hsd); - - // HAL SD initialization - hsd.Instance = SDMMC1; - hsd.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; - hsd.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; - hsd.Init.BusWide = SDMMC_BUS_WIDE_1B; - hsd.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; - hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK); - sd_state = HAL_SD_Init(&hsd); - - #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) - if (sd_state == HAL_OK) - sd_state = HAL_SD_ConfigWideBusOperation(&hsd, SDMMC_BUS_WIDE_4B); - #endif - - return (sd_state == HAL_OK); - } - -#else // !SDIO_FOR_STM32H7 - - #define SD_TIMEOUT 500 // ms - - // SDIO retries, configurable. Default is 3, from STM32F1 - #ifndef SDIO_READ_RETRIES - #define SDIO_READ_RETRIES 3 - #endif - - // F4 supports one DMA for RX and another for TX, but Marlin will never - // do read and write at same time, so we use the same DMA for both. - DMA_HandleTypeDef hdma_sdio; - - #ifdef STM32F1xx - #define DMA_IRQ_HANDLER DMA2_Channel4_5_IRQHandler - #elif defined(STM32F4xx) - #define DMA_IRQ_HANDLER DMA2_Stream3_IRQHandler - #else - #error "Unknown STM32 architecture." - #endif - - extern "C" void SDIO_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); } - extern "C" void DMA_IRQ_HANDLER(void) { HAL_DMA_IRQHandler(&hdma_sdio); } - - /* - SDIO_INIT_CLK_DIV is 118 - SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2) - SDIO init clock frequency should not exceed 400kHz = 48MHz / (118 + 2) - - Default TRANSFER_CLOCK_DIV is 2 (118 / 40) - Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz - This might be too fast for stable SDIO operations - - MKS Robin SDIO seems stable with BusWide 1bit and ClockDiv 8 (i.e., 4.8MHz SDIO clock frequency) - More testing is required as there are clearly some 4bit init problems. - */ - - void go_to_transfer_speed() { - /* Default SDIO peripheral configuration for SD card initialization */ - hsd.Init.ClockEdge = hsd.Init.ClockEdge; - hsd.Init.ClockBypass = hsd.Init.ClockBypass; - hsd.Init.ClockPowerSave = hsd.Init.ClockPowerSave; - hsd.Init.BusWide = hsd.Init.BusWide; - hsd.Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; - hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK); - - /* Initialize SDIO peripheral interface with default configuration */ - SDIO_Init(hsd.Instance, hsd.Init); - } - - void SD_LowLevel_Init() { - uint32_t tempreg; - - // Enable GPIO clocks - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOD_CLK_ENABLE(); - - GPIO_InitTypeDef GPIO_InitStruct; - - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = 1; // GPIO_NOPULL - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - - #if DISABLED(STM32F1xx) - GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; - #endif - - GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus - GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3 - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - #endif - - // Configure PD.02 CMD line - GPIO_InitStruct.Pin = GPIO_PIN_2; - HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); - - // Setup DMA - #ifdef STM32F1xx - hdma_sdio.Init.Mode = DMA_NORMAL; - hdma_sdio.Instance = DMA2_Channel4; - HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn); - #elif defined(STM32F4xx) - hdma_sdio.Init.Mode = DMA_PFCTRL; - hdma_sdio.Instance = DMA2_Stream3; - hdma_sdio.Init.Channel = DMA_CHANNEL_4; - hdma_sdio.Init.FIFOMode = DMA_FIFOMODE_ENABLE; - hdma_sdio.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - hdma_sdio.Init.MemBurst = DMA_MBURST_INC4; - hdma_sdio.Init.PeriphBurst = DMA_PBURST_INC4; - HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); - #endif - HAL_NVIC_EnableIRQ(SDIO_IRQn); - hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE; - hdma_sdio.Init.MemInc = DMA_MINC_ENABLE; - hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; - hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; - hdma_sdio.Init.Priority = DMA_PRIORITY_LOW; - __HAL_LINKDMA(&hsd, hdmarx, hdma_sdio); - __HAL_LINKDMA(&hsd, hdmatx, hdma_sdio); - - #ifdef STM32F1xx - __HAL_RCC_SDIO_CLK_ENABLE(); - __HAL_RCC_DMA2_CLK_ENABLE(); - #else - __HAL_RCC_SDIO_FORCE_RESET(); delay(2); - __HAL_RCC_SDIO_RELEASE_RESET(); delay(2); - __HAL_RCC_SDIO_CLK_ENABLE(); - - __HAL_RCC_DMA2_FORCE_RESET(); delay(2); - __HAL_RCC_DMA2_RELEASE_RESET(); delay(2); - __HAL_RCC_DMA2_CLK_ENABLE(); - #endif - - // Initialize the SDIO (with initial <400Khz Clock) - tempreg = 0 // Reset value - | SDIO_CLKCR_CLKEN // Clock enabled - | SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz - // Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable - SDIO->CLKCR = tempreg; - - // Power up the SDIO - SDIO_PowerState_ON(SDIO); - hsd.Instance = SDIO; - } - - bool SDIO_Init() { - uint8_t retryCnt = SDIO_READ_RETRIES; - - bool status; - hsd.Instance = SDIO; - hsd.State = HAL_SD_STATE_RESET; - - SD_LowLevel_Init(); - - uint8_t retry_Cnt = retryCnt; - for (;;) { - hal.watchdog_refresh(); - status = (bool) HAL_SD_Init(&hsd); - if (!status) break; - if (!--retry_Cnt) return false; // return failing status if retries are exhausted - } - - go_to_transfer_speed(); - - #if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined - retry_Cnt = retryCnt; - for (;;) { - hal.watchdog_refresh(); - if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required - if (!--retry_Cnt) break; - } - if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode - hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET - SD_LowLevel_Init(); - retry_Cnt = retryCnt; - for (;;) { - hal.watchdog_refresh(); - status = (bool) HAL_SD_Init(&hsd); - if (!status) break; - if (!--retry_Cnt) return false; // return failing status if retries are exhausted - } - go_to_transfer_speed(); - } - #endif - - return true; - } - - /** - * @brief Read or Write a block - * @details Read or Write a block with SDIO - * - * @param block The block index - * @param src The data buffer source for a write - * @param dst The data buffer destination for a read - * - * @return true on success - */ - static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) { - if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false; - - hal.watchdog_refresh(); - - HAL_StatusTypeDef ret; - if (src) { - hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH; - HAL_DMA_Init(&hdma_sdio); - ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*)src, block, 1); - } - else { - hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY; - HAL_DMA_Init(&hdma_sdio); - ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*)dst, block, 1); - } - - if (ret != HAL_OK) { - HAL_DMA_Abort_IT(&hdma_sdio); - HAL_DMA_DeInit(&hdma_sdio); - return false; - } - - millis_t timeout = millis() + SD_TIMEOUT; - // Wait the transfer - while (hsd.State != HAL_SD_STATE_READY) { - if (ELAPSED(millis(), timeout)) { - HAL_DMA_Abort_IT(&hdma_sdio); - HAL_DMA_DeInit(&hdma_sdio); - return false; - } - } - - while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0 - || __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ } - - HAL_DMA_Abort_IT(&hdma_sdio); - HAL_DMA_DeInit(&hdma_sdio); - - timeout = millis() + SD_TIMEOUT; - while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (ELAPSED(millis(), timeout)) return false; - - return true; - } - -#endif // !SDIO_FOR_STM32H7 - -/** - * @brief Read a block - * @details Read a block from media with SDIO - * - * @param block The block index - * @param src The block buffer - * - * @return true on success - */ -bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) { - #ifdef SDIO_FOR_STM32H7 - - uint32_t timeout = HAL_GetTick() + SD_TIMEOUT; - - while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) - if (HAL_GetTick() >= timeout) return false; - - waitingRxCplt = 1; - if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*)dst, block, 1) != HAL_OK) - return false; - - timeout = HAL_GetTick() + SD_TIMEOUT; - while (waitingRxCplt) - if (HAL_GetTick() >= timeout) return false; - - return true; - - #else - - uint8_t retries = SDIO_READ_RETRIES; - while (retries--) if (SDIO_ReadWriteBlock_DMA(block, nullptr, dst)) return true; - return false; - - #endif -} - -/** - * @brief Write a block - * @details Write a block to media with SDIO - * - * @param block The block index - * @param src The block data - * - * @return true on success - */ -bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { - #ifdef SDIO_FOR_STM32H7 - - uint32_t timeout = HAL_GetTick() + SD_TIMEOUT; - - while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) - if (HAL_GetTick() >= timeout) return false; - - waitingTxCplt = 1; - if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*)src, block, 1) != HAL_OK) - return false; - - timeout = HAL_GetTick() + SD_TIMEOUT; - while (waitingTxCplt) - if (HAL_GetTick() >= timeout) return false; - - return true; - - #else - - uint8_t retries = SDIO_READ_RETRIES; - while (retries--) if (SDIO_ReadWriteBlock_DMA(block, src, nullptr)) return true; - return false; - - #endif -} - -bool SDIO_IsReady() { - return hsd.State == HAL_SD_STATE_READY; -} - -uint32_t SDIO_GetCardSize() { - return (uint32_t)(hsd.SdCard.BlockNbr) * (hsd.SdCard.BlockSize); -} - -#endif // SDIO_SUPPORT -#endif // HAL_STM32 diff --git a/src/HAL/STM32/sdio.h b/src/HAL/STM32/sdio.h deleted file mode 100644 index cf5539c..0000000 --- a/src/HAL/STM32/sdio.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define SDIO_D0_PIN PC8 -#define SDIO_D1_PIN PC9 -#define SDIO_D2_PIN PC10 -#define SDIO_D3_PIN PC11 -#define SDIO_CK_PIN PC12 -#define SDIO_CMD_PIN PD2 diff --git a/src/HAL/STM32/spi_pins.h b/src/HAL/STM32/spi_pins.h deleted file mode 100644 index 7f341a8..0000000 --- a/src/HAL/STM32/spi_pins.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Define SPI Pins: SCK, MISO, MOSI, SS - */ -#ifndef SD_SCK_PIN - #define SD_SCK_PIN PIN_SPI_SCK -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN PIN_SPI_MISO -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN PIN_SPI_MOSI -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN PIN_SPI_SS -#endif diff --git a/src/HAL/STM32/tft/gt911.cpp b/src/HAL/STM32/tft/gt911.cpp deleted file mode 100644 index 180abc6..0000000 --- a/src/HAL/STM32/tft/gt911.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General 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 "../../platforms.h" - -#ifdef HAL_STM32 - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(TFT_TOUCH_DEVICE_GT911) - -#include "gt911.h" -#include "pinconfig.h" - -SW_IIC::SW_IIC(uint16_t sda, uint16_t scl) { - scl_pin = scl; - sda_pin = sda; -} - -// Software I2C hardware io init -void SW_IIC::init() { - OUT_WRITE(scl_pin, HIGH); - OUT_WRITE(sda_pin, HIGH); -} - -// Software I2C start signal -void SW_IIC::start() { - write_sda(HIGH); // SDA = 1 - write_scl(HIGH); // SCL = 1 - iic_delay(2); - write_sda(LOW); // SDA = 0 - iic_delay(1); - write_scl(LOW); // SCL = 0 // keep SCL low, avoid false stop caused by level jump caused by SDA switching IN/OUT -} - -// Software I2C stop signal -void SW_IIC::stop() { - write_scl(LOW); // SCL = 0 - iic_delay(2); - write_sda(LOW); // SDA = 0 - iic_delay(2); - write_scl(HIGH); // SCL = 1 - iic_delay(2); - write_sda(HIGH); // SDA = 1 -} - -// Software I2C sends ACK or NACK signal -void SW_IIC::send_ack(bool ack) { - write_sda(ack ? LOW : HIGH); // SDA = !ack - iic_delay(2); - write_scl(HIGH); // SCL = 1 - iic_delay(2); - write_scl(LOW); // SCL = 0 -} - -// Software I2C read ACK or NACK signal -bool SW_IIC::read_ack() { - bool error = 0; - set_sda_in(); - - iic_delay(2); - - write_scl(HIGH); // SCL = 1 - error = read_sda(); - - iic_delay(2); - - write_scl(LOW); // SCL = 0 - - set_sda_out(); - return error; -} - -void SW_IIC::send_byte(uint8_t txd) { - LOOP_L_N(i, 8) { - write_sda(txd & 0x80); // write data bit - txd <<= 1; - iic_delay(1); - write_scl(HIGH); // SCL = 1 - iic_delay(2); - write_scl(LOW); // SCL = 0 - iic_delay(1); - } - - read_ack(); // wait ack -} - -uint8_t SW_IIC::read_byte(bool ack) { - uint8_t data = 0; - - set_sda_in(); - LOOP_L_N(i, 8) { - write_scl(HIGH); // SCL = 1 - iic_delay(1); - data <<= 1; - if (read_sda()) data++; - write_scl(LOW); // SCL = 0 - iic_delay(2); - } - set_sda_out(); - - send_ack(ack); - - return data; -} - -GT911_REG_MAP GT911::reg; -SW_IIC GT911::sw_iic = SW_IIC(GT911_SW_I2C_SDA_PIN, GT911_SW_I2C_SCL_PIN); - -void GT911::write_reg(uint16_t reg, uint8_t reg_len, uint8_t* w_data, uint8_t w_len) { - sw_iic.start(); - sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address - LOOP_L_N(i, reg_len) { // Set reg address - uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF; - sw_iic.send_byte(r); - } - - LOOP_L_N(i, w_len) { // Write data to reg - sw_iic.send_byte(w_data[i]); - } - sw_iic.stop(); -} - -void GT911::read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_len) { - sw_iic.start(); - sw_iic.send_byte(gt911_slave_address); // Set IIC Slave address - LOOP_L_N(i, reg_len) { // Set reg address - uint8_t r = (reg >> (8 * (reg_len - 1 - i))) & 0xFF; - sw_iic.send_byte(r); - } - - sw_iic.start(); - sw_iic.send_byte(gt911_slave_address + 1); // Set read mode - - LOOP_L_N(i, r_len) { - r_data[i] = sw_iic.read_byte(1); // Read data from reg - } - sw_iic.stop(); -} - -void GT911::Init() { - OUT_WRITE(GT911_RST_PIN, LOW); - OUT_WRITE(GT911_INT_PIN, LOW); - delay(11); - WRITE(GT911_INT_PIN, HIGH); - delayMicroseconds(110); - WRITE(GT911_RST_PIN, HIGH); - delay(6); - WRITE(GT911_INT_PIN, LOW); - delay(55); - SET_INPUT(GT911_INT_PIN); - - sw_iic.init(); - - uint8_t clear_reg = 0x00; - write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start -} - -bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) { - read_reg(0x814E, 2, ®.REG.status, 1); - - if (reg.REG.status >= 0x80 && reg.REG.status <= 0x85) { - read_reg(0x8150, 2, reg.map + 2, 38); - uint8_t clear_reg = 0x00; - write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start - // First touch point - *x = ((reg.REG.point[0].xh & 0x0F) << 8) | reg.REG.point[0].xl; - *y = ((reg.REG.point[0].yh & 0x0F) << 8) | reg.REG.point[0].yl; - return true; - } - return false; -} - -bool GT911::getPoint(int16_t *x, int16_t *y) { - static bool touched = 0; - static int16_t read_x = 0, read_y = 0; - static millis_t next_time = 0; - - if (ELAPSED(millis(), next_time)) { - touched = getFirstTouchPoint(&read_x, &read_y); - next_time = millis() + 20; - } - - *x = read_x; - *y = read_y; - return touched; -} - -#endif // TFT_TOUCH_DEVICE_GT911 -#endif // HAL_STM32 diff --git a/src/HAL/STM32/tft/gt911.h b/src/HAL/STM32/tft/gt911.h deleted file mode 100644 index 6ecfe8b..0000000 --- a/src/HAL/STM32/tft/gt911.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#define GT911_SLAVE_ADDRESS 0x28 - -#if !PIN_EXISTS(GT911_RST) - #error "GT911_RST_PIN is not defined." -#elif !PIN_EXISTS(GT911_INT) - #error "GT911_INT_PIN is not defined." -#elif !PIN_EXISTS(GT911_SW_I2C_SCL) - #error "GT911_SW_I2C_SCL_PIN is not defined." -#elif !PIN_EXISTS(GT911_SW_I2C_SDA) - #error "GT911_SW_I2C_SDA_PIN is not defined." -#endif - -class SW_IIC { - private: - uint16_t scl_pin; - uint16_t sda_pin; - void write_scl(bool level) - { - WRITE(scl_pin, level); - } - void write_sda(bool level) - { - WRITE(sda_pin, level); - } - bool read_sda() - { - return READ(sda_pin); - } - void set_sda_out() - { - SET_OUTPUT(sda_pin); - } - void set_sda_in() - { - SET_INPUT_PULLUP(sda_pin); - } - static void iic_delay(uint8_t t) - { - delayMicroseconds(t); - } - - public: - SW_IIC(uint16_t sda, uint16_t scl); - // setSCL/SDA have to be called before begin() - void setSCL(uint16_t scl) - { - scl_pin = scl; - }; - void setSDA(uint16_t sda) - { - sda_pin = sda; - }; - void init(); // Initialize the IO port of IIC - void start(); // Send IIC start signal - void stop(); // Send IIC stop signal - void send_byte(uint8_t txd); // IIC sends a byte - uint8_t read_byte(bool ack); // IIC reads a byte - void send_ack(bool ack); // IIC sends ACK or NACK signal - bool read_ack(); -}; - -typedef struct __attribute__((__packed__)) { - uint8_t xl; - uint8_t xh; - uint8_t yl; - uint8_t yh; - uint8_t sizel; - uint8_t sizeh; - uint8_t reserved; - uint8_t track_id; -} GT911_POINT; - -typedef union __attribute__((__packed__)) { - uint8_t map[42]; - struct { - uint8_t status; // 0x814E - uint8_t track_id; // 0x814F - - GT911_POINT point[5]; // [0]:0x8150 - 0x8157 / [1]:0x8158 - 0x815F / [2]:0x8160 - 0x8167 / [3]:0x8168 - 0x816F / [4]:0x8170 - 0x8177 - } REG; -} GT911_REG_MAP; - -class GT911 { - private: - static const uint8_t gt911_slave_address = GT911_SLAVE_ADDRESS; - static GT911_REG_MAP reg; - static SW_IIC sw_iic; - static void write_reg(uint16_t reg, uint8_t reg_len, uint8_t* w_data, uint8_t w_len); - static void read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_len); - - public: - static void Init(); - static bool getFirstTouchPoint(int16_t *x, int16_t *y); - static bool getPoint(int16_t *x, int16_t *y); -}; diff --git a/src/HAL/STM32/tft/tft_fsmc.cpp b/src/HAL/STM32/tft/tft_fsmc.cpp deleted file mode 100644 index e68b3c1..0000000 --- a/src/HAL/STM32/tft/tft_fsmc.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../platforms.h" - -#ifdef HAL_STM32 - -#include "../../../inc/MarlinConfig.h" - -#if HAS_FSMC_TFT - -#include "tft_fsmc.h" -#include "pinconfig.h" - -SRAM_HandleTypeDef TFT_FSMC::SRAMx; -DMA_HandleTypeDef TFT_FSMC::DMAtx; -LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD; - -void TFT_FSMC::Init() { - uint32_t controllerAddress; - FSMC_NORSRAM_TimingTypeDef Timing, ExtTiming; - - uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS); - - // Perform the SRAM1 memory initialization sequence - SRAMx.Instance = FSMC_NORSRAM_DEVICE; - SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE; - // SRAMx.Init - SRAMx.Init.NSBank = NSBank; - SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE; - SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM; - SRAMx.Init.MemoryDataWidth = TERN(TFT_INTERFACE_FSMC_8BIT, FSMC_NORSRAM_MEM_BUS_WIDTH_8, FSMC_NORSRAM_MEM_BUS_WIDTH_16); - SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE; - SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW; - SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE; - SRAMx.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS; - SRAMx.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE; - SRAMx.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE; - SRAMx.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE; - SRAMx.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; - SRAMx.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE; - #ifdef STM32F4xx - SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE; - #endif - // Read Timing - relatively slow to ensure ID information is correctly read from TFT controller - // Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss - Timing.AddressSetupTime = 15; - Timing.AddressHoldTime = 15; - Timing.DataSetupTime = 24; - Timing.BusTurnAroundDuration = 0; - Timing.CLKDivision = 16; - Timing.DataLatency = 17; - Timing.AccessMode = FSMC_ACCESS_MODE_A; - // Write Timing - // Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss - ExtTiming.AddressSetupTime = 8; - ExtTiming.AddressHoldTime = 15; - ExtTiming.DataSetupTime = 8; - ExtTiming.BusTurnAroundDuration = 0; - ExtTiming.CLKDivision = 16; - ExtTiming.DataLatency = 17; - ExtTiming.AccessMode = FSMC_ACCESS_MODE_A; - - __HAL_RCC_FSMC_CLK_ENABLE(); - - for (uint16_t i = 0; PinMap_FSMC[i].pin != NC; i++) - pinmap_pinout(PinMap_FSMC[i].pin, PinMap_FSMC); - pinmap_pinout(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS); - pinmap_pinout(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS); - - controllerAddress = FSMC_BANK1_1; - #ifdef PF0 - switch (NSBank) { - case FSMC_NORSRAM_BANK2: controllerAddress = FSMC_BANK1_2 ; break; - case FSMC_NORSRAM_BANK3: controllerAddress = FSMC_BANK1_3 ; break; - case FSMC_NORSRAM_BANK4: controllerAddress = FSMC_BANK1_4 ; break; - } - #endif - - controllerAddress |= (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_RS_PIN), PinMap_FSMC_RS); - - HAL_SRAM_Init(&SRAMx, &Timing, &ExtTiming); - - __HAL_RCC_DMA2_CLK_ENABLE(); - - #ifdef STM32F1xx - DMAtx.Instance = DMA2_Channel1; - #elif defined(STM32F4xx) - DMAtx.Instance = DMA2_Stream0; - DMAtx.Init.Channel = DMA_CHANNEL_0; - DMAtx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; - DMAtx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - DMAtx.Init.MemBurst = DMA_MBURST_SINGLE; - DMAtx.Init.PeriphBurst = DMA_PBURST_SINGLE; - #endif - - DMAtx.Init.Direction = DMA_MEMORY_TO_MEMORY; - DMAtx.Init.MemInc = DMA_MINC_DISABLE; - DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; - DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - DMAtx.Init.Mode = DMA_NORMAL; - DMAtx.Init.Priority = DMA_PRIORITY_HIGH; - - LCD = (LCD_CONTROLLER_TypeDef *)controllerAddress; -} - -uint32_t TFT_FSMC::GetID() { - uint32_t id; - WriteReg(0); - id = LCD->RAM; - - if (id == 0) - id = ReadID(LCD_READ_ID); - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) - id = ReadID(LCD_READ_ID4); - return id; -} - -uint32_t TFT_FSMC::ReadID(tft_data_t Reg) { - uint32_t id; - WriteReg(Reg); - id = LCD->RAM; // dummy read - id = Reg << 24; - id |= (LCD->RAM & 0x00FF) << 16; - id |= (LCD->RAM & 0x00FF) << 8; - id |= LCD->RAM & 0x00FF; - return id; -} - -bool TFT_FSMC::isBusy() { - #if defined(STM32F1xx) - volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET; - #elif defined(STM32F4xx) - volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN; - #endif - if (dmaEnabled) { - if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) - Abort(); - } - else - Abort(); - return dmaEnabled; -} - -void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - DMAtx.Init.PeriphInc = MemoryIncrease; - HAL_DMA_Init(&DMAtx); - DataTransferBegin(); - HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(LCD->RAM), Count); - HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); - Abort(); -} - -#endif // HAS_FSMC_TFT -#endif // HAL_STM32 diff --git a/src/HAL/STM32/tft/tft_fsmc.h b/src/HAL/STM32/tft/tft_fsmc.h deleted file mode 100644 index 2200aba..0000000 --- a/src/HAL/STM32/tft/tft_fsmc.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#ifdef STM32F1xx - #include "stm32f1xx_hal.h" -#elif defined(STM32F4xx) - #include "stm32f4xx_hal.h" -#else - #error "FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware." -#endif - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#define DATASIZE_8BIT SPI_DATASIZE_8BIT -#define DATASIZE_16BIT SPI_DATASIZE_16BIT -#define TFT_IO_DRIVER TFT_FSMC - -#define TFT_DATASIZE TERN(TFT_INTERFACE_FSMC_8BIT, DATASIZE_8BIT, DATASIZE_16BIT) -typedef TERN(TFT_INTERFACE_FSMC_8BIT, uint8_t, uint16_t) tft_data_t; - -typedef struct { - __IO tft_data_t REG; - __IO tft_data_t RAM; -} LCD_CONTROLLER_TypeDef; - -class TFT_FSMC { - private: - static SRAM_HandleTypeDef SRAMx; - static DMA_HandleTypeDef DMAtx; - - static LCD_CONTROLLER_TypeDef *LCD; - - static uint32_t ReadID(tft_data_t Reg); - static void Transmit(tft_data_t Data) { LCD->RAM = Data; __DSB(); } - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - - public: - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort() { __HAL_DMA_DISABLE(&DMAtx); } - - static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {} - static void DataTransferEnd() {}; - - static void WriteData(uint16_t Data) { Transmit(tft_data_t(Data)); } - static void WriteReg(uint16_t Reg) { LCD->REG = tft_data_t(Reg); __DSB(); } - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); } - static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - while (Count > 0) { - TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); - Count = Count > 0xFFFF ? Count - 0xFFFF : 0; - } - } -}; - -#ifdef STM32F1xx - #define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE) -#elif defined(STM32F4xx) - #define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FSMC) - #define FSMC_BANK1_1 0x60000000U - #define FSMC_BANK1_2 0x64000000U - #define FSMC_BANK1_3 0x68000000U - #define FSMC_BANK1_4 0x6C000000U -#else - #error No configuration for this MCU -#endif - -const PinMap PinMap_FSMC[] = { - {PD_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D00 - {PD_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D01 - {PD_0, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D02 - {PD_1, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D03 - {PE_7, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D04 - {PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05 - {PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06 - {PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07 - #if DISABLED(TFT_INTERFACE_FSMC_8BIT) - {PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08 - {PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09 - {PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10 - {PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11 - {PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12 - {PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13 - {PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14 - {PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15 - #endif - {PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE - {PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE - {NC, NP, 0} -}; - -const PinMap PinMap_FSMC_CS[] = { - {PD_7, (void *)FSMC_NORSRAM_BANK1, FSMC_PIN_DATA}, // FSMC_NE1 - #ifdef PF0 - {PG_9, (void *)FSMC_NORSRAM_BANK2, FSMC_PIN_DATA}, // FSMC_NE2 - {PG_10, (void *)FSMC_NORSRAM_BANK3, FSMC_PIN_DATA}, // FSMC_NE3 - {PG_12, (void *)FSMC_NORSRAM_BANK4, FSMC_PIN_DATA}, // FSMC_NE4 - #endif - {NC, NP, 0} -}; - -#if ENABLED(TFT_INTERFACE_FSMC_8BIT) - #define FSMC_RS(A) (void *)((2 << (A-1)) - 1) -#else - #define FSMC_RS(A) (void *)((2 << A) - 2) -#endif - -const PinMap PinMap_FSMC_RS[] = { - #ifdef PF0 - {PF_0, FSMC_RS( 0), FSMC_PIN_DATA}, // FSMC_A0 - {PF_1, FSMC_RS( 1), FSMC_PIN_DATA}, // FSMC_A1 - {PF_2, FSMC_RS( 2), FSMC_PIN_DATA}, // FSMC_A2 - {PF_3, FSMC_RS( 3), FSMC_PIN_DATA}, // FSMC_A3 - {PF_4, FSMC_RS( 4), FSMC_PIN_DATA}, // FSMC_A4 - {PF_5, FSMC_RS( 5), FSMC_PIN_DATA}, // FSMC_A5 - {PF_12, FSMC_RS( 6), FSMC_PIN_DATA}, // FSMC_A6 - {PF_13, FSMC_RS( 7), FSMC_PIN_DATA}, // FSMC_A7 - {PF_14, FSMC_RS( 8), FSMC_PIN_DATA}, // FSMC_A8 - {PF_15, FSMC_RS( 9), FSMC_PIN_DATA}, // FSMC_A9 - {PG_0, FSMC_RS(10), FSMC_PIN_DATA}, // FSMC_A10 - {PG_1, FSMC_RS(11), FSMC_PIN_DATA}, // FSMC_A11 - {PG_2, FSMC_RS(12), FSMC_PIN_DATA}, // FSMC_A12 - {PG_3, FSMC_RS(13), FSMC_PIN_DATA}, // FSMC_A13 - {PG_4, FSMC_RS(14), FSMC_PIN_DATA}, // FSMC_A14 - {PG_5, FSMC_RS(15), FSMC_PIN_DATA}, // FSMC_A15 - #endif - {PD_11, FSMC_RS(16), FSMC_PIN_DATA}, // FSMC_A16 - {PD_12, FSMC_RS(17), FSMC_PIN_DATA}, // FSMC_A17 - {PD_13, FSMC_RS(18), FSMC_PIN_DATA}, // FSMC_A18 - {PE_3, FSMC_RS(19), FSMC_PIN_DATA}, // FSMC_A19 - {PE_4, FSMC_RS(20), FSMC_PIN_DATA}, // FSMC_A20 - {PE_5, FSMC_RS(21), FSMC_PIN_DATA}, // FSMC_A21 - {PE_6, FSMC_RS(22), FSMC_PIN_DATA}, // FSMC_A22 - {PE_2, FSMC_RS(23), FSMC_PIN_DATA}, // FSMC_A23 - #ifdef PF0 - {PG_13, FSMC_RS(24), FSMC_PIN_DATA}, // FSMC_A24 - {PG_14, FSMC_RS(25), FSMC_PIN_DATA}, // FSMC_A25 - #endif - {NC, NP, 0} -}; diff --git a/src/HAL/STM32/tft/tft_ltdc.cpp b/src/HAL/STM32/tft/tft_ltdc.cpp deleted file mode 100644 index 95871bf..0000000 --- a/src/HAL/STM32/tft/tft_ltdc.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General 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 "../../platforms.h" - -#ifdef HAL_STM32 - -#include "../../../inc/MarlinConfig.h" - -#if HAS_LTDC_TFT - -#include "tft_ltdc.h" -#include "pinconfig.h" - -#define FRAME_BUFFER_ADDRESS 0XC0000000 // SDRAM address - -#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) -#define REFRESH_COUNT ((uint32_t)0x02A5) // SDRAM refresh counter - -#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) -#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) -#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) -#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) -#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) -#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) -#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) -#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) -#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) -#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) -#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) - -void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command) { - - __IO uint32_t tmpmrd =0; - /* Step 1: Configure a clock configuration enable command */ - Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; - Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; - Command->AutoRefreshNumber = 1; - Command->ModeRegisterDefinition = 0; - /* Send the command */ - HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT); - - /* Step 2: Insert 100 us minimum delay */ - /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ - HAL_Delay(1); - - /* Step 3: Configure a PALL (precharge all) command */ - Command->CommandMode = FMC_SDRAM_CMD_PALL; - Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; - Command->AutoRefreshNumber = 1; - Command->ModeRegisterDefinition = 0; - /* Send the command */ - HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT); - - /* Step 4 : Configure a Auto-Refresh command */ - Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; - Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; - Command->AutoRefreshNumber = 8; - Command->ModeRegisterDefinition = 0; - /* Send the command */ - HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT); - - /* Step 5: Program the external memory mode register */ - tmpmrd = (uint32_t)(SDRAM_MODEREG_BURST_LENGTH_1 | - SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | - SDRAM_MODEREG_CAS_LATENCY_2 | - SDRAM_MODEREG_OPERATING_MODE_STANDARD | - SDRAM_MODEREG_WRITEBURST_MODE_SINGLE); - - Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE; - Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; - Command->AutoRefreshNumber = 1; - Command->ModeRegisterDefinition = tmpmrd; - /* Send the command */ - HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT); - - /* Step 6: Set the refresh rate counter */ - /* Set the device refresh rate */ - HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT); -} - -void SDRAM_Config() { - - __HAL_RCC_SYSCFG_CLK_ENABLE(); - __HAL_RCC_FMC_CLK_ENABLE(); - - SDRAM_HandleTypeDef hsdram; - FMC_SDRAM_TimingTypeDef SDRAM_Timing; - FMC_SDRAM_CommandTypeDef command; - - /* Configure the SDRAM device */ - hsdram.Instance = FMC_SDRAM_DEVICE; - hsdram.Init.SDBank = FMC_SDRAM_BANK1; - hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; - hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; - hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; - hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; - hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; - hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; - hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; - hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; - hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; - - /* Timing configuration for 100Mhz as SDRAM clock frequency (System clock is up to 200Mhz) */ - SDRAM_Timing.LoadToActiveDelay = 2; - SDRAM_Timing.ExitSelfRefreshDelay = 8; - SDRAM_Timing.SelfRefreshTime = 6; - SDRAM_Timing.RowCycleDelay = 6; - SDRAM_Timing.WriteRecoveryTime = 2; - SDRAM_Timing.RPDelay = 2; - SDRAM_Timing.RCDDelay = 2; - - /* Initialize the SDRAM controller */ - if (HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) - { - /* Initialization Error */ - } - - /* Program the SDRAM external device */ - SDRAM_Initialization_Sequence(&hsdram, &command); -} - -void LTDC_Config() { - - __HAL_RCC_LTDC_CLK_ENABLE(); - __HAL_RCC_DMA2D_CLK_ENABLE(); - - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; - - /* The PLL3R is configured to provide the LTDC PCLK clock */ - /* PLL3_VCO Input = HSE_VALUE / PLL3M = 25Mhz / 5 = 5 Mhz */ - /* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 5Mhz * 160 = 800 Mhz */ - /* PLLLCDCLK = PLL3_VCO Output/PLL3R = 800Mhz / 16 = 50Mhz */ - /* LTDC clock frequency = PLLLCDCLK = 50 Mhz */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; - PeriphClkInitStruct.PLL3.PLL3M = 5; - PeriphClkInitStruct.PLL3.PLL3N = 160; - PeriphClkInitStruct.PLL3.PLL3FRACN = 0; - PeriphClkInitStruct.PLL3.PLL3P = 2; - PeriphClkInitStruct.PLL3.PLL3Q = 2; - PeriphClkInitStruct.PLL3.PLL3R = (800 / LTDC_LCD_CLK); - PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; - PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_2; - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - - LTDC_HandleTypeDef hltdc_F; - LTDC_LayerCfgTypeDef pLayerCfg; - - /* LTDC Initialization -------------------------------------------------------*/ - - /* Polarity configuration */ - /* Initialize the horizontal synchronization polarity as active low */ - hltdc_F.Init.HSPolarity = LTDC_HSPOLARITY_AL; - /* Initialize the vertical synchronization polarity as active low */ - hltdc_F.Init.VSPolarity = LTDC_VSPOLARITY_AL; - /* Initialize the data enable polarity as active low */ - hltdc_F.Init.DEPolarity = LTDC_DEPOLARITY_AL; - /* Initialize the pixel clock polarity as input pixel clock */ - hltdc_F.Init.PCPolarity = LTDC_PCPOLARITY_IPC; - - /* Timing configuration */ - hltdc_F.Init.HorizontalSync = (LTDC_LCD_HSYNC - 1); - hltdc_F.Init.VerticalSync = (LTDC_LCD_VSYNC - 1); - hltdc_F.Init.AccumulatedHBP = (LTDC_LCD_HSYNC + LTDC_LCD_HBP - 1); - hltdc_F.Init.AccumulatedVBP = (LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1); - hltdc_F.Init.AccumulatedActiveH = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP - 1); - hltdc_F.Init.AccumulatedActiveW = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP - 1); - hltdc_F.Init.TotalHeigh = (TFT_HEIGHT + LTDC_LCD_VSYNC + LTDC_LCD_VBP + LTDC_LCD_VFP - 1); - hltdc_F.Init.TotalWidth = (TFT_WIDTH + LTDC_LCD_HSYNC + LTDC_LCD_HBP + LTDC_LCD_HFP - 1); - - /* Configure R,G,B component values for LCD background color : all black background */ - hltdc_F.Init.Backcolor.Blue = 0; - hltdc_F.Init.Backcolor.Green = 0; - hltdc_F.Init.Backcolor.Red = 0; - - hltdc_F.Instance = LTDC; - - /* Layer0 Configuration ------------------------------------------------------*/ - - /* Windowing configuration */ - pLayerCfg.WindowX0 = 0; - pLayerCfg.WindowX1 = TFT_WIDTH; - pLayerCfg.WindowY0 = 0; - pLayerCfg.WindowY1 = TFT_HEIGHT; - - /* Pixel Format configuration*/ - pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; - - /* Start Address configuration : frame buffer is located at SDRAM memory */ - pLayerCfg.FBStartAdress = (uint32_t)(FRAME_BUFFER_ADDRESS); - - /* Alpha constant (255 == totally opaque) */ - pLayerCfg.Alpha = 255; - - /* Default Color configuration (configure A,R,G,B component values) : no background color */ - pLayerCfg.Alpha0 = 0; /* fully transparent */ - pLayerCfg.Backcolor.Blue = 0; - pLayerCfg.Backcolor.Green = 0; - pLayerCfg.Backcolor.Red = 0; - - /* Configure blending factors */ - pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA; - pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA; - - /* Configure the number of lines and number of pixels per line */ - pLayerCfg.ImageWidth = TFT_WIDTH; - pLayerCfg.ImageHeight = TFT_HEIGHT; - - /* Configure the LTDC */ - if (HAL_LTDC_Init(&hltdc_F) != HAL_OK) - { - /* Initialization Error */ - } - - /* Configure the Layer*/ - if (HAL_LTDC_ConfigLayer(&hltdc_F, &pLayerCfg, 0) != HAL_OK) - { - /* Initialization Error */ - } -} - -uint16_t TFT_LTDC::x_min = 0; -uint16_t TFT_LTDC::x_max = 0; -uint16_t TFT_LTDC::y_min = 0; -uint16_t TFT_LTDC::y_max = 0; -uint16_t TFT_LTDC::x_cur = 0; -uint16_t TFT_LTDC::y_cur = 0; -uint8_t TFT_LTDC::reg = 0; -volatile uint16_t* TFT_LTDC::framebuffer = (volatile uint16_t* )FRAME_BUFFER_ADDRESS; - -void TFT_LTDC::Init() { - - // SDRAM pins init - for (uint16_t i = 0; PinMap_SDRAM[i].pin != NC; i++) - pinmap_pinout(PinMap_SDRAM[i].pin, PinMap_SDRAM); - - // SDRAM peripheral config - SDRAM_Config(); - - // LTDC pins init - for (uint16_t i = 0; PinMap_LTDC[i].pin != NC; i++) - pinmap_pinout(PinMap_LTDC[i].pin, PinMap_LTDC); - - // LTDC peripheral config - LTDC_Config(); -} - -uint32_t TFT_LTDC::GetID() { - return 0xABAB; -} - -uint32_t TFT_LTDC::ReadID(tft_data_t Reg) { - return 0xABAB; -} - -bool TFT_LTDC::isBusy() { - return false; -} - -uint16_t TFT_LTDC::ReadPoint(uint16_t x, uint16_t y) { - return framebuffer[(TFT_WIDTH * y) + x]; -} - -void TFT_LTDC::DrawPoint(uint16_t x, uint16_t y, uint16_t color) { - framebuffer[(TFT_WIDTH * y) + x] = color; -} - -void TFT_LTDC::DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color) { - - if (sx == ex || sy == ey) return; - - uint16_t offline = TFT_WIDTH - (ex - sx); - uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx]; - - CBI(DMA2D->CR, 0); - DMA2D->CR = 3 << 16; - DMA2D->OPFCCR = 0X02; - DMA2D->OOR = offline; - DMA2D->OMAR = addr; - DMA2D->NLR = (ey - sy) | ((ex - sx) << 16); - DMA2D->OCOLR = color; - SBI(DMA2D->CR, 0); - - uint32_t timeout = 0; - while (!TEST(DMA2D->ISR, 1)) { - timeout++; - if (timeout > 0x1FFFFF) break; - } - SBI(DMA2D->IFCR, 1); -} - -void TFT_LTDC::DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors) { - - if (sx == ex || sy == ey) return; - - uint16_t offline = TFT_WIDTH - (ex - sx); - uint32_t addr = (uint32_t)&framebuffer[(TFT_WIDTH * sy) + sx]; - - CBI(DMA2D->CR, 0); - DMA2D->CR = 0 << 16; - DMA2D->FGPFCCR = 0X02; - DMA2D->FGOR = 0; - DMA2D->OOR = offline; - DMA2D->FGMAR = (uint32_t)colors; - DMA2D->OMAR = addr; - DMA2D->NLR = (ey - sy) | ((ex - sx) << 16); - SBI(DMA2D->CR, 0); - - uint32_t timeout = 0; - while (!TEST(DMA2D->ISR, 1)) { - timeout++; - if (timeout > 0x1FFFFF) break; - } - SBI(DMA2D->IFCR, 1); -} - -void TFT_LTDC::WriteData(uint16_t data) { - switch (reg) { - case 0x01: x_cur = x_min = data; return; - case 0x02: x_max = data; return; - case 0x03: y_cur = y_min = data; return; - case 0x04: y_max = data; return; - } - Transmit(data); -} - -void TFT_LTDC::Transmit(tft_data_t Data) { - DrawPoint(x_cur, y_cur, Data); - x_cur++; - if (x_cur > x_max) { - x_cur = x_min; - y_cur++; - if (y_cur > y_max) y_cur = y_min; - } -} - -void TFT_LTDC::WriteReg(uint16_t Reg) { - reg = Reg; -} - -void TFT_LTDC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - - while (x_cur != x_min && Count) { - Transmit(*Data); - if (MemoryIncrease == DMA_PINC_ENABLE) Data++; - Count--; - } - - uint16_t width = x_max - x_min + 1; - uint16_t height = Count / width; - uint16_t x_end_cnt = Count - (width * height); - - if (height) { - if (MemoryIncrease == DMA_PINC_ENABLE) { - DrawImage(x_min, y_cur, x_min + width, y_cur + height, Data); - Data += width * height; - } - else - DrawRect(x_min, y_cur, x_min + width, y_cur + height, *Data); - y_cur += height; - } - - while (x_end_cnt) { - Transmit(*Data); - if (MemoryIncrease == DMA_PINC_ENABLE) Data++; - x_end_cnt--; - } -} - -#endif // HAS_LTDC_TFT -#endif // HAL_STM32 diff --git a/src/HAL/STM32/tft/tft_ltdc.h b/src/HAL/STM32/tft/tft_ltdc.h deleted file mode 100644 index 7b63d69..0000000 --- a/src/HAL/STM32/tft/tft_ltdc.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#ifdef STM32H7xx - #include "stm32h7xx_hal.h" -#else - #error "LTDC TFT is currently only supported on STM32H7 hardware." -#endif - -#define DATASIZE_8BIT SPI_DATASIZE_8BIT -#define DATASIZE_16BIT SPI_DATASIZE_16BIT -#define TFT_IO_DRIVER TFT_LTDC - -#define TFT_DATASIZE DATASIZE_16BIT -typedef uint16_t tft_data_t; - -class TFT_LTDC { - private: - static volatile uint16_t *framebuffer; - static uint16_t x_min, x_max, y_min, y_max, x_cur, y_cur; - static uint8_t reg; - - static uint32_t ReadID(tft_data_t Reg); - - static uint16_t ReadPoint(uint16_t x, uint16_t y); - static void DrawPoint(uint16_t x, uint16_t y, uint16_t color); - static void DrawRect(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t color); - static void DrawImage(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *colors); - static void Transmit(tft_data_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - - public: - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort() { /*__HAL_DMA_DISABLE(&DMAtx);*/ } - - static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {} - static void DataTransferEnd() {}; - - static void WriteData(uint16_t Data); - static void WriteReg(uint16_t Reg); - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); } - static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - while (Count > 0) { - TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); - Count = Count > 0xFFFF ? Count - 0xFFFF : 0; - } - } -}; - -const PinMap PinMap_LTDC[] = { - {PF_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_DE - {PG_7, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_CLK - {PI_9, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_VSYNC - {PI_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_HSYNC - - {PG_6, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R7 - {PH_12, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R6 - {PH_11, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R5 - {PH_10, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R4 - {PH_9, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_R3 - - {PI_2, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G7 - {PI_1, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G6 - {PI_0, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G5 - {PH_15, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G4 - {PH_14, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G3 - {PH_13, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_G2 - - {PI_7, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B7 - {PI_6, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B6 - {PI_5, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B5 - {PI_4, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B4 - {PG_11, LTDC, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF14_LTDC)}, // LCD_B3 - {NC, NP, 0} -}; - -const PinMap PinMap_SDRAM[] = { - {PC_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNWE - {PC_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNE0 - {PC_3, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDCKE0 - {PE_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_NBL0 - {PE_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_NBL1 - {PF_11, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNRAS - {PG_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDCLK - {PG_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_SDNCAS - {PG_4, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_BA0 - {PG_5, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_BA1 - {PD_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D0 - {PD_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D1 - {PD_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D2 - {PD_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D3 - {PE_7, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D4 - {PE_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D5 - {PE_9, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D6 - {PE_10, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D7 - {PE_11, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D8 - {PE_12, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D9 - {PE_13, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D10 - {PE_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D11 - {PE_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D12 - {PD_8, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D13 - {PD_9, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D14 - {PD_10, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_D15 - {PF_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A0 - {PF_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A1 - {PF_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A2 - {PF_3, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A3 - {PF_4, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A4 - {PF_5, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A5 - {PF_12, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A6 - {PF_13, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A7 - {PF_14, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A8 - {PF_15, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A9 - {PG_0, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A10 - {PG_1, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A11 - {PG_2, FMC_Bank1_R, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF12_FMC)}, // FMC_A12 - {NC, NP, 0} -}; - -const PinMap PinMap_QUADSPI[] = { - {PB_2, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_CLK - {PB_10, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_NCS - {PF_6, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO3 - {PF_7, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF9_QUADSPI)}, // QUADSPI_BK1_IO2 - {PF_8, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO0 - {PF_9, QUADSPI, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_QUADSPI)}, // QUADSPI_BK1_IO1 - {NC, NP, 0} -}; diff --git a/src/HAL/STM32/tft/tft_spi.cpp b/src/HAL/STM32/tft/tft_spi.cpp deleted file mode 100644 index 2e18c8a..0000000 --- a/src/HAL/STM32/tft/tft_spi.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../platforms.h" - -#ifdef HAL_STM32 - -#include "../../../inc/MarlinConfig.h" - -#if HAS_SPI_TFT - -#include "tft_spi.h" -#include "pinconfig.h" - -SPI_HandleTypeDef TFT_SPI::SPIx; -DMA_HandleTypeDef TFT_SPI::DMAtx; - -void TFT_SPI::Init() { - SPI_TypeDef *spiInstance; - - OUT_WRITE(TFT_A0_PIN, HIGH); - OUT_WRITE(TFT_CS_PIN, HIGH); - - if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return; - if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return; - - #if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN - if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return; - #endif - - SPIx.Instance = spiInstance; - SPIx.State = HAL_SPI_STATE_RESET; - SPIx.Init.NSS = SPI_NSS_SOFT; - SPIx.Init.Mode = SPI_MODE_MASTER; - SPIx.Init.Direction = (TFT_MISO_PIN == TFT_MOSI_PIN) ? SPI_DIRECTION_1LINE : SPI_DIRECTION_2LINES; - SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; - SPIx.Init.CLKPhase = SPI_PHASE_1EDGE; - SPIx.Init.CLKPolarity = SPI_POLARITY_LOW; - SPIx.Init.DataSize = SPI_DATASIZE_8BIT; - SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPIx.Init.TIMode = SPI_TIMODE_DISABLE; - SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPIx.Init.CRCPolynomial = 10; - - pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK); - pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI); - #if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN - pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO); - #endif - pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN); - - #ifdef SPI1_BASE - if (SPIx.Instance == SPI1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - #ifdef STM32F1xx - __HAL_RCC_DMA1_CLK_ENABLE(); - DMAtx.Instance = DMA1_Channel3; - #elif defined(STM32F4xx) - __HAL_RCC_DMA2_CLK_ENABLE(); - DMAtx.Instance = DMA2_Stream3; - DMAtx.Init.Channel = DMA_CHANNEL_3; - #endif - SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; - } - #endif - #ifdef SPI2_BASE - if (SPIx.Instance == SPI2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - #ifdef STM32F1xx - __HAL_RCC_DMA1_CLK_ENABLE(); - DMAtx.Instance = DMA1_Channel5; - #elif defined(STM32F4xx) - __HAL_RCC_DMA1_CLK_ENABLE(); - DMAtx.Instance = DMA1_Stream4; - DMAtx.Init.Channel = DMA_CHANNEL_0; - #endif - } - #endif - #ifdef SPI3_BASE - if (SPIx.Instance == SPI3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - #ifdef STM32F1xx - __HAL_RCC_DMA2_CLK_ENABLE(); - DMAtx.Instance = DMA2_Channel2; - #elif defined(STM32F4xx) - __HAL_RCC_DMA1_CLK_ENABLE(); - DMAtx.Instance = DMA1_Stream5; - DMAtx.Init.Channel = DMA_CHANNEL_0; - #endif - } - #endif - - HAL_SPI_Init(&SPIx); - - DMAtx.Init.Direction = DMA_MEMORY_TO_PERIPH; - DMAtx.Init.PeriphInc = DMA_PINC_DISABLE; - DMAtx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; - DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - DMAtx.Init.Mode = DMA_NORMAL; - DMAtx.Init.Priority = DMA_PRIORITY_LOW; - #ifdef STM32F4xx - DMAtx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - #endif -} - -void TFT_SPI::DataTransferBegin(uint16_t DataSize) { - SPIx.Init.DataSize = DataSize == DATASIZE_8BIT ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT; - HAL_SPI_Init(&SPIx); - WRITE(TFT_CS_PIN, LOW); -} - -#ifdef TFT_DEFAULT_DRIVER - #include "../../../lcd/tft_io/tft_ids.h" -#endif - -uint32_t TFT_SPI::GetID() { - uint32_t id; - id = ReadID(LCD_READ_ID); - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) { - id = ReadID(LCD_READ_ID4); - #ifdef TFT_DEFAULT_DRIVER - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) - id = TFT_DEFAULT_DRIVER; - #endif - } - return id; -} - -uint32_t TFT_SPI::ReadID(uint16_t Reg) { - uint32_t Data = 0; - #if PIN_EXISTS(TFT_MISO) - uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler; - uint32_t i; - - SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4; - DataTransferBegin(DATASIZE_8BIT); - WriteReg(Reg); - - if (SPIx.Init.Direction == SPI_DIRECTION_1LINE) SPI_1LINE_RX(&SPIx); - __HAL_SPI_ENABLE(&SPIx); - - for (i = 0; i < 4; i++) { - #if TFT_MISO_PIN != TFT_MOSI_PIN - //if (hspi->Init.Direction == SPI_DIRECTION_2LINES) { - while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {} - SPIx.Instance->DR = 0; - //} - #endif - while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_RXNE)) {} - Data = (Data << 8) | SPIx.Instance->DR; - } - - __HAL_SPI_DISABLE(&SPIx); - DataTransferEnd(); - - SPIx.Init.BaudRatePrescaler = BaudRatePrescaler; - #endif - - return Data >> 7; -} - -bool TFT_SPI::isBusy() { - #if defined(STM32F1xx) - volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET; - #elif defined(STM32F4xx) - volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN; - #endif - if (dmaEnabled) { - if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0) - Abort(); - } - else - Abort(); - return dmaEnabled; -} - -void TFT_SPI::Abort() { - // Wait for any running spi - while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {} - while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {} - // First, abort any running dma - HAL_DMA_Abort(&DMAtx); - // DeInit objects - HAL_DMA_DeInit(&DMAtx); - HAL_SPI_DeInit(&SPIx); - // Deselect CS - DataTransferEnd(); -} - -void TFT_SPI::Transmit(uint16_t Data) { - if (TFT_MISO_PIN == TFT_MOSI_PIN) - SPI_1LINE_TX(&SPIx); - - __HAL_SPI_ENABLE(&SPIx); - - SPIx.Instance->DR = Data; - - while (!__HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_TXE)) {} - while ( __HAL_SPI_GET_FLAG(&SPIx, SPI_FLAG_BSY)) {} - - if (TFT_MISO_PIN != TFT_MOSI_PIN) - __HAL_SPI_CLEAR_OVRFLAG(&SPIx); // Clear overrun flag in 2 Lines communication mode because received is not read -} - -void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - // Wait last dma finish, to start another - while (isBusy()) { /* nada */ } - - DMAtx.Init.MemInc = MemoryIncrease; - HAL_DMA_Init(&DMAtx); - - if (TFT_MISO_PIN == TFT_MOSI_PIN) - SPI_1LINE_TX(&SPIx); - - DataTransferBegin(); - - HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count); - __HAL_SPI_ENABLE(&SPIx); - - SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request - - HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY); - Abort(); -} - -#if ENABLED(USE_SPI_DMA_TC) - - void TFT_SPI::TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - - DMAtx.Init.MemInc = MemoryIncrease; - HAL_DMA_Init(&DMAtx); - - if (TFT_MISO_PIN == TFT_MOSI_PIN) - SPI_1LINE_TX(&SPIx); - - DataTransferBegin(); - - HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); - HAL_DMA_Start_IT(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count); - __HAL_SPI_ENABLE(&SPIx); - - SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); // Enable Tx DMA Request - } - - extern "C" void DMA2_Stream3_IRQHandler(void) { HAL_DMA_IRQHandler(&TFT_SPI::DMAtx); } - -#endif - -#endif // HAS_SPI_TFT -#endif // HAL_STM32 diff --git a/src/HAL/STM32/tft/tft_spi.h b/src/HAL/STM32/tft/tft_spi.h deleted file mode 100644 index de051e2..0000000 --- a/src/HAL/STM32/tft/tft_spi.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef STM32F1xx - #include "stm32f1xx_hal.h" -#elif defined(STM32F4xx) - #include "stm32f4xx_hal.h" -#else - #error SPI TFT is currently only supported on STM32F1 and STM32F4 hardware. -#endif - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#define DATASIZE_8BIT SPI_DATASIZE_8BIT -#define DATASIZE_16BIT SPI_DATASIZE_16BIT -#define TFT_IO_DRIVER TFT_SPI - -class TFT_SPI { -private: - static SPI_HandleTypeDef SPIx; - - - static uint32_t ReadID(uint16_t Reg); - static void Transmit(uint16_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - #if ENABLED(USE_SPI_DMA_TC) - static void TransmitDMA_IT(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - #endif - -public: - static DMA_HandleTypeDef DMAtx; - - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort(); - - static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT); - static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); }; - static void DataTransferAbort(); - - static void WriteData(uint16_t Data) { Transmit(Data); } - static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } - - #if ENABLED(USE_SPI_DMA_TC) - static void WriteSequenceIT(uint16_t *Data, uint16_t Count) { TransmitDMA_IT(DMA_MINC_ENABLE, Data, Count); } - #endif - - static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - while (Count > 0) { - TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); - Count = Count > 0xFFFF ? Count - 0xFFFF : 0; - } - } -}; diff --git a/src/HAL/STM32/tft/xpt2046.cpp b/src/HAL/STM32/tft/xpt2046.cpp deleted file mode 100644 index cf4a8f1..0000000 --- a/src/HAL/STM32/tft/xpt2046.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../platforms.h" - -#ifdef HAL_STM32 - -#include "../../../inc/MarlinConfig.h" - -#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS - -#include "xpt2046.h" -#include "pinconfig.h" - -uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } - -SPI_HandleTypeDef XPT2046::SPIx; - -void XPT2046::Init() { - SPI_TypeDef *spiInstance; - - OUT_WRITE(TOUCH_CS_PIN, HIGH); - - #if PIN_EXISTS(TOUCH_INT) - // Optional Pendrive interrupt pin - SET_INPUT(TOUCH_INT_PIN); - #endif - - spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK); - if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI)) spiInstance = NP; - if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO)) spiInstance = NP; - - SPIx.Instance = spiInstance; - - if (SPIx.Instance) { - SPIx.State = HAL_SPI_STATE_RESET; - SPIx.Init.NSS = SPI_NSS_SOFT; - SPIx.Init.Mode = SPI_MODE_MASTER; - SPIx.Init.Direction = SPI_DIRECTION_2LINES; - SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; - SPIx.Init.CLKPhase = SPI_PHASE_2EDGE; - SPIx.Init.CLKPolarity = SPI_POLARITY_HIGH; - SPIx.Init.DataSize = SPI_DATASIZE_8BIT; - SPIx.Init.FirstBit = SPI_FIRSTBIT_MSB; - SPIx.Init.TIMode = SPI_TIMODE_DISABLE; - SPIx.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - SPIx.Init.CRCPolynomial = 10; - - pinmap_pinout(digitalPinToPinName(TOUCH_SCK_PIN), PinMap_SPI_SCLK); - pinmap_pinout(digitalPinToPinName(TOUCH_MOSI_PIN), PinMap_SPI_MOSI); - pinmap_pinout(digitalPinToPinName(TOUCH_MISO_PIN), PinMap_SPI_MISO); - - #ifdef SPI1_BASE - if (SPIx.Instance == SPI1) { - __HAL_RCC_SPI1_CLK_ENABLE(); - SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; - } - #endif - #ifdef SPI2_BASE - if (SPIx.Instance == SPI2) { - __HAL_RCC_SPI2_CLK_ENABLE(); - } - #endif - #ifdef SPI3_BASE - if (SPIx.Instance == SPI3) { - __HAL_RCC_SPI3_CLK_ENABLE(); - } - #endif - } - else { - SPIx.Instance = nullptr; - SET_INPUT(TOUCH_MISO_PIN); - SET_OUTPUT(TOUCH_MOSI_PIN); - SET_OUTPUT(TOUCH_SCK_PIN); - } - - getRawData(XPT2046_Z1); -} - -bool XPT2046::isTouched() { - return isBusy() ? false : ( - #if PIN_EXISTS(TOUCH_INT) - READ(TOUCH_INT_PIN) != HIGH - #else - getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD - #endif - ); -} - -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; - *x = getRawData(XPT2046_X); - *y = getRawData(XPT2046_Y); - return isTouched(); -} - -uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { - uint16_t data[3]; - - DataTransferBegin(); - - for (uint16_t i = 0; i < 3 ; i++) { - IO(coordinate); - data[i] = (IO() << 4) | (IO() >> 4); - } - - DataTransferEnd(); - - uint16_t delta01 = delta(data[0], data[1]); - uint16_t delta02 = delta(data[0], data[2]); - uint16_t delta12 = delta(data[1], data[2]); - - if (delta01 > delta02 || delta01 > delta12) { - if (delta02 > delta12) - data[0] = data[2]; - else - data[1] = data[2]; - } - - return (data[0] + data[1]) >> 1; -} - -uint16_t XPT2046::HardwareIO(uint16_t data) { - __HAL_SPI_ENABLE(&SPIx); - while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {} - SPIx.Instance->DR = data; - while ((SPIx.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {} - __HAL_SPI_DISABLE(&SPIx); - - return SPIx.Instance->DR; -} - -uint16_t XPT2046::SoftwareIO(uint16_t data) { - uint16_t result = 0; - - for (uint8_t j = 0x80; j > 0; j >>= 1) { - WRITE(TOUCH_SCK_PIN, LOW); - __DSB(); - WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); - __DSB(); - if (READ(TOUCH_MISO_PIN)) result |= j; - __DSB(); - WRITE(TOUCH_SCK_PIN, HIGH); - __DSB(); - } - WRITE(TOUCH_SCK_PIN, LOW); - __DSB(); - - return result; -} - -#endif // HAS_TFT_XPT2046 -#endif // HAL_STM32 diff --git a/src/HAL/STM32/tft/xpt2046.h b/src/HAL/STM32/tft/xpt2046.h deleted file mode 100644 index 71de6b0..0000000 --- a/src/HAL/STM32/tft/xpt2046.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef STM32F1xx - #include -#elif defined(STM32F4xx) - #include -#endif - -#include "../../../inc/MarlinConfig.h" - -// Not using regular SPI interface by default to avoid SPI mode conflicts with other SPI devices - -#if !PIN_EXISTS(TOUCH_MISO) - #error "TOUCH_MISO_PIN is not defined." -#elif !PIN_EXISTS(TOUCH_MOSI) - #error "TOUCH_MOSI_PIN is not defined." -#elif !PIN_EXISTS(TOUCH_SCK) - #error "TOUCH_SCK_PIN is not defined." -#elif !PIN_EXISTS(TOUCH_CS) - #error "TOUCH_CS_PIN is not defined." -#endif - -#ifndef TOUCH_INT_PIN - #define TOUCH_INT_PIN -1 -#endif - -#define XPT2046_DFR_MODE 0x00 -#define XPT2046_SER_MODE 0x04 -#define XPT2046_CONTROL 0x80 - -enum XPTCoordinate : uint8_t { - XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, -}; - -#ifndef XPT2046_Z1_THRESHOLD - #define XPT2046_Z1_THRESHOLD 10 -#endif - -class XPT2046 { -private: - static SPI_HandleTypeDef SPIx; - - static bool isBusy() { return false; } - - static uint16_t getRawData(const XPTCoordinate coordinate); - static bool isTouched(); - - static void DataTransferBegin() { if (SPIx.Instance) { HAL_SPI_Init(&SPIx); } WRITE(TOUCH_CS_PIN, LOW); }; - static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; - static uint16_t HardwareIO(uint16_t data); - static uint16_t SoftwareIO(uint16_t data); - static uint16_t IO(uint16_t data = 0) { return SPIx.Instance ? HardwareIO(data) : SoftwareIO(data); } - -public: - static void Init(); - static bool getRawPoint(int16_t *x, int16_t *y); -}; diff --git a/src/HAL/STM32/timers.cpp b/src/HAL/STM32/timers.cpp deleted file mode 100644 index e68b59c..0000000 --- a/src/HAL/STM32/timers.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -// ------------------------ -// Local defines -// ------------------------ - -// Default timer priorities. Override by specifying alternate priorities in the board pins file. -// The TONE timer is not present here, as it currently cannot be set programmatically. It is set -// by defining TIM_IRQ_PRIO in the variant.h or platformio.ini file, which adjusts the default -// priority for STM32 HardwareTimer objects. -#define SWSERIAL_TIMER_IRQ_PRIO_DEFAULT 1 // Requires tight bit timing to communicate reliably with TMC drivers -#define SERVO_TIMER_IRQ_PRIO_DEFAULT 1 // Requires tight PWM timing to control a BLTouch reliably -#define STEP_TIMER_IRQ_PRIO_DEFAULT 2 -#define TEMP_TIMER_IRQ_PRIO_DEFAULT 14 // Low priority avoids interference with other hardware and timers - -#ifndef STEP_TIMER_IRQ_PRIO - #define STEP_TIMER_IRQ_PRIO STEP_TIMER_IRQ_PRIO_DEFAULT -#endif -#ifndef TEMP_TIMER_IRQ_PRIO - #define TEMP_TIMER_IRQ_PRIO TEMP_TIMER_IRQ_PRIO_DEFAULT -#endif -#if HAS_TMC_SW_SERIAL - #include - #ifndef SWSERIAL_TIMER_IRQ_PRIO - #define SWSERIAL_TIMER_IRQ_PRIO SWSERIAL_TIMER_IRQ_PRIO_DEFAULT - #endif -#endif -#if HAS_SERVOS - #include "Servo.h" - #ifndef SERVO_TIMER_IRQ_PRIO - #define SERVO_TIMER_IRQ_PRIO SERVO_TIMER_IRQ_PRIO_DEFAULT - #endif -#endif -#if ENABLED(SPEAKER) - // Ensure the default timer priority is somewhere between the STEP and TEMP priorities. - // The STM32 framework defaults to interrupt 14 for all timers. This should be increased so that - // timing-sensitive operations such as speaker output are not impacted by the long-running - // temperature ISR. This must be defined in the platformio.ini file or the board's variant.h, - // so that it will be consumed by framework code. - #if !(TIM_IRQ_PRIO > STEP_TIMER_IRQ_PRIO && TIM_IRQ_PRIO < TEMP_TIMER_IRQ_PRIO) - #error "Default timer interrupt priority is unspecified or set to a value which may degrade performance." - #endif -#endif - -#if defined(STM32F0xx) || defined(STM32G0xx) - #define MCU_STEP_TIMER 16 - #define MCU_TEMP_TIMER 17 -#elif defined(STM32F1xx) - #define MCU_STEP_TIMER 4 - #define MCU_TEMP_TIMER 2 -#elif defined(STM32F401xC) || defined(STM32F401xE) - #define MCU_STEP_TIMER 9 // STM32F401 has no TIM6, TIM7, or TIM8 - #define MCU_TEMP_TIMER 10 -#elif defined(STM32F4xx) || defined(STM32F7xx) || defined(STM32H7xx) - #define MCU_STEP_TIMER 6 - #define MCU_TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used. -#endif - -#ifndef HAL_TIMER_RATE - #define HAL_TIMER_RATE GetStepperTimerClkFreq() -#endif - -#ifndef STEP_TIMER - #define STEP_TIMER MCU_STEP_TIMER -#endif -#ifndef TEMP_TIMER - #define TEMP_TIMER MCU_TEMP_TIMER -#endif - -#define __TIMER_DEV(X) TIM##X -#define _TIMER_DEV(X) __TIMER_DEV(X) -#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER) -#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER) - -// -------------------------------------------------------------------------- -// Local defines -// -------------------------------------------------------------------------- - -#define NUM_HARDWARE_TIMERS 2 - -// -------------------------------------------------------------------------- -// Private Variables -// -------------------------------------------------------------------------- - -HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { nullptr }; - -// ------------------------ -// Public functions -// ------------------------ - -uint32_t GetStepperTimerClkFreq() { - // Timer input clocks vary between devices, and in some cases between timers on the same device. - // Retrieve at runtime to ensure device compatibility. Cache result to avoid repeated overhead. - static uint32_t clkfreq = timer_instance[MF_TIMER_STEP]->getTimerClkFreq(); - return clkfreq; -} - -// frequency is in Hertz -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - if (!HAL_timer_initialized(timer_num)) { - switch (timer_num) { - case MF_TIMER_STEP: // STEPPER TIMER - use a 32bit timer if possible - timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV); - /* Set the prescaler to the final desired value. - * This will change the effective ISR callback frequency but when - * HAL_timer_start(timer_num=0) is called in the core for the first time - * the real frequency isn't important as long as, after boot, the ISR - * gets called with the correct prescaler and count register. So here - * we set the prescaler to the correct, final value and ignore the frequency - * asked. We will call back the ISR in 1 second to start at full speed. - * - * The proper fix, however, would be a correct initialization OR a - * HAL_timer_change(const uint8_t timer_num, const uint32_t frequency) - * which changes the prescaler when an IRQ frequency change is needed - * (for example when steppers are turned on) - */ - - timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally - timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT); - break; - case MF_TIMER_TEMP: // TEMP TIMER - any available 16bit timer - timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV); - // The prescale factor is computed automatically for HERTZ_FORMAT - timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT); - break; - } - - // Disable preload. Leaving it default-enabled can cause the timer to stop if it happens - // to exit the ISR after the start time for the next interrupt has already passed. - timer_instance[timer_num]->setPreloadEnable(false); - - HAL_timer_enable_interrupt(timer_num); - - // Start the timer. - timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt() - - // This is fixed in Arduino_Core_STM32 1.8. - // These calls can be removed and replaced with - // timer_instance[timer_num]->setInterruptPriority - switch (timer_num) { - case MF_TIMER_STEP: - timer_instance[timer_num]->setInterruptPriority(STEP_TIMER_IRQ_PRIO, 0); - break; - case MF_TIMER_TEMP: - timer_instance[timer_num]->setInterruptPriority(TEMP_TIMER_IRQ_PRIO, 0); - break; - } - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - if (HAL_timer_initialized(timer_num) && !timer_instance[timer_num]->hasInterrupt()) { - switch (timer_num) { - case MF_TIMER_STEP: - timer_instance[timer_num]->attachInterrupt(Step_Handler); - break; - case MF_TIMER_TEMP: - timer_instance[timer_num]->attachInterrupt(Temp_Handler); - break; - } - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - if (HAL_timer_initialized(timer_num)) timer_instance[timer_num]->detachInterrupt(); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - return HAL_timer_initialized(timer_num) && timer_instance[timer_num]->hasInterrupt(); -} - -void SetTimerInterruptPriorities() { - TERN_(HAS_TMC_SW_SERIAL, SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0)); - TERN_(HAS_SERVOS, libServo::setInterruptPriority(SERVO_TIMER_IRQ_PRIO, 0)); -} - -// ------------------------ -// Detect timer conflicts -// ------------------------ - -// This list serves two purposes. Firstly, it facilitates build-time mapping between -// variant-defined timer names (such as TIM1) and timer numbers. It also replicates -// the order of timers used in the framework's SoftwareSerial.cpp. The first timer in -// this list will be automatically used by SoftwareSerial if it is not already defined -// in the board's variant or compiler options. -static constexpr struct {uintptr_t base_address; int timer_number;} stm32_timer_map[] = { - #ifdef TIM18_BASE - { uintptr_t(TIM18), 18 }, - #endif - #ifdef TIM7_BASE - { uintptr_t(TIM7), 7 }, - #endif - #ifdef TIM6_BASE - { uintptr_t(TIM6), 6 }, - #endif - #ifdef TIM22_BASE - { uintptr_t(TIM22), 22 }, - #endif - #ifdef TIM21_BASE - { uintptr_t(TIM21), 21 }, - #endif - #ifdef TIM17_BASE - { uintptr_t(TIM17), 17 }, - #endif - #ifdef TIM16_BASE - { uintptr_t(TIM16), 16 }, - #endif - #ifdef TIM15_BASE - { uintptr_t(TIM15), 15 }, - #endif - #ifdef TIM14_BASE - { uintptr_t(TIM14), 14 }, - #endif - #ifdef TIM13_BASE - { uintptr_t(TIM13), 13 }, - #endif - #ifdef TIM11_BASE - { uintptr_t(TIM11), 11 }, - #endif - #ifdef TIM10_BASE - { uintptr_t(TIM10), 10 }, - #endif - #ifdef TIM12_BASE - { uintptr_t(TIM12), 12 }, - #endif - #ifdef TIM19_BASE - { uintptr_t(TIM19), 19 }, - #endif - #ifdef TIM9_BASE - { uintptr_t(TIM9), 9 }, - #endif - #ifdef TIM5_BASE - { uintptr_t(TIM5), 5 }, - #endif - #ifdef TIM4_BASE - { uintptr_t(TIM4), 4 }, - #endif - #ifdef TIM3_BASE - { uintptr_t(TIM3), 3 }, - #endif - #ifdef TIM2_BASE - { uintptr_t(TIM2), 2 }, - #endif - #ifdef TIM20_BASE - { uintptr_t(TIM20), 20 }, - #endif - #ifdef TIM8_BASE - { uintptr_t(TIM8), 8 }, - #endif - #ifdef TIM1_BASE - { uintptr_t(TIM1), 1 } - #endif -}; - -// Convert from a timer base address to its integer timer number. -static constexpr int get_timer_num_from_base_address(uintptr_t base_address) { - for (const auto &timer : stm32_timer_map) - if (timer.base_address == base_address) return timer.timer_number; - return 0; -} - -// The platform's SoftwareSerial.cpp will use the first timer from stm32_timer_map. -#if HAS_TMC_SW_SERIAL && !defined(TIMER_SERIAL) - #define TIMER_SERIAL (stm32_timer_map[0].base_address) -#endif - -// constexpr doesn't like using the base address pointers that timers evaluate to. -// We can get away with casting them to uintptr_t, if we do so inside an array. -// GCC will not currently do it directly to a uintptr_t. -IF_ENABLED(HAS_TMC_SW_SERIAL, static constexpr uintptr_t timer_serial[] = {uintptr_t(TIMER_SERIAL)}); -IF_ENABLED(SPEAKER, static constexpr uintptr_t timer_tone[] = {uintptr_t(TIMER_TONE)}); -IF_ENABLED(HAS_SERVOS, static constexpr uintptr_t timer_servo[] = {uintptr_t(TIMER_SERVO)}); - -enum TimerPurpose { TP_SERIAL, TP_TONE, TP_SERVO, TP_STEP, TP_TEMP }; - -// List of timers, to enable checking for conflicts. -// Includes the purpose of each timer to ease debugging when evaluating at build-time. -// This cannot yet account for timers used for PWM output, such as for fans. -static constexpr struct { TimerPurpose p; int t; } timers_in_use[] = { - #if HAS_TMC_SW_SERIAL - { TP_SERIAL, get_timer_num_from_base_address(timer_serial[0]) }, // Set in variant.h, or as a define in platformio.h if not present in variant.h - #endif - #if ENABLED(SPEAKER) - { TP_TONE, get_timer_num_from_base_address(timer_tone[0]) }, // Set in variant.h, or as a define in platformio.h if not present in variant.h - #endif - #if HAS_SERVOS - { TP_SERVO, get_timer_num_from_base_address(timer_servo[0]) }, // Set in variant.h, or as a define in platformio.h if not present in variant.h - #endif - { TP_STEP, STEP_TIMER }, - { TP_TEMP, TEMP_TIMER }, -}; - -static constexpr bool verify_no_timer_conflicts() { - LOOP_L_N(i, COUNT(timers_in_use)) - LOOP_S_L_N(j, i + 1, COUNT(timers_in_use)) - if (timers_in_use[i].t == timers_in_use[j].t) return false; - return true; -} - -// If this assertion fails at compile time, review the timers_in_use array. -// If default_envs is defined properly in platformio.ini, VS Code can evaluate the array -// when hovering over it, making it easy to identify the conflicting timers. -static_assert(verify_no_timer_conflicts(), "One or more timer conflict detected. Examine \"timers_in_use\" to help identify conflict."); - -#endif // HAL_STM32 diff --git a/src/HAL/STM32/timers.h b/src/HAL/STM32/timers.h deleted file mode 100644 index 6828998..0000000 --- a/src/HAL/STM32/timers.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfig.h" - -// ------------------------ -// Defines -// ------------------------ - -// STM32 timers may be 16 or 32 bit. Limiting HAL_TIMER_TYPE_MAX to 16 bits -// avoids issues with STM32F0 MCUs, which seem to pause timers if UINT32_MAX -// is written to the register. STM32F4 timers do not manifest this issue, -// even when writing to 16 bit timers. -// -// The range of the timer can be queried at runtime using IS_TIM_32B_COUNTER_INSTANCE. -// This is a more expensive check than a simple compile-time constant, so its -// implementation is deferred until the desire for a 32-bit range outweighs the cost -// of adding a run-time check and HAL_TIMER_TYPE_MAX is refactored to allow unique -// values for each timer. -#define hal_timer_t uint32_t -#define HAL_TIMER_TYPE_MAX UINT16_MAX - -// Marlin timer_instance[] content (unrelated to timer selection) -#define MF_TIMER_STEP 0 // Timer Index for Stepper -#define MF_TIMER_TEMP 1 // Timer Index for Temperature -#define MF_TIMER_PULSE MF_TIMER_STEP - -#define TIMER_INDEX_(T) TIMER##T##_INDEX // TIMER#_INDEX enums (timer_index_t) depend on TIM#_BASE defines. -#define TIMER_INDEX(T) TIMER_INDEX_(T) // Convert Timer ID to HardwareTimer_Handle index. - -#define TEMP_TIMER_FREQUENCY 1000 // Temperature::isr() is expected to be called at around 1kHz - -// TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp -#define STEPPER_TIMER_RATE 2000000 // 2 Mhz -extern uint32_t GetStepperTimerClkFreq(); -#define STEPPER_TIMER_PRESCALE (GetStepperTimerClkFreq() / (STEPPER_TIMER_RATE)) -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -extern void Step_Handler(); -extern void Temp_Handler(); - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() void Step_Handler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() void Temp_Handler() -#endif - -// ------------------------ -// Public Variables -// ------------------------ - -extern HardwareTimer *timer_instance[]; - -// ------------------------ -// Public functions -// ------------------------ - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -// Configure timer priorities for peripherals such as Software Serial or Servos. -// Exposed here to allow all timer priority information to reside in timers.cpp -void SetTimerInterruptPriorities(); - -// FORCE_INLINE because these are used in performance-critical situations -FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) { - return timer_instance[timer_num] != nullptr; -} -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - return HAL_timer_initialized(timer_num) ? timer_instance[timer_num]->getCount() : 0; -} - -// NOTE: Method name may be misleading. -// STM32 has an Auto-Reload Register (ARR) as opposed to a "compare" register -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t overflow) { - if (HAL_timer_initialized(timer_num)) { - timer_instance[timer_num]->setOverflow(overflow + 1, TICK_FORMAT); // Value decremented by setOverflow() - // wiki: "force all registers (Autoreload, prescaler, compare) to be taken into account" - // So, if the new overflow value is less than the count it will trigger a rollover interrupt. - if (overflow < timer_instance[timer_num]->getCount()) // Added 'if' here because reports say it won't boot without it - timer_instance[timer_num]->refresh(); - } -} - -#define HAL_timer_isr_prologue(T) NOOP -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/STM32/usb_host.cpp b/src/HAL/STM32/usb_host.cpp deleted file mode 100644 index d77f0b2..0000000 --- a/src/HAL/STM32/usb_host.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfig.h" - -#if BOTH(USE_OTG_USB_HOST, USBHOST) - -#include "usb_host.h" -#include "../shared/Marduino.h" -#include "usbh_core.h" -#include "usbh_msc.h" - -USBH_HandleTypeDef hUsbHost; -USBHost usb; -BulkStorage bulk(&usb); - -static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id) { - switch(id) { - case HOST_USER_SELECT_CONFIGURATION: - //SERIAL_ECHOLNPGM("APPLICATION_SELECT_CONFIGURATION"); - break; - case HOST_USER_DISCONNECTION: - //SERIAL_ECHOLNPGM("APPLICATION_DISCONNECT"); - //usb.setUsbTaskState(USB_STATE_RUNNING); - break; - case HOST_USER_CLASS_ACTIVE: - //SERIAL_ECHOLNPGM("APPLICATION_READY"); - usb.setUsbTaskState(USB_STATE_RUNNING); - break; - case HOST_USER_CONNECTION: - break; - default: - break; - } -} - -bool USBHost::start() { - if (USBH_Init(&hUsbHost, USBH_UserProcess, TERN(USE_USB_HS_IN_FS, HOST_HS, HOST_FS)) != USBH_OK) { - SERIAL_ECHOLNPGM("Error: USBH_Init"); - return false; - } - if (USBH_RegisterClass(&hUsbHost, USBH_MSC_CLASS) != USBH_OK) { - SERIAL_ECHOLNPGM("Error: USBH_RegisterClass"); - return false; - } - if (USBH_Start(&hUsbHost) != USBH_OK) { - SERIAL_ECHOLNPGM("Error: USBH_Start"); - return false; - } - return true; -} - -void USBHost::Task() { - USBH_Process(&hUsbHost); -} - -uint8_t USBHost::getUsbTaskState() { - return usb_task_state; -} - -void USBHost::setUsbTaskState(uint8_t state) { - usb_task_state = state; - if (usb_task_state == USB_STATE_RUNNING) { - MSC_LUNTypeDef info; - USBH_MSC_GetLUNInfo(&hUsbHost, usb.lun, &info); - capacity = info.capacity.block_nbr / 2000; - block_size = info.capacity.block_size; - block_count = info.capacity.block_nbr; - //SERIAL_ECHOLNPGM("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr); - //SERIAL_ECHOLNPGM("info.capacity.block_size: %d\n", info.capacity.block_size); - //SERIAL_ECHOLNPGM("capacity : %d MB\n", capacity); - } -}; - -bool BulkStorage::LUNIsGood(uint8_t t) { - return USBH_MSC_IsReady(&hUsbHost) && USBH_MSC_UnitIsReady(&hUsbHost, t); -} - -uint32_t BulkStorage::GetCapacity(uint8_t lun) { - return usb->block_count; -} - -uint16_t BulkStorage::GetSectorSize(uint8_t lun) { - return usb->block_size; -} - -uint8_t BulkStorage::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) { - return USBH_MSC_Read(&hUsbHost, lun, addr, buf, blocks) != USBH_OK; -} - -uint8_t BulkStorage::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf) { - return USBH_MSC_Write(&hUsbHost, lun, addr, const_cast(buf), blocks) != USBH_OK; -} - -#endif // USE_OTG_USB_HOST && USBHOST -#endif // HAL_STM32 diff --git a/src/HAL/STM32/usb_host.h b/src/HAL/STM32/usb_host.h deleted file mode 100644 index c0001c0..0000000 --- a/src/HAL/STM32/usb_host.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -typedef enum { - USB_STATE_INIT, - USB_STATE_ERROR, - USB_STATE_RUNNING, -} usb_state_t; - -class USBHost { -public: - bool start(); - void Task(); - uint8_t getUsbTaskState(); - void setUsbTaskState(uint8_t state); - uint8_t regRd(uint8_t reg) { return 0x0; }; - uint8_t usb_task_state = USB_STATE_INIT; - uint8_t lun = 0; - uint32_t capacity = 0; - uint16_t block_size = 0; - uint32_t block_count = 0; -}; - -class BulkStorage { -public: - BulkStorage(USBHost *usb) : usb(usb) {}; - - bool LUNIsGood(uint8_t t); - uint32_t GetCapacity(uint8_t lun); - uint16_t GetSectorSize(uint8_t lun); - uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf); - uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t * buf); - - USBHost *usb; -}; - -extern USBHost usb; -extern BulkStorage bulk; diff --git a/src/HAL/STM32/usb_serial.cpp b/src/HAL/STM32/usb_serial.cpp deleted file mode 100644 index 0b2372f..0000000 --- a/src/HAL/STM32/usb_serial.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../platforms.h" - -#ifdef HAL_STM32 - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) && (USBD_USE_CDC || USBD_USE_CDC_MSC) - -#include "usb_serial.h" -#include "../../feature/e_parser.h" - -EmergencyParser::State emergency_state = EmergencyParser::State::EP_RESET; - -int8_t (*USBD_CDC_Receive_original) (uint8_t *Buf, uint32_t *Len) = nullptr; - -static int8_t USBD_CDC_Receive_hook(uint8_t *Buf, uint32_t *Len) { - for (uint32_t i = 0; i < *Len; i++) - emergency_parser.update(emergency_state, Buf[i]); - return USBD_CDC_Receive_original(Buf, Len); -} - -typedef struct _USBD_CDC_Itf { - int8_t (* Init)(void); - int8_t (* DeInit)(void); - int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); - int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); - int8_t (* Transferred)(void); -} USBD_CDC_ItfTypeDef; - -extern USBD_CDC_ItfTypeDef USBD_CDC_fops; - -void USB_Hook_init() { - USBD_CDC_Receive_original = USBD_CDC_fops.Receive; - USBD_CDC_fops.Receive = USBD_CDC_Receive_hook; -} - -#endif // EMERGENCY_PARSER && USBD_USE_CDC -#endif // HAL_STM32 diff --git a/src/HAL/STM32/usb_serial.h b/src/HAL/STM32/usb_serial.h deleted file mode 100644 index 3edb6fd..0000000 --- a/src/HAL/STM32/usb_serial.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void USB_Hook_init(); diff --git a/src/HAL/STM32F1/HAL.cpp b/src/HAL/STM32F1/HAL.cpp deleted file mode 100644 index 4d31400..0000000 --- a/src/HAL/STM32F1/HAL.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include - -// ------------------------ -// Types -// ------------------------ - -#define __I -#define __IO volatile - typedef struct { - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ - } SCB_Type; - -// ------------------------ -// Local defines -// ------------------------ - -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ - -#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -// ------------------------ -// Serial ports -// ------------------------ - -#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE - - USBSerial SerialUSB; - DefaultSerial1 MSerial0(true, SerialUSB); - - #if ENABLED(EMERGENCY_PARSER) - #include "../libmaple/usb/stm32f1/usb_reg_map.h" - #include "libmaple/usb_cdcacm.h" - // The original callback is not called (no way to retrieve address). - // That callback detects a special STM32 reset sequence: this functionality is not essential - // as M997 achieves the same. - void my_rx_callback(unsigned int, void*) { - // max length of 16 is enough to contain all emergency commands - uint8 buf[16]; - - //rx is usbSerialPart.endpoints[2] - uint16 len = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP); - uint32 total = usb_cdcacm_data_available(); - - if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf))) - return; - - // cannot get character by character due to bug in composite_cdcacm_peek_ex - len = usb_cdcacm_peek(buf, total); - - for (uint32 i = 0; i < len; i++) - emergency_parser.update(MSerial0.emergency_state, buf[i + total - len]); - } - #endif -#endif - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #include - - void watchdogSetup() { - // do whatever. don't remove this function. - } - - /** - * The watchdog clock is 40Khz. So for a 4s or 8s interval use a /256 preescaler and 625 or 1250 reload value (counts down to 0). - */ - #define STM32F1_WD_RELOAD TERN(WATCHDOG_DURATION_8S, 1250, 625) // 4 or 8 second timeout - - /** - * @brief Initialize the independent hardware watchdog. - * - * @return No return - * - * @details The watchdog clock is 40Khz. So for a 4s or 8s interval use a /256 preescaler and 625 or 1250 reload value (counts down to 0). - */ - void MarlinHAL::watchdog_init() { - #if DISABLED(DISABLE_WATCHDOG_INIT) - iwdg_init(IWDG_PRE_256, STM32F1_WD_RELOAD); - #endif - } - - // Reset watchdog. MUST be called every 4 or 8 seconds after the - // first watchdog_init or the STM32F1 will reset. - void MarlinHAL::watchdog_refresh() { - #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) - TOGGLE(LED_PIN); // heartbeat indicator - #endif - iwdg_feed(); - } - -#endif // USE_WATCHDOG - -// ------------------------ -// ADC -// ------------------------ - -// Watch out for recursion here! Our pin_t is signed, so pass through to Arduino -> analogRead(uint8_t) - -uint16_t analogRead(const pin_t pin) { - const bool is_analog = _GET_MODE(pin) == GPIO_INPUT_ANALOG; - return is_analog ? analogRead(uint8_t(pin)) : 0; -} - -// Wrapper to maple unprotected analogWrite -void analogWrite(const pin_t pin, int pwm_val8) { - if (PWM_PIN(pin)) analogWrite(uint8_t(pin), pwm_val8); -} - -uint16_t MarlinHAL::adc_result; - -// ------------------------ -// Private functions -// ------------------------ - -static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); // only values 0..7 are used - - reg_value = SCB->AIRCR; // read old register configuration - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); // clear bits to change - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); // Insert write key & priority group - SCB->AIRCR = reg_value; -} - -// ------------------------ -// Public functions -// ------------------------ - -void flashFirmware(const int16_t) { hal.reboot(); } - -// -// Leave PA11/PA12 intact if USBSerial is not used -// -#if SERIAL_USB - namespace wirish { namespace priv { - #if SERIAL_PORT > 0 - #if SERIAL_PORT2 - #if SERIAL_PORT2 > 0 - void board_setup_usb() {} - #endif - #else - void board_setup_usb() {} - #endif - #endif - } } -#endif - -TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial()); - -// ------------------------ -// MarlinHAL class -// ------------------------ - -void MarlinHAL::init() { - NVIC_SetPriorityGrouping(0x3); - #if PIN_EXISTS(LED) - OUT_WRITE(LED_PIN, LOW); - #endif - #if HAS_SD_HOST_DRIVE - MSC_SD_init(); - #elif BOTH(SERIAL_USB, EMERGENCY_PARSER) - usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, my_rx_callback); - #endif - #if PIN_EXISTS(USB_CONNECT) - OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection - delay(1000); // Give OS time to notice - WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING); - #endif - TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler -} - -// HAL idle task -void MarlinHAL::idletask() { - #if HAS_SHARED_MEDIA - // If Marlin is using the SD card we need to lock it to prevent access from - // a PC via USB. - // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but - // this will not reliably detect delete operations. To be safe we will lock - // the disk if Marlin has it mounted. Unfortunately there is currently no way - // to unmount the disk from the LCD menu. - // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) - /* copy from lpc1768 framework, should be fixed later for process HAS_SD_HOST_DRIVE*/ - // process USB mass storage device class loop - MarlinMSC.loop(); - #endif -} - -void MarlinHAL::reboot() { nvic_sys_reset(); } - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -extern "C" { - extern unsigned int _ebss; // end of bss section -} - -/** - * TODO: Change this to correct it for libmaple - */ - -// return free memory between end of heap (or end bss) and whatever is current - -/* -#include -//extern caddr_t _sbrk(int incr); -#ifndef CONFIG_HEAP_END -extern char _lm_heap_end; -#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) -#endif - -extern "C" { - static int freeMemory() { - char top = 't'; - return &top - reinterpret_cast(sbrk(0)); - } - int freeMemory() { - int free_memory; - int heap_end = (int)_sbrk(0); - free_memory = ((int)&free_memory) - ((int)heap_end); - return free_memory; - } -} -*/ - -// ------------------------ -// ADC -// ------------------------ - -enum ADCIndex : uint8_t { - OPTITEM(HAS_TEMP_ADC_0, TEMP_0) - OPTITEM(HAS_TEMP_ADC_1, TEMP_1) - OPTITEM(HAS_TEMP_ADC_2, TEMP_2) - OPTITEM(HAS_TEMP_ADC_3, TEMP_3) - OPTITEM(HAS_TEMP_ADC_4, TEMP_4) - OPTITEM(HAS_TEMP_ADC_5, TEMP_5) - OPTITEM(HAS_TEMP_ADC_6, TEMP_6) - OPTITEM(HAS_TEMP_ADC_7, TEMP_7) - OPTITEM(HAS_HEATED_BED, TEMP_BED) - OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER) - OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE) - OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER) - OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD) - OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH) - OPTITEM(HAS_ADC_BUTTONS, ADC_KEY) - OPTITEM(HAS_JOY_ADC_X, JOY_X) - OPTITEM(HAS_JOY_ADC_Y, JOY_Y) - OPTITEM(HAS_JOY_ADC_Z, JOY_Z) - OPTITEM(POWER_MONITOR_CURRENT, POWERMON_CURRENT) - OPTITEM(POWER_MONITOR_VOLTAGE, POWERMON_VOLTS) - ADC_COUNT -}; - -static uint16_t adc_results[ADC_COUNT]; - -// Init the AD in continuous capture mode -void MarlinHAL::adc_init() { - static const uint8_t adc_pins[] = { - OPTITEM(HAS_TEMP_ADC_0, TEMP_0_PIN) - OPTITEM(HAS_TEMP_ADC_1, TEMP_1_PIN) - OPTITEM(HAS_TEMP_ADC_2, TEMP_2_PIN) - OPTITEM(HAS_TEMP_ADC_3, TEMP_3_PIN) - OPTITEM(HAS_TEMP_ADC_4, TEMP_4_PIN) - OPTITEM(HAS_TEMP_ADC_5, TEMP_5_PIN) - OPTITEM(HAS_TEMP_ADC_6, TEMP_6_PIN) - OPTITEM(HAS_TEMP_ADC_7, TEMP_7_PIN) - OPTITEM(HAS_HEATED_BED, TEMP_BED_PIN) - OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN) - OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN) - OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER_PIN) - OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD_PIN) - OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN) - OPTITEM(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN) - OPTITEM(HAS_JOY_ADC_X, JOY_X_PIN) - OPTITEM(HAS_JOY_ADC_Y, JOY_Y_PIN) - OPTITEM(HAS_JOY_ADC_Z, JOY_Z_PIN) - OPTITEM(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN) - OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN) - }; - static STM32ADC adc(ADC1); - // configure the ADC - adc.calibrate(); - adc.setSampleRate((F_CPU > 72000000) ? ADC_SMPR_71_5 : ADC_SMPR_41_5); // 71.5 or 41.5 ADC cycles - adc.setPins((uint8_t *)adc_pins, ADC_COUNT); - adc.setDMA(adc_results, uint16_t(ADC_COUNT), uint32_t(DMA_MINC_MODE | DMA_CIRC_MODE), nullptr); - adc.setScanMode(); - adc.setContinuous(); - adc.startConversion(); -} - -void MarlinHAL::adc_start(const pin_t pin) { - #define __TCASE(N,I) case N: pin_index = I; break; - #define _TCASE(C,N,I) TERN_(C, __TCASE(N, I)) - ADCIndex pin_index; - switch (pin) { - default: return; - _TCASE(HAS_TEMP_ADC_0, TEMP_0_PIN, TEMP_0) - _TCASE(HAS_TEMP_ADC_1, TEMP_1_PIN, TEMP_1) - _TCASE(HAS_TEMP_ADC_2, TEMP_2_PIN, TEMP_2) - _TCASE(HAS_TEMP_ADC_3, TEMP_3_PIN, TEMP_3) - _TCASE(HAS_TEMP_ADC_4, TEMP_4_PIN, TEMP_4) - _TCASE(HAS_TEMP_ADC_5, TEMP_5_PIN, TEMP_5) - _TCASE(HAS_TEMP_ADC_6, TEMP_6_PIN, TEMP_6) - _TCASE(HAS_TEMP_ADC_7, TEMP_7_PIN, TEMP_7) - _TCASE(HAS_HEATED_BED, TEMP_BED_PIN, TEMP_BED) - _TCASE(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN, TEMP_CHAMBER) - _TCASE(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN, TEMP_PROBE) - _TCASE(HAS_TEMP_COOLER, TEMP_COOLER_PIN, TEMP_COOLER) - _TCASE(HAS_TEMP_BOARD, TEMP_BOARD_PIN, TEMP_BOARD) - _TCASE(HAS_JOY_ADC_X, JOY_X_PIN, JOY_X) - _TCASE(HAS_JOY_ADC_Y, JOY_Y_PIN, JOY_Y) - _TCASE(HAS_JOY_ADC_Z, JOY_Z_PIN, JOY_Z) - _TCASE(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN, FILWIDTH) - _TCASE(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN, ADC_KEY) - _TCASE(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN, POWERMON_CURRENT) - _TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTS) - } - adc_result = (adc_results[(int)pin_index] & 0xFFF) >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits -} - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/HAL.h b/src/HAL/STM32F1/HAL.h deleted file mode 100644 index b14b5f7..0000000 --- a/src/HAL/STM32F1/HAL.h +++ /dev/null @@ -1,309 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - */ - -#define CPU_32_BIT - -#include "../../core/macros.h" -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" - -#include "fastio.h" - -#include -#include - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_SD_HOST_DRIVE - #include "msc_sd.h" -#endif - -#include "MarlinSerial.h" - -// ------------------------ -// Defines -// ------------------------ - -// -// Default graphical display delays -// -#define CPU_ST7920_DELAY_1 300 -#define CPU_ST7920_DELAY_2 40 -#define CPU_ST7920_DELAY_3 340 - -#ifndef STM32_FLASH_SIZE - #if ANY(MCU_STM32F103RE, MCU_STM32F103VE, MCU_STM32F103ZE) - #define STM32_FLASH_SIZE 512 - #else - #define STM32_FLASH_SIZE 256 - #endif -#endif - -// ------------------------ -// Serial ports -// ------------------------ - -#ifdef SERIAL_USB - typedef ForwardSerial1Class< USBSerial > DefaultSerial1; - extern DefaultSerial1 MSerial0; - #if HAS_SD_HOST_DRIVE - #define UsbSerial MarlinCompositeSerial - #else - #define UsbSerial MSerial0 - #endif -#endif - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) - #define NUM_UARTS 5 -#else - #define NUM_UARTS 3 -#endif - -#if SERIAL_PORT == -1 - #define MYSERIAL1 UsbSerial -#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #define MYSERIAL1 MSERIAL(1) // dummy port - static_assert(false, "SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") -#endif - -#ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == -1 - #define MYSERIAL2 UsbSerial - #elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #define MYSERIAL2 MSERIAL(1) // dummy port - static_assert(false, "SERIAL_PORT_2 must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") - #endif -#endif - -#ifdef SERIAL_PORT_3 - #if SERIAL_PORT_3 == -1 - #define MYSERIAL3 UsbSerial - #elif WITHIN(SERIAL_PORT_3, 1, NUM_UARTS) - #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) - #else - #define MYSERIAL3 MSERIAL(1) // dummy port - static_assert(false, "SERIAL_PORT_3 must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") - #endif -#endif - -#ifdef MMU2_SERIAL_PORT - #if MMU2_SERIAL_PORT == -1 - #define MMU2_SERIAL UsbSerial - #elif WITHIN(MMU2_SERIAL_PORT, 1, NUM_UARTS) - #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) - #else - #define MMU2_SERIAL MSERIAL(1) // dummy port - static_assert(false, "MMU2_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") - #endif -#endif - -#ifdef LCD_SERIAL_PORT - #if LCD_SERIAL_PORT == -1 - #define LCD_SERIAL UsbSerial - #elif WITHIN(LCD_SERIAL_PORT, 1, NUM_UARTS) - #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) - #else - #define LCD_SERIAL MSERIAL(1) // dummy port - static_assert(false, "LCD_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.") - #endif - #if HAS_DGUS_LCD - #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite() - #endif -#endif - -/** - * TODO: review this to return 1 for pins that are not analog input - */ -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) (p) -#endif - -#ifndef digitalPinHasPWM - #define digitalPinHasPWM(P) !!PIN_MAP[P].timer_device - #define NO_COMPILE_TIME_PWM -#endif - -// Reset Reason -#define RST_POWER_ON 1 -#define RST_EXTERNAL 2 -#define RST_BROWN_OUT 4 -#define RST_WATCHDOG 8 -#define RST_JTAG 16 -#define RST_SOFTWARE 32 -#define RST_BACKUP 64 - -// ------------------------ -// Types -// ------------------------ - -typedef int8_t pin_t; - -// ------------------------ -// Interrupts -// ------------------------ - -#define CRITICAL_SECTION_START() const bool irqon = !__get_primask(); (void)__iCliRetVal() -#define CRITICAL_SECTION_END() if (!irqon) (void)__iSeiRetVal() -#define cli() noInterrupts() -#define sei() interrupts() - -// ------------------------ -// ADC -// ------------------------ - -#ifdef ADC_RESOLUTION - #define HAL_ADC_RESOLUTION ADC_RESOLUTION -#else - #define HAL_ADC_RESOLUTION 12 -#endif - -#define HAL_ADC_VREF 3.3 - -uint16_t analogRead(const pin_t pin); // need hal.adc_enable() first -void analogWrite(const pin_t pin, int pwm_val8); // PWM only! mul by 257 in maple!? - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -#define JTAG_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY) -#define JTAGSWD_DISABLE() afio_cfg_debug_ports(AFIO_DEBUG_NONE) - -#define PLATFORM_M997_SUPPORT -void flashFirmware(const int16_t); - -#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment -#ifndef PWM_FREQUENCY - #define PWM_FREQUENCY 1000 // Default PWM Frequency -#endif - -// ------------------------ -// Class Utilities -// ------------------------ - -// Memory related -#define __bss_end __bss_end__ - -void _delay_ms(const int ms); - -extern "C" char* _sbrk(int incr); - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -static inline int freeMemory() { - volatile char top; - return &top - _sbrk(0); -} - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init(); // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_primask(); } - static void isr_on() { ((void)__iSeiRetVal()); } - static void isr_off() { ((void)__iCliRetVal()); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask(); - - // Reset - static uint8_t get_reset_source() { return RST_POWER_ON; } - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static uint16_t adc_result; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t pin) { pinMode(pin, INPUT_ANALOG); } - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value() { return adc_result; } - - /** - * Set the PWM duty cycle for the pin to the given value. - * Optionally invert the duty cycle [default = false] - * Optionally change the maximum size of the provided value to enable finer PWM duty control [default = 255] - * The timer must be pre-configured with set_pwm_frequency() if the default frequency is not desired. - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false); - - /** - * Set the frequency of the timer for the given pin. - * All Timer PWM pins run at the same frequency. - */ - static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); - -}; diff --git a/src/HAL/STM32F1/HAL_SPI.cpp b/src/HAL/STM32F1/HAL_SPI.cpp deleted file mode 100644 index abb348d..0000000 --- a/src/HAL/STM32F1/HAL_SPI.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Software SPI functions originally from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - * Adapted to the STM32F1 HAL - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" -#include - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(SOFTWARE_SPI) - - // ------------------------ - // Software SPI - // ------------------------ - #error "Software SPI not supported for STM32F1. Use hardware SPI." - -#else - -// ------------------------ -// Hardware SPI -// ------------------------ - -/** - * VGPV SPI speed start and F_CPU/2, by default 72/2 = 36Mhz - */ - -/** - * @brief Begin SPI port setup - * - * @return Nothing - * - * @details Only configures SS pin since libmaple creates and initialize the SPI object - */ -void spiBegin() { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif -} - -/** - * @brief Initialize SPI port to required speed rate and transfer mode (MSB, SPI MODE 0) - * - * @param spiRate Rate as declared in HAL.h (speed do not match AVR) - * @return Nothing - * - * @details - */ -void spiInit(uint8_t spiRate) { - /** - * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz - * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 - * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 - */ - #if SPI_DEVICE == 1 - #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 - #else - #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 - #endif - uint8_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break; - case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; - case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; - case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; - case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; - case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; - default: clock = SPI_CLOCK_DIV2; // Default from the SPI library - } - SPI.setModule(SPI_DEVICE); - SPI.begin(); - SPI.setClockDivider(clock); - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); -} - -/** - * @brief Receive a single byte from the SPI port. - * - * @return Byte received - * - * @details - */ -uint8_t spiRec() { - uint8_t returnByte = SPI.transfer(0xFF); - return returnByte; -} - -/** - * @brief Receive a number of bytes from the SPI port to a buffer - * - * @param buf Pointer to starting address of buffer to write to. - * @param nbyte Number of bytes to receive. - * @return Nothing - * - * @details Uses DMA - */ -void spiRead(uint8_t *buf, uint16_t nbyte) { - SPI.dmaTransfer(0, const_cast(buf), nbyte); -} - -/** - * @brief Send a single byte on SPI port - * - * @param b Byte to send - * - * @details - */ -void spiSend(uint8_t b) { - SPI.send(b); -} - -/** - * @brief Write token and then write from 512 byte buffer to SPI (for SD card) - * - * @param buf Pointer with buffer start address - * @return Nothing - * - * @details Use DMA - */ -void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI.send(token); - SPI.dmaSend(const_cast(buf), 512); -} - -#if ENABLED(SPI_EEPROM) - -// Read single byte from specified SPI channel -uint8_t spiRec(uint32_t chan) { return SPI.transfer(0xFF); } - -// Write single byte to specified SPI channel -void spiSend(uint32_t chan, byte b) { SPI.send(b); } - -// Write buffer to specified SPI channel -void spiSend(uint32_t chan, const uint8_t *buf, size_t n) { - for (size_t p = 0; p < n; p++) spiSend(chan, buf[p]); -} - -#endif // SPI_EEPROM - -#endif // SOFTWARE_SPI - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/MarlinSPI.h b/src/HAL/STM32F1/MarlinSPI.h deleted file mode 100644 index fab245f..0000000 --- a/src/HAL/STM32F1/MarlinSPI.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -/** - * Marlin currently requires 3 SPI classes: - * - * SPIClass: - * This class is normally provided by frameworks and has a semi-default interface. - * This is needed because some libraries reference it globally. - * - * SPISettings: - * Container for SPI configs for SPIClass. As above, libraries may reference it globally. - * - * These two classes are often provided by frameworks so we cannot extend them to add - * useful methods for Marlin. - * - * MarlinSPI: - * Provides the default SPIClass interface plus some Marlin goodies such as a simplified - * interface for SPI DMA transfer. - * - */ - -using MarlinSPI = SPIClass; diff --git a/src/HAL/STM32F1/MarlinSerial.cpp b/src/HAL/STM32F1/MarlinSerial.cpp deleted file mode 100644 index 6dabcde..0000000 --- a/src/HAL/STM32F1/MarlinSerial.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" -#include "MarlinSerial.h" -#include - -// Copied from ~/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/usart_private.h -// Changed to handle Emergency Parser -static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MSerialT &serial) { - /* Handle RXNEIE and TXEIE interrupts. - * RXNE signifies availability of a byte in DR. - * - * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15. - * We enable RXNEIE. - */ - uint32_t srflags = regs->SR, cr1its = regs->CR1; - - if ((cr1its & USART_CR1_RXNEIE) && (srflags & USART_SR_RXNE)) { - if (srflags & USART_SR_FE || srflags & USART_SR_PE ) { - // framing error or parity error - regs->DR; // Read and throw away the data, which also clears FE and PE - } - else { - uint8_t c = (uint8)regs->DR; - #ifdef USART_SAFE_INSERT - // If the buffer is full and the user defines USART_SAFE_INSERT, - // ignore new bytes. - rb_safe_insert(rb, c); - #else - // By default, push bytes around in the ring buffer. - rb_push_insert(rb, c); - #endif - #if ENABLED(EMERGENCY_PARSER) - if (serial.emergency_parser_enabled()) - emergency_parser.update(serial.emergency_state, c); - #endif - } - } - else if (srflags & USART_SR_ORE) { - // overrun and empty data, just do a dummy read to clear ORE - // and prevent a raise condition where a continuous interrupt stream (due to ORE set) occurs - // (see chapter "Overrun error" ) in STM32 reference manual - regs->DR; - } - - // TXE signifies readiness to send a byte to DR. - if ((cr1its & USART_CR1_TXEIE) && (srflags & USART_SR_TXE)) { - if (!rb_is_empty(wb)) - regs->DR=rb_remove(wb); - else - regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE - } -} - -// Not every MarlinSerial port should handle emergency parsing. -// It would not make sense to parse GCode from TMC responses, for example. -constexpr bool serial_handles_emergency(int port) { - return false - #ifdef SERIAL_PORT - || (SERIAL_PORT) == port - #endif - #ifdef SERIAL_PORT_2 - || (SERIAL_PORT_2) == port - #endif - #ifdef LCD_SERIAL_PORT - || (LCD_SERIAL_PORT) == port - #endif - ; -} - -#define DEFINE_HWSERIAL_MARLIN(name, n) \ - MSerialT name(serial_handles_emergency(n),\ - USART##n, \ - BOARD_USART##n##_TX_PIN, \ - BOARD_USART##n##_RX_PIN); \ - extern "C" void __irq_usart##n(void) { \ - my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \ - } - -#define DEFINE_HWSERIAL_UART_MARLIN(name, n) \ - MSerialT name(serial_handles_emergency(n), \ - UART##n, \ - BOARD_USART##n##_TX_PIN, \ - BOARD_USART##n##_RX_PIN); \ - extern "C" void __irq_usart##n(void) { \ - my_usart_irq(UART##n->rb, UART##n->wb, UART##n##_BASE, MSerial##n); \ - } - -// Instantiate all UARTs even if they are not needed -// This avoids a bunch of logic to figure out every serial -// port which may be in use on the system. -#if DISABLED(MKS_WIFI_MODULE) - DEFINE_HWSERIAL_MARLIN(MSerial1, 1); -#endif -DEFINE_HWSERIAL_MARLIN(MSerial2, 2); -DEFINE_HWSERIAL_MARLIN(MSerial3, 3); -#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) - DEFINE_HWSERIAL_UART_MARLIN(MSerial4, 4); - DEFINE_HWSERIAL_UART_MARLIN(MSerial5, 5); -#endif - -// Check the type of each serial port by passing it to a template function. -// HardwareSerial is known to sometimes hang the controller when an error occurs, -// so this case will fail the static assert. All other classes are assumed to be ok. -template -constexpr bool IsSerialClassAllowed(const T&) { return true; } -constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; } - -#define CHECK_CFG_SERIAL(A) static_assert(IsSerialClassAllowed(A), STRINGIFY(A) " is defined incorrectly"); -#define CHECK_AXIS_SERIAL(A) static_assert(IsSerialClassAllowed(A##_HARDWARE_SERIAL), STRINGIFY(A) "_HARDWARE_SERIAL must be defined in the form MSerial1, rather than Serial1"); - -// If you encounter this error, replace SerialX with MSerialX, for example MSerial3. - -// Non-TMC ports were already validated in HAL.h, so do not require verbose error messages. -#ifdef MYSERIAL1 - CHECK_CFG_SERIAL(MYSERIAL1); -#endif -#ifdef MYSERIAL2 - CHECK_CFG_SERIAL(MYSERIAL2); -#endif -#ifdef LCD_SERIAL - CHECK_CFG_SERIAL(LCD_SERIAL); -#endif -#if AXIS_HAS_HW_SERIAL(X) - CHECK_AXIS_SERIAL(X); -#endif -#if AXIS_HAS_HW_SERIAL(X2) - CHECK_AXIS_SERIAL(X2); -#endif -#if AXIS_HAS_HW_SERIAL(Y) - CHECK_AXIS_SERIAL(Y); -#endif -#if AXIS_HAS_HW_SERIAL(Y2) - CHECK_AXIS_SERIAL(Y2); -#endif -#if AXIS_HAS_HW_SERIAL(Z) - CHECK_AXIS_SERIAL(Z); -#endif -#if AXIS_HAS_HW_SERIAL(Z2) - CHECK_AXIS_SERIAL(Z2); -#endif -#if AXIS_HAS_HW_SERIAL(Z3) - CHECK_AXIS_SERIAL(Z3); -#endif -#if AXIS_HAS_HW_SERIAL(Z4) - CHECK_AXIS_SERIAL(Z4); -#endif -#if AXIS_HAS_HW_SERIAL(I) - CHECK_AXIS_SERIAL(I); -#endif -#if AXIS_HAS_HW_SERIAL(J) - CHECK_AXIS_SERIAL(J); -#endif -#if AXIS_HAS_HW_SERIAL(K) - CHECK_AXIS_SERIAL(K); -#endif -#if AXIS_HAS_HW_SERIAL(E0) - CHECK_AXIS_SERIAL(E0); -#endif -#if AXIS_HAS_HW_SERIAL(E1) - CHECK_AXIS_SERIAL(E1); -#endif -#if AXIS_HAS_HW_SERIAL(E2) - CHECK_AXIS_SERIAL(E2); -#endif -#if AXIS_HAS_HW_SERIAL(E3) - CHECK_AXIS_SERIAL(E3); -#endif -#if AXIS_HAS_HW_SERIAL(E4) - CHECK_AXIS_SERIAL(E4); -#endif -#if AXIS_HAS_HW_SERIAL(E5) - CHECK_AXIS_SERIAL(E5); -#endif -#if AXIS_HAS_HW_SERIAL(E6) - CHECK_AXIS_SERIAL(E6); -#endif -#if AXIS_HAS_HW_SERIAL(E7) - CHECK_AXIS_SERIAL(E7); -#endif - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/MarlinSerial.h b/src/HAL/STM32F1/MarlinSerial.h deleted file mode 100644 index dda32fe..0000000 --- a/src/HAL/STM32F1/MarlinSerial.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include -#include - -#include "../../inc/MarlinConfigPre.h" -#include "../../core/serial_hook.h" - -// Increase priority of serial interrupts, to reduce overflow errors -#define UART_IRQ_PRIO 1 - -struct MarlinSerial : public HardwareSerial { - MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) : HardwareSerial(usart_device, tx_pin, rx_pin) { } - - #ifdef UART_IRQ_PRIO - // Shadow the parent methods to set IRQ priority after begin() - void begin(uint32 baud) { - MarlinSerial::begin(baud, SERIAL_8N1); - } - - void begin(uint32 baud, uint8_t config) { - HardwareSerial::begin(baud, config); - nvic_irq_set_priority(c_dev()->irq_num, UART_IRQ_PRIO); - } - #endif -}; - -typedef Serial1Class MSerialT; - -extern MSerialT MSerial1; -extern MSerialT MSerial2; -extern MSerialT MSerial3; -#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) - extern MSerialT MSerial4; - extern MSerialT MSerial5; -#endif diff --git a/src/HAL/STM32F1/MinSerial.cpp b/src/HAL/STM32F1/MinSerial.cpp deleted file mode 100644 index 6cf68d8..0000000 --- a/src/HAL/STM32F1/MinSerial.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - -#include "../shared/MinSerial.h" - -#include -#include -#include - -/* Instruction Synchronization Barrier */ -#define isb() __asm__ __volatile__ ("isb" : : : "memory") - -/* Data Synchronization Barrier */ -#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") - -static void TXBegin() { - #if !WITHIN(SERIAL_PORT, 1, 6) - #warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error." - #warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port." - #else - // We use MYSERIAL1 here, so we need to figure out how to get the linked register - struct usart_dev* dev = MYSERIAL1.c_dev(); - - // Or use this if removing libmaple - // int irq = dev->irq_num; - // int nvicUART[] = { NVIC_USART1 /* = 37 */, NVIC_USART2 /* = 38 */, NVIC_USART3 /* = 39 */, NVIC_UART4 /* = 52 */, NVIC_UART5 /* = 53 */ }; - // Disabling irq means setting the bit in the NVIC ICER register located at - // Disable UART interrupt in NVIC - nvic_irq_disable(dev->irq_num); - - // Use this if removing libmaple - //SBI(NVIC_BASE->ICER[1], irq - 32); - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - dsb(); - isb(); - - rcc_clk_disable(dev->clk_id); - rcc_clk_enable(dev->clk_id); - - usart_reg_map *regs = dev->regs; - regs->CR1 = 0; // Reset the USART - regs->CR2 = 0; // 1 stop bit - - // If we don't touch the BRR (baudrate register), we don't need to recompute. Else we would need to call - usart_set_baud_rate(dev, 0, BAUDRATE); - - regs->CR1 = (USART_CR1_TE | USART_CR1_UE); // 8 bits, no parity, 1 stop bit - #endif -} - -// A SW memory barrier, to ensure GCC does not overoptimize loops -#define sw_barrier() __asm__ volatile("": : :"memory"); -static void TX(char c) { - #if WITHIN(SERIAL_PORT, 1, 6) - struct usart_dev* dev = MYSERIAL1.c_dev(); - while (!(dev->regs->SR & USART_SR_TXE)) { - hal.watchdog_refresh(); - sw_barrier(); - } - dev->regs->DR = c; - #endif -} - -void install_min_serial() { - HAL_min_serial_init = &TXBegin; - HAL_min_serial_out = &TX; -} - -#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't branch to a symbol that's too far, so we have a specific hack for them -extern "C" { - __attribute__((naked)) void JumpHandler_ASM() { - __asm__ __volatile__ ( - "b CommonHandler_ASM\n" - ); - } - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_hardfault(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_busfault(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_usagefault(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_memmanage(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_nmi(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception7(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception8(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception9(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception10(); - void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception13(); -} -#endif - -#endif // POSTMORTEM_DEBUGGING -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/README.md b/src/HAL/STM32F1/README.md deleted file mode 100644 index 40c5633..0000000 --- a/src/HAL/STM32F1/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# STM32F1 - -This HAL is for STM32F103 boards used with [Arduino STM32](https://github.com/rogerclarkmelbourne/Arduino_STM32) framework. - -Currently has been tested in Malyan M200 (103CBT6), SKRmini (103RCT6), Chitu 3d (103ZET6), and various 103VET6 boards. - -### Main developers: -- Victorpv -- xC000005 -- thisiskeithb -- tpruvot diff --git a/src/HAL/STM32F1/SPI.cpp b/src/HAL/STM32F1/SPI.cpp deleted file mode 100644 index 1ce2c7d..0000000 --- a/src/HAL/STM32F1/SPI.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/** - * @author Marti Bolivar - * @brief Wirish SPI implementation. - */ - -#ifdef __STM32F1__ - -#include - -#include -#include -#include - -#include -#include - -#include "../../inc/MarlinConfig.h" -#include "spi_pins.h" - -/** Time in ms for DMA receive timeout */ -#define DMA_TIMEOUT 100 - -#if CYCLES_PER_MICROSECOND != 72 - #warning "Unexpected clock speed; SPI frequency calculation will be incorrect" -#endif - -struct spi_pins { uint8_t nss, sck, miso, mosi; }; - -static const spi_pins* dev_to_spi_pins(spi_dev *dev); -static void configure_gpios(spi_dev *dev, bool as_master); -static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq); - -#if BOARD_NR_SPI >= 3 && !defined(STM32_HIGH_DENSITY) - #error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices" -#endif - -static const spi_pins board_spi_pins[] __FLASH__ = { - #if BOARD_NR_SPI >= 1 - { BOARD_SPI1_NSS_PIN, - BOARD_SPI1_SCK_PIN, - BOARD_SPI1_MISO_PIN, - BOARD_SPI1_MOSI_PIN }, - #endif - #if BOARD_NR_SPI >= 2 - { BOARD_SPI2_NSS_PIN, - BOARD_SPI2_SCK_PIN, - BOARD_SPI2_MISO_PIN, - BOARD_SPI2_MOSI_PIN }, - #endif - #if BOARD_NR_SPI >= 3 - { BOARD_SPI3_NSS_PIN, - BOARD_SPI3_SCK_PIN, - BOARD_SPI3_MISO_PIN, - BOARD_SPI3_MOSI_PIN }, - #endif -}; - -#if BOARD_NR_SPI >= 1 - static void *_spi1_this; -#endif -#if BOARD_NR_SPI >= 2 - static void *_spi2_this; -#endif -#if BOARD_NR_SPI >= 3 - static void *_spi3_this; -#endif - -/** - * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset. - */ -static inline void waitSpiTxEnd(spi_dev *spi_d) { - while (spi_is_tx_empty(spi_d) == 0) { /* nada */ } // wait until TXE=1 - while (spi_is_busy(spi_d) != 0) { /* nada */ } // wait until BSY=0 -} - -/** - * Constructor - */ -SPIClass::SPIClass(uint32_t spi_num) { - _currentSetting = &_settings[spi_num - 1]; // SPI channels are called 1 2 and 3 but the array is zero indexed - - switch (spi_num) { - #if BOARD_NR_SPI >= 1 - case 1: - _currentSetting->spi_d = SPI1; - _spi1_this = (void*)this; - break; - #endif - #if BOARD_NR_SPI >= 2 - case 2: - _currentSetting->spi_d = SPI2; - _spi2_this = (void*)this; - break; - #endif - #if BOARD_NR_SPI >= 3 - case 3: - _currentSetting->spi_d = SPI3; - _spi3_this = (void*)this; - break; - #endif - default: ASSERT(0); - } - - // Init things specific to each SPI device - // clock divider setup is a bit of hack, and needs to be improved at a later date. - #if BOARD_NR_SPI >= 1 - _settings[0].spi_d = SPI1; - _settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); - _settings[0].spiDmaDev = DMA1; - _settings[0].spiTxDmaChannel = DMA_CH3; - _settings[0].spiRxDmaChannel = DMA_CH2; - #endif - #if BOARD_NR_SPI >= 2 - _settings[1].spi_d = SPI2; - _settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); - _settings[1].spiDmaDev = DMA1; - _settings[1].spiTxDmaChannel = DMA_CH5; - _settings[1].spiRxDmaChannel = DMA_CH4; - #endif - #if BOARD_NR_SPI >= 3 - _settings[2].spi_d = SPI3; - _settings[2].clockDivider = determine_baud_rate(_settings[2].spi_d, _settings[2].clock); - _settings[2].spiDmaDev = DMA2; - _settings[2].spiTxDmaChannel = DMA_CH2; - _settings[2].spiRxDmaChannel = DMA_CH1; - #endif - - // added for DMA callbacks. - _currentSetting->state = SPI_STATE_IDLE; -} - -SPIClass::SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel) : SPIClass(1) { - #if BOARD_NR_SPI >= 1 - if (mosi == BOARD_SPI1_MOSI_PIN) setModule(1); - #endif - #if BOARD_NR_SPI >= 2 - if (mosi == BOARD_SPI2_MOSI_PIN) setModule(2); - #endif - #if BOARD_NR_SPI >= 3 - if (mosi == BOARD_SPI3_MOSI_PIN) setModule(3); - #endif -} - -/** - * Set up/tear down - */ -void SPIClass::updateSettings() { - uint32_t flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize | SPI_SW_SLAVE | SPI_SOFT_SS); - spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags); -} - -void SPIClass::begin() { - spi_init(_currentSetting->spi_d); - configure_gpios(_currentSetting->spi_d, 1); - updateSettings(); - // added for DMA callbacks. - _currentSetting->state = SPI_STATE_READY; -} - -void SPIClass::beginSlave() { - spi_init(_currentSetting->spi_d); - configure_gpios(_currentSetting->spi_d, 0); - uint32_t flags = ((_currentSetting->bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | _currentSetting->dataSize); - spi_slave_enable(_currentSetting->spi_d, (spi_mode)_currentSetting->dataMode, flags); - // added for DMA callbacks. - _currentSetting->state = SPI_STATE_READY; -} - -void SPIClass::end() { - if (!spi_is_enabled(_currentSetting->spi_d)) return; - - // Follows RM0008's sequence for disabling a SPI in master/slave - // full duplex mode. - while (spi_is_rx_nonempty(_currentSetting->spi_d)) { - // FIXME [0.1.0] remove this once you have an interrupt based driver - volatile uint16_t rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d); - } - waitSpiTxEnd(_currentSetting->spi_d); - - spi_peripheral_disable(_currentSetting->spi_d); - // added for DMA callbacks. - // Need to add unsetting the callbacks for the DMA channels. - _currentSetting->state = SPI_STATE_IDLE; -} - -/* Roger Clark added 3 functions */ -void SPIClass::setClockDivider(uint32_t clockDivider) { - _currentSetting->clockDivider = clockDivider; - uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_BR); - _currentSetting->spi_d->regs->CR1 = cr1 | (clockDivider & SPI_CR1_BR); -} - -void SPIClass::setBitOrder(BitOrder bitOrder) { - _currentSetting->bitOrder = bitOrder; - uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_LSBFIRST); - if (bitOrder == LSBFIRST) cr1 |= SPI_CR1_LSBFIRST; - _currentSetting->spi_d->regs->CR1 = cr1; -} - -/** - * Victor Perez. Added to test changing datasize from 8 to 16 bit modes on the fly. - * Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. - */ -void SPIClass::setDataSize(uint32_t datasize) { - _currentSetting->dataSize = datasize; - uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_DFF); - uint8_t en = spi_is_enabled(_currentSetting->spi_d); - spi_peripheral_disable(_currentSetting->spi_d); - _currentSetting->spi_d->regs->CR1 = cr1 | (datasize & SPI_CR1_DFF) | en; -} - -void SPIClass::setDataMode(uint8_t dataMode) { - /** - * Notes: - * As far as we know the AVR numbers for dataMode match the numbers required by the STM32. - * From the AVR doc https://www.atmel.com/images/doc2585.pdf section 2.4 - * - * SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge - * 0 0 0 Falling Rising - * 1 0 1 Rising Falling - * 2 1 0 Rising Falling - * 3 1 1 Falling Rising - * - * On the STM32 it appears to be - * - * bit 1 - CPOL : Clock polarity - * (This bit should not be changed when communication is ongoing) - * 0 : CLK to 0 when idle - * 1 : CLK to 1 when idle - * - * bit 0 - CPHA : Clock phase - * (This bit should not be changed when communication is ongoing) - * 0 : The first clock transition is the first data capture edge - * 1 : The second clock transition is the first data capture edge - * - * If someone finds this is not the case or sees a logic error with this let me know ;-) - */ - _currentSetting->dataMode = dataMode; - uint32_t cr1 = _currentSetting->spi_d->regs->CR1 & ~(SPI_CR1_CPOL|SPI_CR1_CPHA); - _currentSetting->spi_d->regs->CR1 = cr1 | (dataMode & (SPI_CR1_CPOL|SPI_CR1_CPHA)); -} - -void SPIClass::beginTransaction(uint8_t pin, const SPISettings &settings) { - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); - begin(); -} - -void SPIClass::beginTransactionSlave(const SPISettings &settings) { - setBitOrder(settings.bitOrder); - setDataMode(settings.dataMode); - setDataSize(settings.dataSize); - beginSlave(); -} - -void SPIClass::endTransaction() { } - -/** - * I/O - */ - -uint16_t SPIClass::read() { - while (!spi_is_rx_nonempty(_currentSetting->spi_d)) { /* nada */ } - return (uint16_t)spi_rx_reg(_currentSetting->spi_d); -} - -void SPIClass::read(uint8_t *buf, uint32_t len) { - if (len == 0) return; - spi_rx_reg(_currentSetting->spi_d); // clear the RX buffer in case a byte is waiting on it. - spi_reg_map * regs = _currentSetting->spi_d->regs; - // start sequence: write byte 0 - regs->DR = 0x00FF; // write the first byte - // main loop - while (--len) { - while (!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait for TXE flag - noInterrupts(); // go atomic level - avoid interrupts to surely get the previously received data - regs->DR = 0x00FF; // write the next data item to be transmitted into the SPI_DR register. This clears the TXE flag. - while (!(regs->SR & SPI_SR_RXNE)) { /* nada */ } // wait till data is available in the DR register - *buf++ = (uint8)(regs->DR); // read and store the received byte. This clears the RXNE flag. - interrupts(); // let systick do its job - } - // read remaining last byte - while (!(regs->SR & SPI_SR_RXNE)) { /* nada */ } // wait till data is available in the Rx register - *buf++ = (uint8)(regs->DR); // read and store the received byte -} - -void SPIClass::write(uint16_t data) { - /* Added for 16bit data Victor Perez. Roger Clark - * Improved speed by just directly writing the single byte to the SPI data reg and wait for completion, - * by taking the Tx code from transfer(byte) - * This almost doubles the speed of this function. - */ - spi_tx_reg(_currentSetting->spi_d, data); // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - waitSpiTxEnd(_currentSetting->spi_d); -} - -void SPIClass::write16(uint16_t data) { - // Added by stevestrong: write two consecutive bytes in 8 bit mode (DFF=0) - spi_tx_reg(_currentSetting->spi_d, data>>8); // write high byte - while (!spi_is_tx_empty(_currentSetting->spi_d)) { /* nada */ } // Wait until TXE=1 - spi_tx_reg(_currentSetting->spi_d, data); // write low byte - waitSpiTxEnd(_currentSetting->spi_d); -} - -void SPIClass::write(uint16_t data, uint32_t n) { - // Added by stevstrong: Repeatedly send same data by the specified number of times - spi_reg_map * regs = _currentSetting->spi_d->regs; - while (n--) { - regs->DR = data; // write the data to be transmitted into the SPI_DR register (this clears the TXE flag) - while (!(regs->SR & SPI_SR_TXE)) { /* nada */ } // wait till Tx empty - } - while (regs->SR & SPI_SR_BSY) { /* nada */ } // wait until BSY=0 before returning -} - -void SPIClass::write(const void *data, uint32_t length) { - spi_dev * spi_d = _currentSetting->spi_d; - spi_tx(spi_d, data, length); // data can be array of bytes or words - waitSpiTxEnd(spi_d); -} - -uint8_t SPIClass::transfer(uint8_t byte) const { - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - spi_tx_reg(spi_d, byte); // Write the data item to be transmitted into the SPI_DR register - waitSpiTxEnd(spi_d); - return (uint8)spi_rx_reg(spi_d); // "... and read the last received data." -} - -uint16_t SPIClass::transfer16(uint16_t data) const { - // Modified by stevestrong: write & read two consecutive bytes in 8 bit mode (DFF=0) - // This is more effective than two distinct byte transfers - spi_dev * spi_d = _currentSetting->spi_d; - spi_rx_reg(spi_d); // read any previous data - spi_tx_reg(spi_d, data>>8); // write high byte - waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 - uint16_t ret = spi_rx_reg(spi_d)<<8; // read and shift high byte - spi_tx_reg(spi_d, data); // write low byte - waitSpiTxEnd(spi_d); // wait until TXE=1 and then wait until BSY=0 - ret += spi_rx_reg(spi_d); // read low byte - return ret; -} - -/** - * Roger Clark and Victor Perez, 2015 - * Performs a DMA SPI transfer with at least a receive buffer. - * If a TX buffer is not provided, FF is sent over and over for the length of the transfer. - * On exit TX buffer is not modified, and RX buffer contains the received data. - * Still in progress. - */ -void SPIClass::dmaTransferSet(const void *transmitBuf, void *receiveBuf) { - dma_init(_currentSetting->spiDmaDev); - //spi_rx_dma_enable(_currentSetting->spi_d); - //spi_tx_dma_enable(_currentSetting->spi_d); - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &_currentSetting->spi_d->regs->DR, - dma_bit_size, receiveBuf, dma_bit_size, (DMA_MINC_MODE | DMA_TRNS_CMPLT ));// receive buffer DMA - if (!transmitBuf) { - transmitBuf = &ff; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, - dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, (DMA_FROM_MEM));// Transmit FF repeatedly - } - else { - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, - dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, (DMA_MINC_MODE | DMA_FROM_MEM ));// Transmit buffer DMA - } - dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); - dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, DMA_PRIORITY_VERY_HIGH); -} - -uint8_t SPIClass::dmaTransferRepeat(uint16_t length) { - if (length == 0) return 0; - if (spi_is_rx_nonempty(_currentSetting->spi_d) == 1) spi_rx_reg(_currentSetting->spi_d); - _currentSetting->state = SPI_STATE_TRANSFER; - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, length); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel);// enable receive - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit - spi_rx_dma_enable(_currentSetting->spi_d); - spi_tx_dma_enable(_currentSetting->spi_d); - if (_currentSetting->receiveCallback) - return 0; - - //uint32_t m = millis(); - uint8_t b = 0; - uint32_t m = millis(); - while (!(dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)) { - // Avoid interrupts and just loop waiting for the flag to be set. - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } - } - - waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 - spi_tx_dma_disable(_currentSetting->spi_d); - spi_rx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; - return b; -} - -/** - * Roger Clark and Victor Perez, 2015 - * Performs a DMA SPI transfer with at least a receive buffer. - * If a TX buffer is not provided, FF is sent over and over for the length of the transfer. - * On exit TX buffer is not modified, and RX buffer contains the received data. - * Still in progress. - */ -uint8_t SPIClass::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) { - dmaTransferSet(transmitBuf, receiveBuf); - return dmaTransferRepeat(length); -} - -/** - * Roger Clark and Victor Perez, 2015 - * Performs a DMA SPI send using a TX buffer. - * On exit TX buffer is not modified. - * Still in progress. - * 2016 - stevstrong - reworked to automatically detect bit size from SPI setting - */ -void SPIClass::dmaSendSet(const void * transmitBuf, bool minc) { - uint32_t flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); - dma_init(_currentSetting->spiDmaDev); - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, dma_bit_size, - (volatile void*)transmitBuf, dma_bit_size, flags);// Transmit buffer DMA - dma_set_priority(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, DMA_PRIORITY_LOW); -} - -uint8_t SPIClass::dmaSendRepeat(uint16_t length) { - if (length == 0) return 0; - - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - _currentSetting->state = SPI_STATE_TRANSMIT; - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); // enable transmit - spi_tx_dma_enable(_currentSetting->spi_d); - if (_currentSetting->transmitCallback) return 0; - - uint32_t m = millis(); - uint8_t b = 0; - while (!(dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)) { - // Avoid interrupts and just loop waiting for the flag to be set. - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } - } - waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 - spi_tx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; - return b; -} - -uint8_t SPIClass::dmaSend(const void * transmitBuf, uint16_t length, bool minc) { - dmaSendSet(transmitBuf, minc); - return dmaSendRepeat(length); -} - -uint8_t SPIClass::dmaSendAsync(const void * transmitBuf, uint16_t length, bool minc) { - uint8_t b = 0; - - if (_currentSetting->state != SPI_STATE_READY) { - uint32_t m = millis(); - while (!(dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel) & DMA_ISR_TCIF1)) { - //Avoid interrupts and just loop waiting for the flag to be set. - //delayMicroseconds(10); - if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; } - } - waitSpiTxEnd(_currentSetting->spi_d); // until TXE=1 and BSY=0 - spi_tx_dma_disable(_currentSetting->spi_d); - dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - _currentSetting->state = SPI_STATE_READY; - } - - if (length == 0) return 0; - uint32_t flags = ( (DMA_MINC_MODE*minc) | DMA_FROM_MEM | DMA_TRNS_CMPLT); - - dma_init(_currentSetting->spiDmaDev); - // TX - dma_xfer_size dma_bit_size = (_currentSetting->dataSize==DATA_SIZE_16BIT) ? DMA_SIZE_16BITS : DMA_SIZE_8BITS; - dma_setup_transfer(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &_currentSetting->spi_d->regs->DR, - dma_bit_size, (volatile void*)transmitBuf, dma_bit_size, flags);// Transmit buffer DMA - dma_set_num_transfers(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, length); - dma_clear_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - dma_enable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel);// enable transmit - spi_tx_dma_enable(_currentSetting->spi_d); - - _currentSetting->state = SPI_STATE_TRANSMIT; - return b; -} - - -/** - * New functions added to manage callbacks. - * Victor Perez 2017 - */ -void SPIClass::onReceive(void(*callback)()) { - _currentSetting->receiveCallback = callback; - if (callback) { - switch (_currentSetting->spi_d->clk_id) { - #if BOARD_NR_SPI >= 1 - case RCC_SPI1: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi1EventCallback); - break; - #endif - #if BOARD_NR_SPI >= 2 - case RCC_SPI2: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi2EventCallback); - break; - #endif - #if BOARD_NR_SPI >= 3 - case RCC_SPI3: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel, &SPIClass::_spi3EventCallback); - break; - #endif - default: - ASSERT(0); - } - } - else { - dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - } -} - -void SPIClass::onTransmit(void(*callback)()) { - _currentSetting->transmitCallback = callback; - if (callback) { - switch (_currentSetting->spi_d->clk_id) { - #if BOARD_NR_SPI >= 1 - case RCC_SPI1: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi1EventCallback); - break; - #endif - #if BOARD_NR_SPI >= 2 - case RCC_SPI2: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi2EventCallback); - break; - #endif - #if BOARD_NR_SPI >= 3 - case RCC_SPI3: - dma_attach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel, &SPIClass::_spi3EventCallback); - break; - #endif - default: - ASSERT(0); - } - } - else { - dma_detach_interrupt(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - } -} - -/** - * TODO: check if better to first call the customer code, next disable the DMA requests. - * Also see if we need to check whether callbacks are set or not, may be better to be checked - * during the initial setup and only set the callback to EventCallback if they are set. - */ -void SPIClass::EventCallback() { - waitSpiTxEnd(_currentSetting->spi_d); - switch (_currentSetting->state) { - case SPI_STATE_TRANSFER: - while (spi_is_rx_nonempty(_currentSetting->spi_d)) { /* nada */ } - _currentSetting->state = SPI_STATE_READY; - spi_tx_dma_disable(_currentSetting->spi_d); - spi_rx_dma_disable(_currentSetting->spi_d); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaChannel); - if (_currentSetting->receiveCallback) - _currentSetting->receiveCallback(); - break; - case SPI_STATE_TRANSMIT: - _currentSetting->state = SPI_STATE_READY; - spi_tx_dma_disable(_currentSetting->spi_d); - //dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaChannel); - if (_currentSetting->transmitCallback) - _currentSetting->transmitCallback(); - break; - default: - break; - } -} - -void SPIClass::attachInterrupt() { - // Should be enableInterrupt() -} - -void SPIClass::detachInterrupt() { - // Should be disableInterrupt() -} - -/** - * Pin accessors - */ - -uint8_t SPIClass::misoPin() { - return dev_to_spi_pins(_currentSetting->spi_d)->miso; -} - -uint8_t SPIClass::mosiPin() { - return dev_to_spi_pins(_currentSetting->spi_d)->mosi; -} - -uint8_t SPIClass::sckPin() { - return dev_to_spi_pins(_currentSetting->spi_d)->sck; -} - -uint8_t SPIClass::nssPin() { - return dev_to_spi_pins(_currentSetting->spi_d)->nss; -} - -/** - * Deprecated functions - */ -uint8_t SPIClass::send(uint8_t data) { write(data); return 1; } -uint8_t SPIClass::send(uint8_t *buf, uint32_t len) { write(buf, len); return len; } -uint8_t SPIClass::recv() { return read(); } - -/** - * DMA call back functions, one per port. - */ -#if BOARD_NR_SPI >= 1 - void SPIClass::_spi1EventCallback() { - reinterpret_cast(_spi1_this)->EventCallback(); - } -#endif -#if BOARD_NR_SPI >= 2 - void SPIClass::_spi2EventCallback() { - reinterpret_cast(_spi2_this)->EventCallback(); - } -#endif -#if BOARD_NR_SPI >= 3 - void SPIClass::_spi3EventCallback() { - reinterpret_cast(_spi3_this)->EventCallback(); - } -#endif - -/** - * Auxiliary functions - */ -static const spi_pins* dev_to_spi_pins(spi_dev *dev) { - switch (dev->clk_id) { - #if BOARD_NR_SPI >= 1 - case RCC_SPI1: return board_spi_pins; - #endif - #if BOARD_NR_SPI >= 2 - case RCC_SPI2: return board_spi_pins + 1; - #endif - #if BOARD_NR_SPI >= 3 - case RCC_SPI3: return board_spi_pins + 2; - #endif - default: return nullptr; - } -} - -static void disable_pwm(const stm32_pin_info *i) { - if (i->timer_device) - timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED); -} - -static void configure_gpios(spi_dev *dev, bool as_master) { - const spi_pins *pins = dev_to_spi_pins(dev); - if (!pins) return; - - const stm32_pin_info *nssi = &PIN_MAP[pins->nss], - *scki = &PIN_MAP[pins->sck], - *misoi = &PIN_MAP[pins->miso], - *mosii = &PIN_MAP[pins->mosi]; - - disable_pwm(nssi); - disable_pwm(scki); - disable_pwm(misoi); - disable_pwm(mosii); - - spi_config_gpios(dev, as_master, nssi->gpio_device, nssi->gpio_bit, - scki->gpio_device, scki->gpio_bit, misoi->gpio_bit, - mosii->gpio_bit); -} - -static const spi_baud_rate baud_rates[8] __FLASH__ = { - SPI_BAUD_PCLK_DIV_2, - SPI_BAUD_PCLK_DIV_4, - SPI_BAUD_PCLK_DIV_8, - SPI_BAUD_PCLK_DIV_16, - SPI_BAUD_PCLK_DIV_32, - SPI_BAUD_PCLK_DIV_64, - SPI_BAUD_PCLK_DIV_128, - SPI_BAUD_PCLK_DIV_256, -}; - -/** - * Note: This assumes you're on a LeafLabs-style board - * (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - */ -static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) { - uint32_t clock = 0; - switch (rcc_dev_clk(dev->clk_id)) { - case RCC_AHB: - case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz - case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz - } - clock >>= 1; - - uint8_t i = 0; - while (i < 7 && freq < clock) { clock >>= 1; i++; } - return baud_rates[i]; -} - -SPIClass SPI(SPI_DEVICE); - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/SPI.h b/src/HAL/STM32F1/SPI.h deleted file mode 100644 index 13f4d5e..0000000 --- a/src/HAL/STM32F1/SPI.h +++ /dev/null @@ -1,417 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - *****************************************************************************/ -#pragma once - -#include -#include -#include - -#include -#include -#include - -// SPI_HAS_TRANSACTION means SPI has -// - beginTransaction() -// - endTransaction() -// - usingInterrupt() -// - SPISetting(clock, bitOrder, dataMode) -//#define SPI_HAS_TRANSACTION - -#define SPI_CLOCK_DIV2 SPI_BAUD_PCLK_DIV_2 -#define SPI_CLOCK_DIV4 SPI_BAUD_PCLK_DIV_4 -#define SPI_CLOCK_DIV8 SPI_BAUD_PCLK_DIV_8 -#define SPI_CLOCK_DIV16 SPI_BAUD_PCLK_DIV_16 -#define SPI_CLOCK_DIV32 SPI_BAUD_PCLK_DIV_32 -#define SPI_CLOCK_DIV64 SPI_BAUD_PCLK_DIV_64 -#define SPI_CLOCK_DIV128 SPI_BAUD_PCLK_DIV_128 -#define SPI_CLOCK_DIV256 SPI_BAUD_PCLK_DIV_256 - -/* - * Roger Clark. 20150106 - * Commented out redundant AVR defined - * -#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR -#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR -#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR - -// define SPI_AVR_EIMSK for AVR boards with external interrupt pins -#ifdef EIMSK - #define SPI_AVR_EIMSK EIMSK -#elif defined(GICR) - #define SPI_AVR_EIMSK GICR -#elif defined(GIMSK) - #define SPI_AVR_EIMSK GIMSK -#endif -*/ - -#ifndef STM32_LSBFIRST - #define STM32_LSBFIRST 0 -#endif -#ifndef STM32_MSBFIRST - #define STM32_MSBFIRST 1 -#endif - -// PC13 or PA4 -#define BOARD_SPI_DEFAULT_SS PA4 -//#define BOARD_SPI_DEFAULT_SS PC13 - -#define SPI_MODE0 SPI_MODE_0 -#define SPI_MODE1 SPI_MODE_1 -#define SPI_MODE2 SPI_MODE_2 -#define SPI_MODE3 SPI_MODE_3 - -#define DATA_SIZE_8BIT SPI_CR1_DFF_8_BIT -#define DATA_SIZE_16BIT SPI_CR1_DFF_16_BIT - -typedef enum { - SPI_STATE_IDLE, - SPI_STATE_READY, - SPI_STATE_RECEIVE, - SPI_STATE_TRANSMIT, - SPI_STATE_TRANSFER -} spi_mode_t; - -class SPISettings { -public: - SPISettings(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode) { - if (__builtin_constant_p(inClock)) - init_AlwaysInline(inClock, inBitOrder, inDataMode, DATA_SIZE_8BIT); - else - init_MightInline(inClock, inBitOrder, inDataMode, DATA_SIZE_8BIT); - } - SPISettings(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { - if (__builtin_constant_p(inClock)) - init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); - else - init_MightInline(inClock, inBitOrder, inDataMode, inDataSize); - } - SPISettings(uint32_t inClock) { - if (__builtin_constant_p(inClock)) - init_AlwaysInline(inClock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); - else - init_MightInline(inClock, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); - } - SPISettings() { - init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); - } -private: - void init_MightInline(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { - init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); - } - void init_AlwaysInline(uint32_t inClock, BitOrder inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) { - clock = inClock; - bitOrder = inBitOrder; - dataMode = inDataMode; - dataSize = inDataSize; - //state = SPI_STATE_IDLE; - } - uint32_t clock; - uint32_t dataSize; - uint32_t clockDivider; - BitOrder bitOrder; - uint8_t dataMode; - uint8_t _SSPin; - volatile spi_mode_t state; - spi_dev *spi_d; - dma_channel spiRxDmaChannel, spiTxDmaChannel; - dma_dev* spiDmaDev; - void (*receiveCallback)() = nullptr; - void (*transmitCallback)() = nullptr; - - friend class SPIClass; -}; - -/* - * Kept for compat. - */ -static const uint8_t ff = 0xFF; - -/** - * @brief Wirish SPI interface. - * - * This implementation uses software slave management, so the caller - * is responsible for controlling the slave select line. - */ -class SPIClass { - -public: - /** - * @param spiPortNumber Number of the SPI port to manage. - */ - SPIClass(uint32_t spiPortNumber); - - /** - * Init using pins - */ - SPIClass(int8_t mosi, int8_t miso, int8_t sclk, int8_t ssel=-1); - - /** - * @brief Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0). - */ - void begin(); - - /** - * @brief Turn on a SPI port and set its GPIO pin modes for use as a slave. - * - * SPI port is enabled in full duplex mode, with software slave management. - * - * @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST(big-endian) - * @param mode SPI mode to use - */ - void beginSlave(uint32_t bitOrder, uint32_t mode); - - /** - * @brief Equivalent to beginSlave(MSBFIRST, 0). - */ - void beginSlave(); - - /** - * @brief Disables the SPI port, but leaves its GPIO pin modes unchanged. - */ - void end(); - - void beginTransaction(const SPISettings &settings) { beginTransaction(BOARD_SPI_DEFAULT_SS, settings); } - void beginTransaction(uint8_t pin, const SPISettings &settings); - void endTransaction(); - - void beginTransactionSlave(const SPISettings &settings); - - void setClockDivider(uint32_t clockDivider); - void setBitOrder(BitOrder bitOrder); - void setDataMode(uint8_t dataMode); - - // SPI Configuration methods - void attachInterrupt(); - void detachInterrupt(); - - /* Victor Perez. Added to change datasize from 8 to 16 bit modes on the fly. - * Input parameter should be SPI_CR1_DFF set to 0 or 1 on a 32bit word. - * Requires an added function spi_data_size on STM32F1 / cores / maple / libmaple / spi.c - */ - void setDataSize(uint32_t ds); - - uint32_t getDataSize() { return _currentSetting->dataSize; } - - /* Victor Perez 2017. Added to set and clear callback functions for callback - * on DMA transfer completion. - * onReceive used to set the callback in case of dmaTransfer (tx/rx), once rx is completed - * onTransmit used to set the callback in case of dmaSend (tx only). That function - * will NOT be called in case of TX/RX - */ - void onReceive(void(*)()); - void onTransmit(void(*)()); - - /* - * I/O - */ - - /** - * @brief Return the next unread byte/word. - * - * If there is no unread byte/word waiting, this function will block - * until one is received. - */ - uint16_t read(); - - /** - * @brief Read length bytes, storing them into buffer. - * @param buffer Buffer to store received bytes into. - * @param length Number of bytes to store in buffer. This - * function will block until the desired number of - * bytes have been read. - */ - void read(uint8_t *buffer, uint32_t length); - - /** - * @brief Transmit one byte/word. - * @param data to transmit. - */ - void write(uint16_t data); - void write16(uint16_t data); // write 2 bytes in 8 bit mode (DFF=0) - - /** - * @brief Transmit one byte/word a specified number of times. - * @param data to transmit. - */ - void write(uint16_t data, uint32_t n); - - /** - * @brief Transmit multiple bytes/words. - * @param buffer Bytes/words to transmit. - * @param length Number of bytes/words in buffer to transmit. - */ - void write(const void * buffer, uint32_t length); - - /** - * @brief Transmit a byte, then return the next unread byte. - * - * This function transmits before receiving. - * - * @param data Byte to transmit. - * @return Next unread byte. - */ - uint8_t transfer(uint8_t data) const; - uint16_t transfer16(uint16_t data) const; - - /** - * @brief Sets up a DMA Transfer for "length" bytes. - * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. - * - * This function transmits and receives to buffers. - * - * @param transmitBuf buffer Bytes to transmit. If passed as 0, it sends FF repeatedly for "length" bytes - * @param receiveBuf buffer Bytes to save received data. - * @param length Number of bytes in buffer to transmit. - */ - uint8_t dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16_t length); - void dmaTransferSet(const void *transmitBuf, void *receiveBuf); - uint8_t dmaTransferRepeat(uint16_t length); - - /** - * @brief Sets up a DMA Transmit for SPI 8 or 16 bit transfer mode. - * The transfer mode (8 or 16 bit mode) is evaluated from the SPI peripheral setting. - * - * This function only transmits and does not care about the RX fifo. - * - * @param data buffer half words to transmit, - * @param length Number of bytes in buffer to transmit. - * @param minc Set to use Memory Increment mode, clear to use Circular mode. - */ - uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = 1); - void dmaSendSet(const void * transmitBuf, bool minc); - uint8_t dmaSendRepeat(uint16_t length); - - uint8_t dmaSendAsync(const void * transmitBuf, uint16_t length, bool minc = 1); - /* - * Pin accessors - */ - - /** - * @brief Return the number of the MISO (master in, slave out) pin - */ - uint8_t misoPin(); - - /** - * @brief Return the number of the MOSI (master out, slave in) pin - */ - uint8_t mosiPin(); - - /** - * @brief Return the number of the SCK (serial clock) pin - */ - uint8_t sckPin(); - - /** - * @brief Return the number of the NSS (slave select) pin - */ - uint8_t nssPin(); - - /* Escape hatch */ - - /** - * @brief Get a pointer to the underlying libmaple spi_dev for - * this HardwareSPI instance. - */ - spi_dev* c_dev() { return _currentSetting->spi_d; } - - spi_dev* dev() { return _currentSetting->spi_d; } - - /** - * @brief Sets the number of the SPI peripheral to be used by - * this HardwareSPI instance. - * - * @param spi_num Number of the SPI port. 1-2 in low density devices - * or 1-3 in high density devices. - */ - void setModule(int spi_num) { - _currentSetting = &_settings[spi_num - 1];// SPI channels are called 1 2 and 3 but the array is zero indexed - } - - /* -- The following methods are deprecated --------------------------- */ - - /** - * @brief Deprecated. - * - * Use HardwareSPI::transfer() instead. - * - * @see HardwareSPI::transfer() - */ - uint8_t send(uint8_t data); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::write() in combination with - * HardwareSPI::read() (or HardwareSPI::transfer()) instead. - * - * @see HardwareSPI::write() - * @see HardwareSPI::read() - * @see HardwareSPI::transfer() - */ - uint8_t send(uint8_t *data, uint32_t length); - - /** - * @brief Deprecated. - * - * Use HardwareSPI::read() instead. - * - * @see HardwareSPI::read() - */ - uint8_t recv(); - -private: - - SPISettings _settings[BOARD_NR_SPI]; - SPISettings *_currentSetting; - - void updateSettings(); - - /* - * Functions added for DMA transfers with Callback. - * Experimental. - */ - - void EventCallback(); - - #if BOARD_NR_SPI >= 1 - static void _spi1EventCallback(); - #endif - #if BOARD_NR_SPI >= 2 - static void _spi2EventCallback(); - #endif - #if BOARD_NR_SPI >= 3 - static void _spi3EventCallback(); - #endif - /* - spi_dev *spi_d; - uint8_t _SSPin; - uint32_t clockDivider; - uint8_t dataMode; - BitOrder bitOrder; - */ -}; - -extern SPIClass SPI; diff --git a/src/HAL/STM32F1/Servo.cpp b/src/HAL/STM32F1/Servo.cpp deleted file mode 100644 index 47ffb63..0000000 --- a/src/HAL/STM32F1/Servo.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -uint8_t ServoCount = 0; - -#include "Servo.h" - -//#include "Servo.h" - -#include -#include -#include -#include - -/** - * 20 millisecond period config. For a 1-based prescaler, - * - * (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec - * => prescaler * overflow = 20 * CYC_MSEC - * - * This uses the smallest prescaler that allows an overflow < 2^16. - */ -#define MAX_OVERFLOW UINT16_MAX // _BV(16) - 1 -#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) -#define TAU_MSEC 20 -#define TAU_USEC (TAU_MSEC * 1000) -#define TAU_CYC (TAU_MSEC * CYC_MSEC) -#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1) -#define SERVO_OVERFLOW ((uint16_t)round((double)TAU_CYC / SERVO_PRESCALER)) - -// Unit conversions -#define US_TO_COMPARE(us) uint16_t(map((us), 0, TAU_USEC, 0, SERVO_OVERFLOW)) -#define COMPARE_TO_US(c) uint32_t(map((c), 0, SERVO_OVERFLOW, 0, TAU_USEC)) -#define ANGLE_TO_US(a) uint16_t(map((a), minAngle, maxAngle, SERVO_DEFAULT_MIN_PW, SERVO_DEFAULT_MAX_PW)) -#define US_TO_ANGLE(us) int16_t(map((us), SERVO_DEFAULT_MIN_PW, SERVO_DEFAULT_MAX_PW, minAngle, maxAngle)) - -void libServo::servoWrite(uint8_t inPin, uint16_t duty_cycle) { - #ifdef MF_TIMER_SERVO0 - if (servoIndex == 0) { - pwmSetDuty(duty_cycle); - return; - } - #endif - - timer_dev *tdev = PIN_MAP[inPin].timer_device; - uint8_t tchan = PIN_MAP[inPin].timer_channel; - if (tdev) timer_set_compare(tdev, tchan, duty_cycle); -} - -libServo::libServo() { - servoIndex = ServoCount < MAX_SERVOS ? ServoCount++ : INVALID_SERVO; - HAL_timer_set_interrupt_priority(MF_TIMER_SERVO0, SERVO0_TIMER_IRQ_PRIO); -} - -bool libServo::attach(const int32_t inPin, const int32_t inMinAngle, const int32_t inMaxAngle) { - if (servoIndex >= MAX_SERVOS) return false; - if (inPin >= BOARD_NR_GPIO_PINS) return false; - - minAngle = inMinAngle; - maxAngle = inMaxAngle; - angle = -1; - - #ifdef MF_TIMER_SERVO0 - if (servoIndex == 0 && setupSoftPWM(inPin)) { - pin = inPin; // set attached() - return true; - } - #endif - - if (!PWM_PIN(inPin)) return false; - - timer_dev *tdev = PIN_MAP[inPin].timer_device; - //uint8_t tchan = PIN_MAP[inPin].timer_channel; - - SET_PWM(inPin); - servoWrite(inPin, 0); - - timer_pause(tdev); - timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based - timer_set_reload(tdev, SERVO_OVERFLOW); - timer_generate_update(tdev); - timer_resume(tdev); - - pin = inPin; // set attached() - return true; -} - -bool libServo::detach() { - if (!attached()) return false; - angle = -1; - servoWrite(pin, 0); - return true; -} - -int32_t libServo::read() const { - if (attached()) { - #ifdef MF_TIMER_SERVO0 - if (servoIndex == 0) return angle; - #endif - timer_dev *tdev = PIN_MAP[pin].timer_device; - uint8_t tchan = PIN_MAP[pin].timer_channel; - return US_TO_ANGLE(COMPARE_TO_US(timer_get_compare(tdev, tchan))); - } - return 0; -} - -void libServo::move(const int32_t 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 (attached()) { - angle = constrain(value, minAngle, maxAngle); - servoWrite(pin, US_TO_COMPARE(ANGLE_TO_US(angle))); - safe_delay(servo_delay[servoIndex]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -#ifdef MF_TIMER_SERVO0 - extern "C" void Servo_IRQHandler() { - static timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0); - uint16_t SR = timer_get_status(tdev); - if (SR & TIMER_SR_CC1IF) { // channel 1 off - #ifdef SERVO0_PWM_OD - OUT_WRITE_OD(SERVO0_PIN, HIGH); // off - #else - OUT_WRITE(SERVO0_PIN, LOW); - #endif - timer_reset_status_bit(tdev, TIMER_SR_CC1IF_BIT); - } - if (SR & TIMER_SR_CC2IF) { // channel 2 resume - #ifdef SERVO0_PWM_OD - OUT_WRITE_OD(SERVO0_PIN, LOW); // on - #else - OUT_WRITE(SERVO0_PIN, HIGH); - #endif - timer_reset_status_bit(tdev, TIMER_SR_CC2IF_BIT); - } - } - - bool libServo::setupSoftPWM(const int32_t inPin) { - timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0); - if (!tdev) return false; - #ifdef SERVO0_PWM_OD - OUT_WRITE_OD(inPin, HIGH); - #else - OUT_WRITE(inPin, LOW); - #endif - - timer_pause(tdev); - timer_set_mode(tdev, 1, TIMER_OUTPUT_COMPARE); // counter with isr - timer_oc_set_mode(tdev, 1, TIMER_OC_MODE_FROZEN, 0); // no pin output change - timer_oc_set_mode(tdev, 2, TIMER_OC_MODE_FROZEN, 0); // no pin output change - timer_set_prescaler(tdev, SERVO_PRESCALER - 1); // prescaler is 1-based - timer_set_reload(tdev, SERVO_OVERFLOW); - timer_set_compare(tdev, 1, SERVO_OVERFLOW); - timer_set_compare(tdev, 2, SERVO_OVERFLOW); - timer_attach_interrupt(tdev, 1, Servo_IRQHandler); - timer_attach_interrupt(tdev, 2, Servo_IRQHandler); - timer_generate_update(tdev); - timer_resume(tdev); - - return true; - } - - void libServo::pwmSetDuty(const uint16_t duty_cycle) { - timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0); - timer_set_compare(tdev, 1, duty_cycle); - timer_generate_update(tdev); - if (duty_cycle) { - timer_enable_irq(tdev, 1); - timer_enable_irq(tdev, 2); - } - else { - timer_disable_irq(tdev, 1); - timer_disable_irq(tdev, 2); - #ifdef SERVO0_PWM_OD - OUT_WRITE_OD(pin, HIGH); // off - #else - OUT_WRITE(pin, LOW); - #endif - } - } - - void libServo::pauseSoftPWM() { // detach - timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0); - timer_pause(tdev); - pwmSetDuty(0); - } - -#else - - bool libServo::setupSoftPWM(const int32_t inPin) { return false; } - void libServo::pwmSetDuty(const uint16_t duty_cycle) {} - void libServo::pauseSoftPWM() {} - -#endif - -#endif // HAS_SERVOS - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/Servo.h b/src/HAL/STM32F1/Servo.h deleted file mode 100644 index 745a1c9..0000000 --- a/src/HAL/STM32F1/Servo.h +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// Pin number of unattached pins -#define NOT_ATTACHED (-1) -#define INVALID_SERVO 255 - -#ifndef MAX_SERVOS - #define MAX_SERVOS 3 -#endif - -#define SERVO_DEFAULT_MIN_PW 544 -#define SERVO_DEFAULT_MAX_PW 2400 -#define SERVO_DEFAULT_MIN_ANGLE 0 -#define SERVO_DEFAULT_MAX_ANGLE 180 - -class libServo; -typedef libServo hal_servo_t; - -class libServo { - public: - libServo(); - bool attach(const int32_t pin, const int32_t minAngle=SERVO_DEFAULT_MIN_ANGLE, const int32_t maxAngle=SERVO_DEFAULT_MAX_ANGLE); - bool attached() const { return pin != NOT_ATTACHED; } - bool detach(); - void move(const int32_t value); - int32_t read() const; - private: - void servoWrite(uint8_t pin, const uint16_t duty_cycle); - - uint8_t servoIndex; // index into the channel data for this servo - int32_t pin = NOT_ATTACHED; - int32_t minAngle; - int32_t maxAngle; - int32_t angle; - - bool setupSoftPWM(const int32_t pin); - void pauseSoftPWM(); - void pwmSetDuty(const uint16_t duty_cycle); -}; diff --git a/src/HAL/STM32F1/build_flags.py b/src/HAL/STM32F1/build_flags.py deleted file mode 100644 index 970ca8b..0000000 --- a/src/HAL/STM32F1/build_flags.py +++ /dev/null @@ -1,56 +0,0 @@ -from __future__ import print_function -import sys - -#dynamic build flags for generic compile options -if __name__ == "__main__": - args = " ".join([ "-std=gnu++14", - "-Os", - "-mcpu=cortex-m3", - "-mthumb", - - "-fsigned-char", - "-fno-move-loop-invariants", - "-fno-strict-aliasing", - "-fsingle-precision-constant", - - "--specs=nano.specs", - "--specs=nosys.specs", - - "-IMarlin/src/HAL/STM32F1", - - "-MMD", - "-MP", - "-DTARGET_STM32F1" - ]) - - for i in range(1, len(sys.argv)): - args += " " + sys.argv[i] - - print(args) - -# extra script for linker options -else: - import pioutil - if pioutil.is_pio_build(): - from SCons.Script import DefaultEnvironment - env = DefaultEnvironment() - env.Append( - ARFLAGS=["rcs"], - - ASFLAGS=["-x", "assembler-with-cpp"], - - CXXFLAGS=[ - "-fabi-version=0", - "-fno-use-cxa-atexit", - "-fno-threadsafe-statics" - ], - LINKFLAGS=[ - "-Os", - "-mcpu=cortex-m3", - "-ffreestanding", - "-mthumb", - "--specs=nano.specs", - "--specs=nosys.specs", - "-u_printf_float", - ], - ) diff --git a/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp b/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp deleted file mode 100644 index 26ea1ea..0000000 --- a/src/HAL/STM32F1/dogm/u8g_com_stm32duino_swspi.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef __STM32F1__ - -#include "../../../inc/MarlinConfig.h" - -#if BOTH(HAS_MARLINUI_U8GLIB, FORCE_SOFT_SPI) - -#include -#include "../../shared/HAL_SPI.h" - -#ifndef LCD_SPI_SPEED - #define LCD_SPI_SPEED SPI_FULL_SPEED // Fastest - //#define LCD_SPI_SPEED SPI_QUARTER_SPEED // Slower -#endif - -static uint8_t SPI_speed = LCD_SPI_SPEED; - -static inline uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { - LOOP_L_N(i, 8) { - if (spi_speed == 0) { - WRITE(DOGLCD_MOSI, !!(b & 0x80)); - WRITE(DOGLCD_SCK, HIGH); - b <<= 1; - if (miso_pin >= 0 && READ(miso_pin)) b |= 1; - WRITE(DOGLCD_SCK, LOW); - } - else { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - LOOP_L_N(j, spi_speed) - WRITE(DOGLCD_MOSI, state); - - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - WRITE(DOGLCD_SCK, HIGH); - - b <<= 1; - if (miso_pin >= 0 && READ(miso_pin)) b |= 1; - - LOOP_L_N(j, spi_speed) - WRITE(DOGLCD_SCK, LOW); - } - } - return b; -} - -static inline uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t miso_pin=-1) { - LOOP_L_N(i, 8) { - const uint8_t state = (b & 0x80) ? HIGH : LOW; - if (spi_speed == 0) { - WRITE(DOGLCD_SCK, LOW); - WRITE(DOGLCD_MOSI, state); - WRITE(DOGLCD_MOSI, state); // need some setup time - WRITE(DOGLCD_SCK, HIGH); - } - else { - LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) - WRITE(DOGLCD_SCK, LOW); - - LOOP_L_N(j, spi_speed) - WRITE(DOGLCD_MOSI, state); - - LOOP_L_N(j, spi_speed) - WRITE(DOGLCD_SCK, HIGH); - } - b <<= 1; - if (miso_pin >= 0 && READ(miso_pin)) b |= 1; - } - return b; -} - -static void u8g_sw_spi_HAL_STM32F1_shift_out(uint8_t val) { - #if ENABLED(FYSETC_MINI_12864) - swSpiTransfer_mode_3(val, SPI_speed); - #else - swSpiTransfer_mode_0(val, SPI_speed); - #endif -} - -static uint8_t swSpiInit(const uint8_t spi_speed) { - #if PIN_EXISTS(LCD_RESET) - SET_OUTPUT(LCD_RESET_PIN); - #endif - SET_OUTPUT(DOGLCD_A0); - OUT_WRITE(DOGLCD_SCK, LOW); - OUT_WRITE(DOGLCD_MOSI, LOW); - OUT_WRITE(DOGLCD_CS, HIGH); - return spi_speed; -} - -uint8_t u8g_com_HAL_STM32F1_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { - switch (msg) { - case U8G_COM_MSG_INIT: - SPI_speed = swSpiInit(LCD_SPI_SPEED); - break; - - case U8G_COM_MSG_STOP: - break; - - case U8G_COM_MSG_RESET: - #if PIN_EXISTS(LCD_RESET) - WRITE(LCD_RESET_PIN, arg_val); - #endif - break; - - case U8G_COM_MSG_CHIP_SELECT: - #if ENABLED(FYSETC_MINI_12864) // This LCD SPI is running mode 3 while SD card is running mode 0 - if (arg_val) { // SCK idle state needs to be set to the proper idle state before - // the next chip select goes active - WRITE(DOGLCD_SCK, HIGH); // Set SCK to mode 3 idle state before CS goes active - WRITE(DOGLCD_CS, LOW); - } - else { - WRITE(DOGLCD_CS, HIGH); - WRITE(DOGLCD_SCK, LOW); // Set SCK to mode 0 idle state after CS goes inactive - } - #else - WRITE(DOGLCD_CS, !arg_val); - #endif - break; - - case U8G_COM_MSG_WRITE_BYTE: - u8g_sw_spi_HAL_STM32F1_shift_out(arg_val); - break; - - case U8G_COM_MSG_WRITE_SEQ: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_sw_spi_HAL_STM32F1_shift_out(*ptr++); - arg_val--; - } - } break; - - case U8G_COM_MSG_WRITE_SEQ_P: { - uint8_t *ptr = (uint8_t *)arg_ptr; - while (arg_val > 0) { - u8g_sw_spi_HAL_STM32F1_shift_out(u8g_pgm_read(ptr)); - ptr++; - arg_val--; - } - } break; - - case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ - WRITE(DOGLCD_A0, arg_val); - break; - } - return 1; -} - -#endif // HAS_MARLINUI_U8GLIB && FORCE_SOFT_SPI -#endif // STM32F1 diff --git a/src/HAL/STM32F1/eeprom_bl24cxx.cpp b/src/HAL/STM32F1/eeprom_bl24cxx.cpp deleted file mode 100644 index 4e25bc6..0000000 --- a/src/HAL/STM32F1/eeprom_bl24cxx.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __STM32F1__ - -/** - * PersistentStore for Arduino-style EEPROM interface - * with simple implementations supplied by Marlin. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(IIC_BL24CXX_EEPROM) - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -// -// PersistentStore -// - -#ifndef MARLIN_EEPROM_SIZE - #error "MARLIN_EEPROM_SIZE is required for IIC_BL24CXX_EEPROM." -#endif - -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { eeprom_init(); return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t v = *value; - uint8_t * const p = (uint8_t * const)pos; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t * const p = (uint8_t * const)pos; - uint8_t c = eeprom_read_byte(p); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // IIC_BL24CXX_EEPROM -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/eeprom_flash.cpp b/src/HAL/STM32F1/eeprom_flash.cpp deleted file mode 100644 index e7d9dd2..0000000 --- a/src/HAL/STM32F1/eeprom_flash.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * persistent_store_flash.cpp - * HAL for stm32duino and compatible (STM32F1) - * Implementation of EEPROM settings in SDCard - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(FLASH_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" - -#include -#include - -// Store settings in the last two pages -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE ((EEPROM_PAGE_SIZE) * 2) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -static uint8_t ram_eeprom[MARLIN_EEPROM_SIZE] __attribute__((aligned(4))) = {0}; -static bool eeprom_dirty = false; - -bool PersistentStore::access_start() { - const uint32_t *source = reinterpret_cast(EEPROM_PAGE0_BASE); - uint32_t *destination = reinterpret_cast(ram_eeprom); - - static_assert(0 == (MARLIN_EEPROM_SIZE) % 4, "MARLIN_EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe - constexpr size_t eeprom_size_u32 = (MARLIN_EEPROM_SIZE) / 4; - - for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source) - *destination = *source; - - eeprom_dirty = false; - return true; -} - -bool PersistentStore::access_finish() { - - if (eeprom_dirty) { - FLASH_Status status; - - // Instead of erasing all (both) pages, maybe in the loop we check what page we are in, and if the - // data has changed in that page. We then erase the first time we "detect" a change. In theory, if - // nothing changed in a page, we wouldn't need to erase/write it. - // Or, instead of checking at this point, turn eeprom_dirty into an array of bool the size of number - // of pages. Inside write_data, we set the flag to true at that time if something in that - // page changes...either way, something to look at later. - FLASH_Unlock(); - - #define ACCESS_FINISHED(TF) { FLASH_Lock(); eeprom_dirty = false; return TF; } - - status = FLASH_ErasePage(EEPROM_PAGE0_BASE); - if (status != FLASH_COMPLETE) ACCESS_FINISHED(true); - status = FLASH_ErasePage(EEPROM_PAGE1_BASE); - if (status != FLASH_COMPLETE) ACCESS_FINISHED(true); - - const uint16_t *source = reinterpret_cast(ram_eeprom); - for (size_t i = 0; i < MARLIN_EEPROM_SIZE; i += 2, ++source) { - if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE) - ACCESS_FINISHED(false); - } - - ACCESS_FINISHED(true); - } - - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - for (size_t i = 0; i < size; ++i) ram_eeprom[pos + i] = value[i]; - eeprom_dirty = true; - crc16(crc, value, size); - pos += size; - return false; // return true for any error -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) { - const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos]; - if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i]; - crc16(crc, buff, size); - pos += size; - return false; // return true for any error -} - -#endif // FLASH_EEPROM_EMULATION -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/eeprom_if_iic.cpp b/src/HAL/STM32F1/eeprom_if_iic.cpp deleted file mode 100644 index 78b7af0..0000000 --- a/src/HAL/STM32F1/eeprom_if_iic.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Platform-independent Arduino functions for I2C EEPROM. - * Enable USE_SHARED_EEPROM if not supplied by the framework. - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(IIC_BL24CXX_EEPROM) - -#include "../../libs/BL24CXX.h" -#include "../shared/eeprom_if.h" - -void eeprom_init() { BL24CXX::init(); } - -// ------------------------ -// Public functions -// ------------------------ - -void eeprom_write_byte(uint8_t *pos, uint8_t value) { - const unsigned eeprom_address = (unsigned)pos; - return BL24CXX::writeOneByte(eeprom_address, value); -} - -uint8_t eeprom_read_byte(uint8_t *pos) { - const unsigned eeprom_address = (unsigned)pos; - return BL24CXX::readOneByte(eeprom_address); -} - -#endif // IIC_BL24CXX_EEPROM -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/eeprom_sdcard.cpp b/src/HAL/STM32F1/eeprom_sdcard.cpp deleted file mode 100644 index d608cce..0000000 --- a/src/HAL/STM32F1/eeprom_sdcard.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - * Implementation of EEPROM settings in SD Card - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SDCARD_EEPROM_EMULATION) - -#include "../shared/eeprom_api.h" -#include "../../sd/cardreader.h" - -#define EEPROM_FILENAME "eeprom.dat" - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE 0x1000 // 4KB -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -#define _ALIGN(x) __attribute__ ((aligned(x))) // SDIO uint32_t* compat. -static char _ALIGN(4) HAL_eeprom_data[MARLIN_EEPROM_SIZE]; - -bool PersistentStore::access_start() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - if (!file.open(&root, EEPROM_FILENAME, O_RDONLY)) - return true; // false aborts the save - - int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE); - if (bytes_read < 0) return false; - for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++) - HAL_eeprom_data[bytes_read] = 0xFF; - file.close(); - return true; -} - -bool PersistentStore::access_finish() { - if (!card.isMounted()) return false; - - SdFile file, root = card.getroot(); - int bytes_written = 0; - if (file.open(&root, EEPROM_FILENAME, O_CREAT | O_WRITE | O_TRUNC)) { - bytes_written = file.write(HAL_eeprom_data, MARLIN_EEPROM_SIZE); - file.close(); - } - return (bytes_written == MARLIN_EEPROM_SIZE); -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - for (size_t i = 0; i < size; i++) - HAL_eeprom_data[pos + i] = value[i]; - crc16(crc, value, size); - pos += size; - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) { - for (size_t i = 0; i < size; i++) { - uint8_t c = HAL_eeprom_data[pos + i]; - if (writing) value[i] = c; - crc16(crc, &c, 1); - } - pos += size; - return false; -} - -#endif // SDCARD_EEPROM_EMULATION -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/eeprom_wired.cpp b/src/HAL/STM32F1/eeprom_wired.cpp deleted file mode 100644 index bc48eef..0000000 --- a/src/HAL/STM32F1/eeprom_wired.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL PersistentStore for STM32F1 - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -#include "../shared/eeprom_if.h" -#include "../shared/eeprom_api.h" - -#ifndef MARLIN_EEPROM_SIZE - #error "MARLIN_EEPROM_SIZE is required for I2C / SPI EEPROM." -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::access_start() { - eeprom_init(); - #if ENABLED(SPI_EEPROM) - #if SPI_CHAN_EEPROM1 == 1 - SET_OUTPUT(BOARD_SPI1_SCK_PIN); - SET_OUTPUT(BOARD_SPI1_MOSI_PIN); - SET_INPUT(BOARD_SPI1_MISO_PIN); - SET_OUTPUT(SPI_EEPROM1_CS_PIN); - #endif - spiInit(0); - #endif - return true; -} - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing && value) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/endstop_interrupts.h b/src/HAL/STM32F1/endstop_interrupts.h deleted file mode 100644 index 4d7edb9..0000000 --- a/src/HAL/STM32F1/endstop_interrupts.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop interrupts for Libmaple STM32F1 based targets. - * - * On STM32F, all pins support external interrupt capability. - * Any pin can be used for external interrupts, but there are some restrictions. - * At most 16 different external interrupts can be used at one time. - * Further, you can’t just pick any 16 pins to use. This is because every pin on the STM32 - * connects to what is called an EXTI line, and only one pin per EXTI line can be used for external interrupts at a time - * Check the Reference Manual of the MCU to confirm which line is used by each pin - */ - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(P, endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/STM32F1/fast_pwm.cpp b/src/HAL/STM32F1/fast_pwm.cpp deleted file mode 100644 index 297804a..0000000 --- a/src/HAL/STM32F1/fast_pwm.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#include - -#define NR_TIMERS TERN(STM32_XL_DENSITY, 14, 8) // Maple timers, 14 for STM32_XL_DENSITY (F/G chips), 8 for HIGH density (C D E) - -static uint16_t timer_freq[NR_TIMERS]; - -inline uint8_t timer_and_index_for_pin(const pin_t pin, timer_dev **timer_ptr) { - *timer_ptr = PIN_MAP[pin].timer_device; - for (uint8_t i = 0; i < NR_TIMERS; i++) if (*timer_ptr == HAL_get_timer_dev(i)) - return i; - return 0; -} - -void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { - const uint16_t duty = invert ? v_size - v : v; - if (PWM_PIN(pin)) { - timer_dev *timer; UNUSED(timer); - if (timer_freq[timer_and_index_for_pin(pin, &timer)] == 0) - set_pwm_frequency(pin, PWM_FREQUENCY); - const uint8_t channel = PIN_MAP[pin].timer_channel; - timer_set_compare(timer, channel, duty); - timer_set_mode(timer, channel, TIMER_PWM); // PWM Output Mode - } - else { - pinMode(pin, OUTPUT); - digitalWrite(pin, duty < v_size / 2 ? LOW : HIGH); - } -} - -void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { - if (!PWM_PIN(pin)) return; // Don't proceed if no hardware timer - - timer_dev *timer; UNUSED(timer); - timer_freq[timer_and_index_for_pin(pin, &timer)] = f_desired; - - // Protect used timers - if (timer == HAL_get_timer_dev(MF_TIMER_TEMP)) return; - if (timer == HAL_get_timer_dev(MF_TIMER_STEP)) return; - #if MF_TIMER_PULSE != MF_TIMER_STEP - if (timer == HAL_get_timer_dev(MF_TIMER_PULSE)) return; - #endif - - if (!(timer->regs.bas->SR & TIMER_CR1_CEN)) // Ensure the timer is enabled - timer_init(timer); - - const uint8_t channel = PIN_MAP[pin].timer_channel; - timer_set_mode(timer, channel, TIMER_PWM); - // Preload (resolution) cannot be equal to duty of 255 otherwise it may not result in digital off or on. - uint16_t preload = 254; - int32_t prescaler = (HAL_TIMER_RATE) / (preload + 1) / f_desired - 1; - if (prescaler > 65535) { // For low frequencies increase prescaler - prescaler = 65535; - preload = (HAL_TIMER_RATE) / (prescaler + 1) / f_desired - 1; - } - if (prescaler < 0) return; // Too high frequency - timer_set_reload(timer, preload); - timer_set_prescaler(timer, prescaler); -} - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/fastio.h b/src/HAL/STM32F1/fastio.h deleted file mode 100644 index e75254d..0000000 --- a/src/HAL/STM32F1/fastio.h +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O interfaces for STM32F1 - * These use GPIO functions instead of Direct Port Manipulation, as on AVR. - */ - -#include - -#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & _BV32(PIN_MAP[IO].gpio_bit) ? HIGH : LOW) -#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = _BV32(PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16)) -#define TOGGLE(IO) TBI32(PIN_MAP[IO].gpio_device->regs->ODR, PIN_MAP[IO].gpio_bit) - -#define _GET_MODE(IO) gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit) -#define _SET_MODE(IO,M) gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M) -#define _SET_OUTPUT(IO) _SET_MODE(IO, GPIO_OUTPUT_PP) -#define _SET_OUTPUT_OD(IO) _SET_MODE(IO, GPIO_OUTPUT_OD) - -#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) -#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0) - -#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING) -#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU) -#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, GPIO_INPUT_PD) -#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW) -#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0) -#define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN) - -#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD) -#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD) - -#define PWM_PIN(IO) !!PIN_MAP[IO].timer_device - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -// -// Pins Definitions -// -#define PA0 0x00 -#define PA1 0x01 -#define PA2 0x02 -#define PA3 0x03 -#define PA4 0x04 -#define PA5 0x05 -#define PA6 0x06 -#define PA7 0x07 -#define PA8 0x08 -#define PA9 0x09 -#define PA10 0x0A -#define PA11 0x0B -#define PA12 0x0C -#define PA13 0x0D -#define PA14 0x0E -#define PA15 0x0F - -#define PB0 0x10 -#define PB1 0x11 -#define PB2 0x12 -#define PB3 0x13 -#define PB4 0x14 -#define PB5 0x15 -#define PB6 0x16 -#define PB7 0x17 // 36 pins (F103T) -#define PB8 0x18 -#define PB9 0x19 -#define PB10 0x1A -#define PB11 0x1B -#define PB12 0x1C -#define PB13 0x1D -#define PB14 0x1E -#define PB15 0x1F - -#if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8) - #define PC13 0x20 - #define PC14 0x21 - #define PC15 0x22 -#else - #define PC0 0x20 - #define PC1 0x21 - #define PC2 0x22 - #define PC3 0x23 - #define PC4 0x24 - #define PC5 0x25 - #define PC6 0x26 - #define PC7 0x27 - #define PC8 0x28 - #define PC9 0x29 - #define PC10 0x2A - #define PC11 0x2B - #define PC12 0x2C - #define PC13 0x2D - #define PC14 0x2E - #define PC15 0x2F -#endif - -#define PD0 0x30 -#define PD1 0x31 -#define PD2 0x32 // 64 pins (F103R) -#define PD3 0x33 -#define PD4 0x34 -#define PD5 0x35 -#define PD6 0x36 -#define PD7 0x37 -#define PD8 0x38 -#define PD9 0x39 -#define PD10 0x3A -#define PD11 0x3B -#define PD12 0x3C -#define PD13 0x3D -#define PD14 0x3E -#define PD15 0x3F - -#define PE0 0x40 -#define PE1 0x41 -#define PE2 0x42 -#define PE3 0x43 -#define PE4 0x44 -#define PE5 0x45 -#define PE6 0x46 -#define PE7 0x47 -#define PE8 0x48 -#define PE9 0x49 -#define PE10 0x4A -#define PE11 0x4B -#define PE12 0x4C -#define PE13 0x4D -#define PE14 0x4E -#define PE15 0x4F // 100 pins (F103V) - -#define PF0 0x50 -#define PF1 0x51 -#define PF2 0x52 -#define PF3 0x53 -#define PF4 0x54 -#define PF5 0x55 -#define PF6 0x56 -#define PF7 0x57 -#define PF8 0x58 -#define PF9 0x59 -#define PF10 0x5A -#define PF11 0x5B -#define PF12 0x5C -#define PF13 0x5D -#define PF14 0x5E -#define PF15 0x5F - -#define PG0 0x60 -#define PG1 0x61 -#define PG2 0x62 -#define PG3 0x63 -#define PG4 0x64 -#define PG5 0x65 -#define PG6 0x66 -#define PG7 0x67 -#define PG8 0x68 -#define PG9 0x69 -#define PG10 0x6A -#define PG11 0x6B -#define PG12 0x6C -#define PG13 0x6D -#define PG14 0x6E -#define PG15 0x6F // 144 pins (F103Z) diff --git a/src/HAL/STM32F1/inc/Conditionals_LCD.h b/src/HAL/STM32F1/inc/Conditionals_LCD.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/STM32F1/inc/Conditionals_LCD.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/STM32F1/inc/Conditionals_adv.h b/src/HAL/STM32F1/inc/Conditionals_adv.h deleted file mode 100644 index 0fe7924..0000000 --- a/src/HAL/STM32F1/inc/Conditionals_adv.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef USE_USB_COMPOSITE - //#warning "SD_CHECK_AND_RETRY isn't needed with USE_USB_COMPOSITE." - #undef SD_CHECK_AND_RETRY - #if DISABLED(NO_SD_HOST_DRIVE) - #define HAS_SD_HOST_DRIVE 1 - #endif -#endif diff --git a/src/HAL/STM32F1/inc/Conditionals_post.h b/src/HAL/STM32F1/inc/Conditionals_post.h deleted file mode 100644 index 656fbe1..0000000 --- a/src/HAL/STM32F1/inc/Conditionals_post.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation -#if USE_FALLBACK_EEPROM - #define SDCARD_EEPROM_EMULATION -#elif EITHER(I2C_EEPROM, SPI_EEPROM) - #define USE_SHARED_EEPROM 1 -#endif - -// Allow SDSUPPORT to be disabled -#if DISABLED(SDSUPPORT) - #undef SDIO_SUPPORT -#endif diff --git a/src/HAL/STM32F1/inc/SanityCheck.h b/src/HAL/STM32F1/inc/SanityCheck.h deleted file mode 100644 index fe8f6e0..0000000 --- a/src/HAL/STM32F1/inc/SanityCheck.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test STM32F1-specific configuration values for errors at compile-time. - */ - -#if ENABLED(SDCARD_EEPROM_EMULATION) && DISABLED(SDSUPPORT) - #undef SDCARD_EEPROM_EMULATION // Avoid additional error noise - #if USE_FALLBACK_EEPROM - #warning "EEPROM type not specified. Fallback is SDCARD_EEPROM_EMULATION." - #endif - #error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation." -#endif - -#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on the STM32F1 platform." -#elif ENABLED(SERIAL_STATS_DROPPED_RX) - #error "SERIAL_STATS_DROPPED_RX is not supported on the STM32F1 platform." -#endif - -#if ENABLED(NEOPIXEL_LED) && DISABLED(FYSETC_MINI_12864_2_1) - #error "NEOPIXEL_LED (Adafruit NeoPixel) is not supported for HAL/STM32F1. Comment out this line to proceed at your own risk!" -#endif - -// Emergency Parser needs at least one serial with HardwareSerial or USBComposite. -// The USBSerial maple don't allow any hook to implement EMERGENCY_PARSER. -// And copy all USBSerial code to marlin space to support EMERGENCY_PARSER, when we have another options, don't worth it. -#if ENABLED(EMERGENCY_PARSER) && !defined(USE_USB_COMPOSITE) && ((SERIAL_PORT == -1 && !defined(SERIAL_PORT_2)) || (SERIAL_PORT_2 == -1 && !defined(SERIAL_PORT))) - #error "EMERGENCY_PARSER is only supported by HardwareSerial or USBComposite in HAL/STM32F1." -#endif diff --git a/src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf b/src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf deleted file mode 100644 index e4221b7..0000000 --- a/src/HAL/STM32F1/maple_win_usb_driver/maple_serial.inf +++ /dev/null @@ -1,56 +0,0 @@ -; -; STMicroelectronics Communication Device Class driver installation file -; (C)2006 Copyright STMicroelectronics -; - -[Version] -Signature="$Windows NT$" -Class=Ports -ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} -Provider=%STM% -LayoutFile=layout.inf - -[Manufacturer] -%MFGNAME%=VirComDevice,NT,NTamd64 - -[DestinationDirs] -DefaultDestDir = 12 - -[VirComDevice.NT] -%DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 -%DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 - -[VirComDevice.NTamd64] -%DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 -%DESCRIPTION%=DriverInstall,USB\VID_1EAF&PID_0029&MI_01 - -[DriverInstall.NT] -Include=mdmcpq.inf -CopyFiles=FakeModemCopyFileSection -AddReg=DriverInstall.NT.AddReg - -[DriverInstall.NT.AddReg] -HKR,,DevLoader,,*ntkern -HKR,,NTMPDriver,,usbser.sys -HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" - -[DriverInstall.NT.Services] -AddService=usbser, 0x00000002, DriverServiceInst - -[DriverServiceInst] -DisplayName=%SERVICE% -ServiceType=1 -StartType=3 -ErrorControl=1 -ServiceBinary=%12%\usbser.sys - -;------------------------------------------------------------------------------ -; String Definitions -;------------------------------------------------------------------------------ - - -[Strings] -STM = "LeafLabs" -MFGNAME = "LeafLabs" -DESCRIPTION = "Maple R3" -SERVICE = "USB Virtual COM port" diff --git a/src/HAL/STM32F1/msc_sd.cpp b/src/HAL/STM32F1/msc_sd.cpp deleted file mode 100644 index f490c83..0000000 --- a/src/HAL/STM32F1/msc_sd.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_SD_HOST_DRIVE - -#include "msc_sd.h" -#include "SPI.h" -#include "usb_reg_map.h" - -#define PRODUCT_ID 0x29 - -USBMassStorage MarlinMSC; -Serial1Class MarlinCompositeSerial(true); - -#include "../../inc/MarlinConfig.h" - -#if SD_CONNECTION_IS(ONBOARD) - - #include "onboard_sd.h" - - static bool MSC_Write(const uint8_t *writebuff, uint32_t startSector, uint16_t numSectors) { - return (disk_write(0, writebuff, startSector, numSectors) == RES_OK); - } - static bool MSC_Read(uint8_t *readbuff, uint32_t startSector, uint16_t numSectors) { - return (disk_read(0, readbuff, startSector, numSectors) == RES_OK); - } - -#endif - -#if ENABLED(EMERGENCY_PARSER) - - // The original callback is not called (no way to retrieve address). - // That callback detects a special STM32 reset sequence: this functionality is not essential - // as M997 achieves the same. - void my_rx_callback(unsigned int, void*) { - // max length of 16 is enough to contain all emergency commands - uint8 buf[16]; - - //rx is usbSerialPart.endpoints[2] - uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address); - uint32 total = composite_cdcacm_data_available(); - - if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf))) - return; - - // cannot get character by character due to bug in composite_cdcacm_peek_ex - len = composite_cdcacm_peek(buf, total); - - for (uint32 i = 0; i < len; i++) - emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]); - } - -#endif - -void MSC_SD_init() { - USBComposite.setProductId(PRODUCT_ID); - // Just set MarlinCompositeSerial enabled to true - // because when MarlinCompositeSerial.begin() is used in setup() - // it clears all USBComposite devices. - MarlinCompositeSerial.begin(); - USBComposite.end(); - USBComposite.clear(); - // Set api and register mass storage - #if SD_CONNECTION_IS(ONBOARD) - uint32_t cardSize; - if (disk_initialize(0) == RES_OK) { - if (disk_ioctl(0, GET_SECTOR_COUNT, (void *)(&cardSize)) == RES_OK) { - MarlinMSC.setDriveData(0, cardSize, MSC_Read, MSC_Write); - MarlinMSC.registerComponent(); - } - } - #endif - // Register composite Serial - MarlinCompositeSerial.registerComponent(); - USBComposite.begin(); - #if ENABLED(EMERGENCY_PARSER) - composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback); - #endif -} - -#endif // HAS_SD_HOST_DRIVE -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/msc_sd.h b/src/HAL/STM32F1/msc_sd.h deleted file mode 100644 index f4636bd..0000000 --- a/src/HAL/STM32F1/msc_sd.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -#include "../../inc/MarlinConfigPre.h" -#include "../../core/serial_hook.h" - -extern USBMassStorage MarlinMSC; -extern Serial1Class MarlinCompositeSerial; - -void MSC_SD_init(); diff --git a/src/HAL/STM32F1/onboard_sd.cpp b/src/HAL/STM32F1/onboard_sd.cpp deleted file mode 100644 index a3d8dcb..0000000 --- a/src/HAL/STM32F1/onboard_sd.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/** - * STM32F1: MMCv3/SDv1/SDv2 (SPI mode) control module - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] - * Copyright (C) 2015, ChaN, all right reserved. - * - * This software is a free software and there is NO WARRANTY. - * No restriction on use. You can use, modify and redistribute it for - * personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. - * Redistributions of source code must retain the above copyright notice. - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -#if SD_CONNECTION_IS(ONBOARD) - -#include "onboard_sd.h" -#include "SPI.h" -#include "fastio.h" - -#ifndef ONBOARD_SPI_DEVICE - #define ONBOARD_SPI_DEVICE SPI_DEVICE -#endif - -#if HAS_SD_HOST_DRIVE - #define ONBOARD_SD_SPI SPI -#else - SPIClass OnboardSPI(ONBOARD_SPI_DEVICE); - #define ONBOARD_SD_SPI OnboardSPI -#endif - -#if ONBOARD_SPI_DEVICE == 1 - #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_4 -#else - #define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2 -#endif - -#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN - #define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) // Set OnboardSPI cs low - #define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) // Set OnboardSPI cs high -#else - #define CS_LOW() - #define CS_HIGH() -#endif - -#define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX) -#define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256) - -/*-------------------------------------------------------------------------- - Module Private Functions ----------------------------------------------------------------------------*/ - -/* MMC/SD command */ -#define CMD0 (0) // GO_IDLE_STATE -#define CMD1 (1) // SEND_OP_COND (MMC) -#define ACMD41 (0x80+41) // SEND_OP_COND (SDC) -#define CMD8 (8) // SEND_IF_COND -#define CMD9 (9) // SEND_CSD -#define CMD10 (10) // SEND_CID -#define CMD12 (12) // STOP_TRANSMISSION -#define ACMD13 (0x80+13) // SD_STATUS (SDC) -#define CMD16 (16) // SET_BLOCKLEN -#define CMD17 (17) // READ_SINGLE_BLOCK -#define CMD18 (18) // READ_MULTIPLE_BLOCK -#define CMD23 (23) // SET_BLOCK_COUNT (MMC) -#define ACMD23 (0x80+23) // SET_WR_BLK_ERASE_COUNT (SDC) -#define CMD24 (24) // WRITE_BLOCK -#define CMD25 (25) // WRITE_MULTIPLE_BLOCK -#define CMD32 (32) // ERASE_ER_BLK_START -#define CMD33 (33) // ERASE_ER_BLK_END -#define CMD38 (38) // ERASE -#define CMD48 (48) // READ_EXTR_SINGLE -#define CMD49 (49) // WRITE_EXTR_SINGLE -#define CMD55 (55) // APP_CMD -#define CMD58 (58) // READ_OCR - -static volatile DSTATUS Stat = STA_NOINIT; // Physical drive status -static volatile UINT timeout; -static BYTE CardType; // Card type flags - -/*-----------------------------------------------------------------------*/ -/* Send/Receive data to the MMC (Platform dependent) */ -/*-----------------------------------------------------------------------*/ - -/* Exchange a byte */ -static BYTE xchg_spi ( - BYTE dat // Data to send -) { - BYTE returnByte = ONBOARD_SD_SPI.transfer(dat); - return returnByte; -} - -/* Receive multiple byte */ -static void rcvr_spi_multi ( - BYTE *buff, // Pointer to data buffer - UINT btr // Number of bytes to receive (16, 64 or 512) -) { - ONBOARD_SD_SPI.dmaTransfer(0, const_cast(buff), btr); -} - -#if _DISKIO_WRITE - - // Send multiple bytes - static void xmit_spi_multi ( - const BYTE *buff, // Pointer to the data - UINT btx // Number of bytes to send (multiple of 16) - ) { - ONBOARD_SD_SPI.dmaSend(const_cast(buff), btx); - } - -#endif // _DISKIO_WRITE - -/*-----------------------------------------------------------------------*/ -/* Wait for card ready */ -/*-----------------------------------------------------------------------*/ - -static int wait_ready ( // 1:Ready, 0:Timeout - UINT wt // Timeout [ms] -) { - BYTE d; - timeout = millis() + wt; - do { - d = xchg_spi(0xFF); - // This loop takes a while. Insert rot_rdq() here for multitask environment. - } while (d != 0xFF && (timeout > millis())); // Wait for card goes ready or timeout - - return (d == 0xFF) ? 1 : 0; -} - -/*-----------------------------------------------------------------------*/ -/* Deselect card and release SPI */ -/*-----------------------------------------------------------------------*/ - -static void deselect() { - CS_HIGH(); // CS = H - xchg_spi(0xFF); // Dummy clock (force DO hi-z for multiple slave SPI) -} - -/*-----------------------------------------------------------------------*/ -/* Select card and wait for ready */ -/*-----------------------------------------------------------------------*/ - -static int select() { // 1:OK, 0:Timeout - CS_LOW(); // CS = L - xchg_spi(0xFF); // Dummy clock (force DO enabled) - - if (wait_ready(500)) return 1; // Leading busy check: Wait for card ready - - deselect(); // Timeout - return 0; -} - -/*-----------------------------------------------------------------------*/ -/* Control SPI module (Platform dependent) */ -/*-----------------------------------------------------------------------*/ - -// Enable SSP module and attach it to I/O pads -static void sd_power_on() { - ONBOARD_SD_SPI.setModule(ONBOARD_SPI_DEVICE); - ONBOARD_SD_SPI.begin(); - ONBOARD_SD_SPI.setBitOrder(MSBFIRST); - ONBOARD_SD_SPI.setDataMode(SPI_MODE0); - CS_HIGH(); -} - -// Disable SPI function -static void sd_power_off() { - select(); // Wait for card ready - deselect(); -} - -/*-----------------------------------------------------------------------*/ -/* Receive a data packet from the MMC */ -/*-----------------------------------------------------------------------*/ - -static int rcvr_datablock ( // 1:OK, 0:Error - BYTE *buff, // Data buffer - UINT btr // Data block length (byte) -) { - BYTE token; - - timeout = millis() + 200; - do { // Wait for DataStart token in timeout of 200ms - token = xchg_spi(0xFF); - // This loop will take a while. Insert rot_rdq() here for multitask environment. - } while ((token == 0xFF) && (timeout > millis())); - if (token != 0xFE) return 0; // Function fails if invalid DataStart token or timeout - - rcvr_spi_multi(buff, btr); // Store trailing data to the buffer - xchg_spi(0xFF); xchg_spi(0xFF); // Discard CRC - - return 1; // Function succeeded -} - -/*-----------------------------------------------------------------------*/ -/* Send a data packet to the MMC */ -/*-----------------------------------------------------------------------*/ - -#if _DISKIO_WRITE - - static int xmit_datablock( // 1:OK, 0:Failed - const BYTE *buff, // Pointer to 512 byte data to be sent - BYTE token // Token - ) { - BYTE resp; - - if (!wait_ready(500)) return 0; // Leading busy check: Wait for card ready to accept data block - - xchg_spi(token); // Send token - if (token == 0xFD) return 1; // Do not send data if token is StopTran - - xmit_spi_multi(buff, 512); // Data - xchg_spi(0xFF); xchg_spi(0xFF); // Dummy CRC - - resp = xchg_spi(0xFF); // Receive data resp - - return (resp & 0x1F) == 0x05 ? 1 : 0; // Data was accepted or not - - // Busy check is done at next transmission - } - -#endif // _DISKIO_WRITE - -/*-----------------------------------------------------------------------*/ -/* Send a command packet to the MMC */ -/*-----------------------------------------------------------------------*/ - -static BYTE send_cmd( // Return value: R1 resp (bit7==1:Failed to send) - BYTE cmd, // Command index - DWORD arg // Argument -) { - BYTE n, res; - - if (cmd & 0x80) { // Send a CMD55 prior to ACMD - cmd &= 0x7F; - res = send_cmd(CMD55, 0); - if (res > 1) return res; - } - - // Select the card and wait for ready except to stop multiple block read - if (cmd != CMD12) { - deselect(); - if (!select()) return 0xFF; - } - - // Send command packet - xchg_spi(0x40 | cmd); // Start + command index - xchg_spi((BYTE)(arg >> 24)); // Argument[31..24] - xchg_spi((BYTE)(arg >> 16)); // Argument[23..16] - xchg_spi((BYTE)(arg >> 8)); // Argument[15..8] - xchg_spi((BYTE)arg); // Argument[7..0] - n = 0x01; // Dummy CRC + Stop - if (cmd == CMD0) n = 0x95; // Valid CRC for CMD0(0) - if (cmd == CMD8) n = 0x87; // Valid CRC for CMD8(0x1AA) - xchg_spi(n); - - // Receive command response - if (cmd == CMD12) xchg_spi(0xFF); // Discard the following byte when CMD12 - n = 10; // Wait for response (10 bytes max) - do - res = xchg_spi(0xFF); - while ((res & 0x80) && --n); - - return res; // Return received response -} - -/*-------------------------------------------------------------------------- - Public Functions ----------------------------------------------------------------------------*/ - -/*-----------------------------------------------------------------------*/ -/* Initialize disk drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE drv // Physical drive number (0) -) { - BYTE n, cmd, ty, ocr[4]; - - if (drv) return STA_NOINIT; // Supports only drive 0 - sd_power_on(); // Initialize SPI - - if (Stat & STA_NODISK) return Stat; // Is a card existing in the socket? - - FCLK_SLOW(); - for (n = 10; n; n--) xchg_spi(0xFF); // Send 80 dummy clocks - - ty = 0; - if (send_cmd(CMD0, 0) == 1) { // Put the card SPI state - timeout = millis() + 1000; // Initialization timeout = 1 sec - if (send_cmd(CMD8, 0x1AA) == 1) { // Is the catd SDv2? - for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); // Get 32 bit return value of R7 resp - if (ocr[2] == 0x01 && ocr[3] == 0xAA) { // Does the card support 2.7-3.6V? - while ((timeout > millis()) && send_cmd(ACMD41, 1UL << 30)); // Wait for end of initialization with ACMD41(HCS) - if ((timeout > millis()) && send_cmd(CMD58, 0) == 0) { // Check CCS bit in the OCR - for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF); - ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; // Check if the card is SDv2 - } - } - } - else { // Not an SDv2 card - if (send_cmd(ACMD41, 0) <= 1) { // SDv1 or MMCv3? - ty = CT_SD1; cmd = ACMD41; // SDv1 (ACMD41(0)) - } - else { - ty = CT_MMC; cmd = CMD1; // MMCv3 (CMD1(0)) - } - while ((timeout > millis()) && send_cmd(cmd, 0)); // Wait for the card leaves idle state - if (!(timeout > millis()) || send_cmd(CMD16, 512) != 0) // Set block length: 512 - ty = 0; - } - } - CardType = ty; // Card type - deselect(); - - if (ty) { // OK - FCLK_FAST(); // Set fast clock - Stat &= ~STA_NOINIT; // Clear STA_NOINIT flag - } - else { // Failed - sd_power_off(); - Stat = STA_NOINIT; - } - - return Stat; -} - -/*-----------------------------------------------------------------------*/ -/* Get disk status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE drv // Physical drive number (0) -) { - if (drv) return STA_NOINIT; // Supports only drive 0 - return Stat; // Return disk status -} - -/*-----------------------------------------------------------------------*/ -/* Read sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE drv, // Physical drive number (0) - BYTE *buff, // Pointer to the data buffer to store read data - DWORD sector, // Start sector number (LBA) - UINT count // Number of sectors to read (1..128) -) { - BYTE cmd; - - if (drv || !count) return RES_PARERR; // Check parameter - if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready - if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ot BA conversion (byte addressing cards) - FCLK_FAST(); - cmd = count > 1 ? CMD18 : CMD17; // READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK - if (send_cmd(cmd, sector) == 0) { - do { - if (!rcvr_datablock(buff, 512)) break; - buff += 512; - } while (--count); - if (cmd == CMD18) send_cmd(CMD12, 0); // STOP_TRANSMISSION - } - deselect(); - - return count ? RES_ERROR : RES_OK; // Return result -} - -/*-----------------------------------------------------------------------*/ -/* Write sector(s) */ -/*-----------------------------------------------------------------------*/ - -#if _DISKIO_WRITE - - DRESULT disk_write( - BYTE drv, // Physical drive number (0) - const BYTE *buff, // Pointer to the data to write - DWORD sector, // Start sector number (LBA) - UINT count // Number of sectors to write (1..128) - ) { - if (drv || !count) return RES_PARERR; // Check parameter - if (Stat & STA_NOINIT) return RES_NOTRDY; // Check drive status - if (Stat & STA_PROTECT) return RES_WRPRT; // Check write protect - FCLK_FAST(); - if (!(CardType & CT_BLOCK)) sector *= 512; // LBA ==> BA conversion (byte addressing cards) - - if (count == 1) { // Single sector write - if ((send_cmd(CMD24, sector) == 0) // WRITE_BLOCK - && xmit_datablock(buff, 0xFE)) { - count = 0; - } - } - else { // Multiple sector write - if (CardType & CT_SDC) send_cmd(ACMD23, count); // Predefine number of sectors - if (send_cmd(CMD25, sector) == 0) { // WRITE_MULTIPLE_BLOCK - do { - if (!xmit_datablock(buff, 0xFC)) break; - buff += 512; - } while (--count); - if (!xmit_datablock(0, 0xFD)) count = 1; // STOP_TRAN token - } - } - deselect(); - - return count ? RES_ERROR : RES_OK; // Return result - } - -#endif // _DISKIO_WRITE - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous drive controls other than data read/write */ -/*-----------------------------------------------------------------------*/ - -#if _DISKIO_IOCTL - - DRESULT disk_ioctl ( - BYTE drv, // Physical drive number (0) - BYTE cmd, // Control command code - void *buff // Pointer to the conrtol data - ) { - DRESULT res; - BYTE n, csd[16], *ptr = (BYTE *)buff; - DWORD *dp, st, ed, csize; - #if _DISKIO_ISDIO - SDIO_CMD *sdio = buff; - BYTE rc, *buf; - UINT dc; - #endif - - if (drv) return RES_PARERR; // Check parameter - if (Stat & STA_NOINIT) return RES_NOTRDY; // Check if drive is ready - - res = RES_ERROR; - FCLK_FAST(); - switch (cmd) { - case CTRL_SYNC: // Wait for end of internal write process of the drive - if (select()) res = RES_OK; - break; - - case GET_SECTOR_COUNT: // Get drive capacity in unit of sector (DWORD) - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { - if ((csd[0] >> 6) == 1) { // SDC ver 2.00 - csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1; - *(DWORD*)buff = csize << 10; - } - else { // SDC ver 1.XX or MMC ver 3 - n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; - csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; - *(DWORD*)buff = csize << (n - 9); - } - res = RES_OK; - } - break; - - case GET_BLOCK_SIZE: // Get erase block size in unit of sector (DWORD) - if (CardType & CT_SD2) { // SDC ver 2.00 - if (send_cmd(ACMD13, 0) == 0) { // Read SD status - xchg_spi(0xFF); - if (rcvr_datablock(csd, 16)) { // Read partial block - for (n = 64 - 16; n; n--) xchg_spi(0xFF); // Purge trailing data - *(DWORD*)buff = 16UL << (csd[10] >> 4); - res = RES_OK; - } - } - } - else { // SDC ver 1.XX or MMC - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { // Read CSD - if (CardType & CT_SD1) { // SDC ver 1.XX - *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); - } - else { // MMC - *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); - } - res = RES_OK; - } - } - break; - - case CTRL_TRIM: // Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1) - if (!(CardType & CT_SDC)) break; // Check if the card is SDC - if (disk_ioctl(drv, MMC_GET_CSD, csd)) break; // Get CSD - if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break; // Check if sector erase can be applied to the card - dp = (DWORD *)buff; st = dp[0]; ed = dp[1]; // Load sector block - if (!(CardType & CT_BLOCK)) { - st *= 512; ed *= 512; - } - if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) { // Erase sector block - res = RES_OK; // FatFs does not check result of this command - } - break; - - // The following commands are never used by FatFs module - - case MMC_GET_TYPE: // Get MMC/SDC type (BYTE) - *ptr = CardType; - res = RES_OK; - break; - - case MMC_GET_CSD: // Read CSD (16 bytes) - if (send_cmd(CMD9, 0) == 0 && rcvr_datablock(ptr, 16)) { - res = RES_OK; - } - break; - - case MMC_GET_CID: // Read CID (16 bytes) - if (send_cmd(CMD10, 0) == 0 && rcvr_datablock(ptr, 16)) { - res = RES_OK; - } - break; - - case MMC_GET_OCR: // Read OCR (4 bytes) - if (send_cmd(CMD58, 0) == 0) { - for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF); - res = RES_OK; - } - break; - - case MMC_GET_SDSTAT: // Read SD status (64 bytes) - if (send_cmd(ACMD13, 0) == 0) { - xchg_spi(0xFF); - if (rcvr_datablock(ptr, 64)) res = RES_OK; - } - break; - - #if _DISKIO_ISDIO - - case ISDIO_READ: - sdio = buff; - if (send_cmd(CMD48, 0x80000000 | sdio->func << 28 | sdio->addr << 9 | ((sdio->ndata - 1) & 0x1FF)) == 0) { - for (Timer1 = 1000; (rc = xchg_spi(0xFF)) == 0xFF && Timer1; ) ; - if (rc == 0xFE) { - for (buf = sdio->data, dc = sdio->ndata; dc; dc--) *buf++ = xchg_spi(0xFF); - for (dc = 514 - sdio->ndata; dc; dc--) xchg_spi(0xFF); - res = RES_OK; - } - } - break; - case ISDIO_WRITE: - sdio = buff; - if (send_cmd(CMD49, 0x80000000 | sdio->func << 28 | sdio->addr << 9 | ((sdio->ndata - 1) & 0x1FF)) == 0) { - xchg_spi(0xFF); xchg_spi(0xFE); - for (buf = sdio->data, dc = sdio->ndata; dc; dc--) xchg_spi(*buf++); - for (dc = 514 - sdio->ndata; dc; dc--) xchg_spi(0xFF); - if ((xchg_spi(0xFF) & 0x1F) == 0x05) res = RES_OK; - } - break; - case ISDIO_MRITE: - sdio = buff; - if (send_cmd(CMD49, 0x84000000 | sdio->func << 28 | sdio->addr << 9 | sdio->ndata >> 8) == 0) { - xchg_spi(0xFF); xchg_spi(0xFE); - xchg_spi(sdio->ndata); - for (dc = 513; dc; dc--) xchg_spi(0xFF); - if ((xchg_spi(0xFF) & 0x1F) == 0x05) res = RES_OK; - } - break; - - #endif // _DISKIO_ISDIO - - default: res = RES_PARERR; - } - - deselect(); - return res; - } - -#endif // _DISKIO_IOCTL - -#endif // SD_CONNECTION_IS(ONBOARD) -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/onboard_sd.h b/src/HAL/STM32F1/onboard_sd.h deleted file mode 100644 index f228d06..0000000 --- a/src/HAL/STM32F1/onboard_sd.h +++ /dev/null @@ -1,96 +0,0 @@ -/*----------------------------------------------------------------------- -/ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] -/ * Copyright (c) 2019 BigTreeTech [https://github.com/bigtreetech] -/ * Low level disk interface module include file (C)ChaN, 2015 -/-----------------------------------------------------------------------*/ - -#pragma once - -#define _DISKIO_WRITE 1 /* 1: Enable disk_write function */ -#define _DISKIO_IOCTL 1 /* 1: Enable disk_ioctl function */ -#define _DISKIO_ISDIO 0 /* 1: Enable iSDIO control function */ - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -typedef unsigned int UINT; - -/* 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; - - -#if _DISKIO_ISDIO -/* Command structure for iSDIO ioctl command */ -typedef struct { - BYTE func; /* Function number: 0..7 */ - WORD ndata; /* Number of bytes to transfer: 1..512, or mask + data */ - DWORD addr; /* Register address: 0..0x1FFFF */ - void* data; /* Pointer to the data (to be written | read buffer) */ -} SDIO_CMD; -#endif - -/*---------------------------------------*/ -/* 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); -#if _DISKIO_WRITE - DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); -#endif -#if _DISKIO_IOCTL - DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff); -#endif - -/* 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 function */ - -/* 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_FORMAT 5 /* Create physical format on the media */ -#define CTRL_POWER_IDLE 6 /* Put the device idle state */ -#define CTRL_POWER_OFF 7 /* Put the device off state */ -#define CTRL_LOCK 8 /* Lock media removal */ -#define CTRL_UNLOCK 9 /* Unlock media removal */ -#define CTRL_EJECT 10 /* Eject media */ - -/* MMC/SDC specific ioctl command (Not used by FatFs) */ -#define MMC_GET_TYPE 50 /* Get card type */ -#define MMC_GET_CSD 51 /* Get CSD */ -#define MMC_GET_CID 52 /* Get CID */ -#define MMC_GET_OCR 53 /* Get OCR */ -#define MMC_GET_SDSTAT 54 /* Get SD status */ -#define ISDIO_READ 55 /* Read data form SD iSDIO register */ -#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ -#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ - -/* ATA/CF specific ioctl command (Not used by FatFs) */ -#define ATA_GET_REV 60 /* Get F/W revision */ -#define ATA_GET_MODEL 61 /* Get model name */ -#define ATA_GET_SN 62 /* Get serial number */ - -/* MMC card type flags (MMC_GET_TYPE) */ -#define CT_MMC 0x01 /* MMC ver 3 */ -#define CT_SD1 0x02 /* SD ver 1 */ -#define CT_SD2 0x04 /* SD ver 2 */ -#define CT_SDC (CT_SD1|CT_SD2) /* SD */ -#define CT_BLOCK 0x08 /* Block addressing */ diff --git a/src/HAL/STM32F1/pinsDebug.h b/src/HAL/STM32F1/pinsDebug.h deleted file mode 100644 index 7828479..0000000 --- a/src/HAL/STM32F1/pinsDebug.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Support routines for MAPLE_STM32F1 - */ - -/** - * Translation of routines & variables used by pinsDebug.h - */ - -#ifndef BOARD_NR_GPIO_PINS // Only in MAPLE_STM32F1 - #error "Expected BOARD_NR_GPIO_PINS not found" -#endif - -#include "fastio.h" - -extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS]; - -#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS -#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS -#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS) -#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin) -#define pwm_status(pin) PWM_PIN(pin) -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PORT(p) print_port(p) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define MULTI_NAME_PAD 21 // space needed to be pretty if not first name assigned to a pin - -// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities -#ifndef M43_NEVER_TOUCH - #define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX) -#endif - -static int8_t get_pin_mode(pin_t pin) { - return VALID_PIN(pin) ? _GET_MODE(pin) : -1; -} - -static pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) { - if (!VALID_PIN(pin)) return -1; - int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel); - #ifdef NUM_ANALOG_INPUTS - if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = ADCx; - #endif - return pin_t(adc_channel); -} - -static bool IS_ANALOG(pin_t pin) { - if (!VALID_PIN(pin)) return false; - if (PIN_MAP[pin].adc_channel != ADCx) { - #ifdef NUM_ANALOG_INPUTS - if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false; - #endif - return _GET_MODE(pin) == GPIO_INPUT_ANALOG && !M43_NEVER_TOUCH(pin); - } - return false; -} - -static bool GET_PINMODE(const pin_t pin) { - return VALID_PIN(pin) && !IS_INPUT(pin); -} - -static bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) { - const pin_t pin = GET_ARRAY_PIN(array_pin); - return (!IS_ANALOG(pin) - #ifdef NUM_ANALOG_INPUTS - || PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS - #endif - ); -} - -#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density - -static void pwm_details(const pin_t pin) { - if (PWM_PIN(pin)) { - timer_dev * const tdev = PIN_MAP[pin].timer_device; - const uint8_t channel = PIN_MAP[pin].timer_channel; - const char num = ( - #if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) - tdev == &timer8 ? '8' : - tdev == &timer5 ? '5' : - #endif - tdev == &timer4 ? '4' : - tdev == &timer3 ? '3' : - tdev == &timer2 ? '2' : - tdev == &timer1 ? '1' : '?' - ); - char buffer[10]; - sprintf_P(buffer, PSTR(" TIM%c CH%c"), num, ('0' + channel)); - SERIAL_ECHO(buffer); - } -} - -static void print_port(pin_t pin) { - const char port = 'A' + char(pin >> 4); // pin div 16 - const int16_t gbit = PIN_MAP[pin].gpio_bit; - char buffer[8]; - sprintf_P(buffer, PSTR("P%c%hd "), port, gbit); - if (gbit < 10) SERIAL_CHAR(' '); - SERIAL_ECHO(buffer); -} diff --git a/src/HAL/STM32F1/sdio.cpp b/src/HAL/STM32F1/sdio.cpp deleted file mode 100644 index 6e41d2c..0000000 --- a/src/HAL/STM32F1/sdio.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef ARDUINO_ARCH_STM32F1 - -#include - -#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density - -#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY) - -#include "sdio.h" - -SDIO_CardInfoTypeDef SdCard; - -bool SDIO_Init() { - uint32_t count = 0U; - SdCard.CardType = SdCard.CardVersion = SdCard.Class = SdCard.RelCardAdd = SdCard.BlockNbr = SdCard.BlockSize = SdCard.LogBlockNbr = SdCard.LogBlockSize = 0; - - sdio_begin(); - sdio_set_dbus_width(SDIO_CLKCR_WIDBUS_1BIT); - - dma_init(SDIO_DMA_DEV); - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - dma_set_priority(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); - - if (!SDIO_CmdGoIdleState()) return false; - if (!SDIO_CmdGoIdleState()) return false; /* Hotplugged cards tends to miss first CMD0, so give them a second chance. */ - - SdCard.CardVersion = SDIO_CmdOperCond() ? CARD_V2_X : CARD_V1_X; - - do { - if (count++ == SDMMC_MAX_VOLT_TRIAL) return false; - SDIO_CmdAppOperCommand(SdCard.CardVersion == CARD_V2_X ? SDMMC_HIGH_CAPACITY : SDMMC_STD_CAPACITY); - } while ((SDIO_GetResponse(SDIO_RESP1) & 0x80000000) == 0); - - SdCard.CardType = (SDIO_GetResponse(SDIO_RESP1) & SDMMC_HIGH_CAPACITY) ? CARD_SDHC_SDXC : CARD_SDSC; - - if (!SDIO_CmdSendCID()) return false; - if (!SDIO_CmdSetRelAdd(&SdCard.RelCardAdd)) return false; /* Send CMD3 SET_REL_ADDR with argument 0. SD Card publishes its RCA. */ - if (!SDIO_CmdSendCSD(SdCard.RelCardAdd << 16U)) return false; - - SdCard.Class = (SDIO_GetResponse(SDIO_RESP2) >> 20U); - - if (SdCard.CardType == CARD_SDHC_SDXC) { - SdCard.LogBlockNbr = SdCard.BlockNbr = (((SDIO_GetResponse(SDIO_RESP2) & 0x0000003FU) << 26U) | ((SDIO_GetResponse(SDIO_RESP3) & 0xFFFF0000U) >> 6U)) + 1024; - SdCard.LogBlockSize = SdCard.BlockSize = 512U; - } - else { - SdCard.BlockNbr = ((((SDIO_GetResponse(SDIO_RESP2) & 0x000003FFU) << 2U ) | ((SDIO_GetResponse(SDIO_RESP3) & 0xC0000000U) >> 30U)) + 1U) * (4U << ((SDIO_GetResponse(SDIO_RESP3) & 0x00038000U) >> 15U)); - SdCard.BlockSize = 1U << ((SDIO_GetResponse(SDIO_RESP2) >> 16) & 0x0FU); - SdCard.LogBlockNbr = (SdCard.BlockNbr) * ((SdCard.BlockSize) / 512U); - SdCard.LogBlockSize = 512U; - } - - if (!SDIO_CmdSelDesel(SdCard.RelCardAdd << 16U)) return false; - if (!SDIO_CmdAppSetClearCardDetect(SdCard.RelCardAdd << 16U)) return false; - if (!SDIO_CmdAppSetBusWidth(SdCard.RelCardAdd << 16U, 2)) return false; - - sdio_set_dbus_width(SDIO_CLKCR_WIDBUS_4BIT); - sdio_set_clock(SDIO_CLOCK); - return true; -} - -bool SDIO_ReadBlock_DMA(uint32_t blockAddress, uint8_t *data) { - if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false; - if (blockAddress >= SdCard.LogBlockNbr) return false; - if ((0x03 & (uint32_t)data)) return false; // misaligned data - - if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; } - - dma_setup_transfer(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, &SDIO->FIFO, DMA_SIZE_32BITS, data, DMA_SIZE_32BITS, DMA_MINC_MODE); - dma_set_num_transfers(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, 128); - dma_clear_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - dma_enable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - - sdio_setup_transfer(SDIO_DATA_TIMEOUT * (F_CPU / 1000U), 512, SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN | SDIO_DIR_RX); - - if (!SDIO_CmdReadSingleBlock(blockAddress)) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - return false; - } - - while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) { /* wait */ } - - //If there were SDIO errors, do not wait DMA. - if (SDIO->STA & SDIO_STA_TRX_ERROR_FLAGS) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - return false; - } - - //Wait for DMA transaction to complete - while ((DMA2_BASE->ISR & (DMA_ISR_TEIF4|DMA_ISR_TCIF4)) == 0 ) { /* wait */ } - - if (DMA2_BASE->ISR & DMA_ISR_TEIF4) { - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - - if (SDIO->STA & SDIO_STA_RXDAVL) { - while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO; - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - - if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return true; -} - -bool SDIO_ReadBlock(uint32_t blockAddress, uint8_t *data) { - uint32_t retries = SDIO_READ_RETRIES; - while (retries--) if (SDIO_ReadBlock_DMA(blockAddress, data)) return true; - return false; -} - -uint32_t millis(); - -bool SDIO_WriteBlock(uint32_t blockAddress, const uint8_t *data) { - if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false; - if (blockAddress >= SdCard.LogBlockNbr) return false; - if ((0x03 & (uint32_t)data)) return false; // misaligned data - - if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; } - - dma_setup_transfer(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, &SDIO->FIFO, DMA_SIZE_32BITS, (volatile void *) data, DMA_SIZE_32BITS, DMA_MINC_MODE | DMA_FROM_MEM); - dma_set_num_transfers(SDIO_DMA_DEV, SDIO_DMA_CHANNEL, 128); - dma_clear_isr_bits(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - dma_enable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - - if (!SDIO_CmdWriteSingleBlock(blockAddress)) { - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - return false; - } - - sdio_setup_transfer(SDIO_DATA_TIMEOUT * (F_CPU / 1000U), 512U, SDIO_BLOCKSIZE_512 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN); - - while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) { /* wait */ } - - dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); - - if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) { - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - return false; - } - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); - - uint32_t timeout = millis() + SDIO_WRITE_TIMEOUT; - while (timeout > millis()) { - if (SDIO_GetCardState() == SDIO_CARD_TRANSFER) { - return true; - } - } - return false; -} - -inline uint32_t SDIO_GetCardState() { return SDIO_CmdSendStatus(SdCard.RelCardAdd << 16U) ? (SDIO_GetResponse(SDIO_RESP1) >> 9U) & 0x0FU : SDIO_CARD_ERROR; } - -// No F1 board with SDIO + MSC using Maple, that I aware of... -bool SDIO_IsReady() { return true; } -uint32_t SDIO_GetCardSize() { return 0; } - -// ------------------------ -// SD Commands and Responses -// ------------------------ - -void SDIO_SendCommand(uint16_t command, uint32_t argument) { SDIO->ARG = argument; SDIO->CMD = (uint32_t)(SDIO_CMD_CPSMEN | command); } -uint8_t SDIO_GetCommandResponse() { return (uint8_t)(SDIO->RESPCMD); } -uint32_t SDIO_GetResponse(uint32_t response) { return SDIO->RESP[response]; } - -bool SDIO_CmdGoIdleState() { SDIO_SendCommand(CMD0_GO_IDLE_STATE, 0); return SDIO_GetCmdError(); } -bool SDIO_CmdSendCID() { SDIO_SendCommand(CMD2_ALL_SEND_CID, 0); return SDIO_GetCmdResp2(); } -bool SDIO_CmdSetRelAdd(uint32_t *rca) { SDIO_SendCommand(CMD3_SET_REL_ADDR, 0); return SDIO_GetCmdResp6(SDMMC_CMD_SET_REL_ADDR, rca); } -bool SDIO_CmdSelDesel(uint32_t address) { SDIO_SendCommand(CMD7_SEL_DESEL_CARD, address); return SDIO_GetCmdResp1(SDMMC_CMD_SEL_DESEL_CARD); } -bool SDIO_CmdOperCond() { SDIO_SendCommand(CMD8_HS_SEND_EXT_CSD, SDMMC_CHECK_PATTERN); return SDIO_GetCmdResp7(); } -bool SDIO_CmdSendCSD(uint32_t argument) { SDIO_SendCommand(CMD9_SEND_CSD, argument); return SDIO_GetCmdResp2(); } -bool SDIO_CmdSendStatus(uint32_t argument) { SDIO_SendCommand(CMD13_SEND_STATUS, argument); return SDIO_GetCmdResp1(SDMMC_CMD_SEND_STATUS); } -bool SDIO_CmdReadSingleBlock(uint32_t address) { SDIO_SendCommand(CMD17_READ_SINGLE_BLOCK, address); return SDIO_GetCmdResp1(SDMMC_CMD_READ_SINGLE_BLOCK); } -bool SDIO_CmdWriteSingleBlock(uint32_t address) { SDIO_SendCommand(CMD24_WRITE_SINGLE_BLOCK, address); return SDIO_GetCmdResp1(SDMMC_CMD_WRITE_SINGLE_BLOCK); } -bool SDIO_CmdAppCommand(uint32_t rsa) { SDIO_SendCommand(CMD55_APP_CMD, rsa); return SDIO_GetCmdResp1(SDMMC_CMD_APP_CMD); } - -bool SDIO_CmdAppSetBusWidth(uint32_t rsa, uint32_t argument) { - if (!SDIO_CmdAppCommand(rsa)) return false; - SDIO_SendCommand(ACMD6_APP_SD_SET_BUSWIDTH, argument); - return SDIO_GetCmdResp2(); -} - -bool SDIO_CmdAppOperCommand(uint32_t sdType) { - if (!SDIO_CmdAppCommand(0)) return false; - SDIO_SendCommand(ACMD41_SD_APP_OP_COND , SDMMC_VOLTAGE_WINDOW_SD | sdType); - return SDIO_GetCmdResp3(); -} - -bool SDIO_CmdAppSetClearCardDetect(uint32_t rsa) { - if (!SDIO_CmdAppCommand(rsa)) return false; - SDIO_SendCommand(ACMD42_SD_APP_SET_CLR_CARD_DETECT, 0); - return SDIO_GetCmdResp2(); -} - -// Wait until given flags are unset or till timeout -#define SDIO_WAIT(FLAGS) do{ \ - uint32_t count = 1 + (SDIO_CMDTIMEOUT) * ((F_CPU) / 8U / 1000U); \ - do { if (!--count) return false; } while (!SDIO_GET_FLAG(FLAGS)); \ -}while(0) - -bool SDIO_GetCmdError() { - SDIO_WAIT(SDIO_STA_CMDSENT); - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - return true; -} - -bool SDIO_GetCmdResp1(uint8_t command) { - SDIO_WAIT(SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT); - - if (SDIO_GET_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT)) { - SDIO_CLEAR_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT); - return false; - } - if (SDIO_GetCommandResponse() != command) return false; - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - return (SDIO_GetResponse(SDIO_RESP1) & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO; -} - -bool SDIO_GetCmdResp2() { - SDIO_WAIT(SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT); - - if (SDIO_GET_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT)) { - SDIO_CLEAR_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT); - return false; - } - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - return true; -} - -bool SDIO_GetCmdResp3() { - SDIO_WAIT(SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT); - - if (SDIO_GET_FLAG(SDIO_STA_CTIMEOUT)) { - SDIO_CLEAR_FLAG(SDIO_STA_CTIMEOUT); - return false; - } - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - return true; -} - -bool SDIO_GetCmdResp6(uint8_t command, uint32_t *rca) { - SDIO_WAIT(SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT); - - if (SDIO_GET_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT)) { - SDIO_CLEAR_FLAG(SDIO_STA_CCRCFAIL | SDIO_STA_CTIMEOUT); - return false; - } - if (SDIO_GetCommandResponse() != command) return false; - - SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); - if (SDIO_GetResponse(SDIO_RESP1) & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) return false; - - *rca = SDIO_GetResponse(SDIO_RESP1) >> 16; - return true; -} - -bool SDIO_GetCmdResp7() { - SDIO_WAIT(SDIO_STA_CCRCFAIL | SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT); - - if (SDIO_GET_FLAG(SDIO_STA_CTIMEOUT)) { - SDIO_CLEAR_FLAG(SDIO_STA_CTIMEOUT); - return false; - } - - if (SDIO_GET_FLAG(SDIO_STA_CMDREND)) { SDIO_CLEAR_FLAG(SDIO_STA_CMDREND); } - return true; -} - -#endif // STM32_HIGH_DENSITY || STM32_XL_DENSITY -#endif // ARDUINO_ARCH_STM32F1 diff --git a/src/HAL/STM32F1/sdio.h b/src/HAL/STM32F1/sdio.h deleted file mode 100644 index 8777299..0000000 --- a/src/HAL/STM32F1/sdio.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to override SDIO clock / retries - -#include -#include - -// ------------------------ -// Defines -// ------------------------ - -#define SDMMC_CMD_GO_IDLE_STATE ((uint8_t)0) /* Resets the SD memory card. */ -#define SDMMC_CMD_ALL_SEND_CID ((uint8_t)2) /* Asks any card connected to the host to send the CID numbers on the CMD line. */ -#define SDMMC_CMD_SET_REL_ADDR ((uint8_t)3) /* Asks the card to publish a new relative address (RCA). */ -#define SDMMC_CMD_SEL_DESEL_CARD ((uint8_t)7) /* Selects the card by its own relative address and gets deselected by any other address */ -#define SDMMC_CMD_HS_SEND_EXT_CSD ((uint8_t)8) /* Sends SD Memory Card interface condition, which includes host supply voltage information and asks the card whether card supports voltage. */ -#define SDMMC_CMD_SEND_CSD ((uint8_t)9) /* Addressed card sends its card specific data (CSD) on the CMD line. */ -#define SDMMC_CMD_SEND_STATUS ((uint8_t)13) /*!< Addressed card sends its status register. */ -#define SDMMC_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /* Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC. */ -#define SDMMC_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) /* Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC. */ -#define SDMMC_CMD_APP_CMD ((uint8_t)55) /* Indicates to the card that the next command is an application specific command rather than a standard command. */ - -#define SDMMC_ACMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /* (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus widths are given in SCR register. */ -#define SDMMC_ACMD_SD_APP_OP_COND ((uint8_t)41) /* (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to send its operating condition register (OCR) content in the response on the CMD line. */ -#define SDMMC_ACMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /* (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */ - -#define CMD0_GO_IDLE_STATE (uint16_t)(SDMMC_CMD_GO_IDLE_STATE | SDIO_CMD_WAIT_NO_RESP) -#define CMD2_ALL_SEND_CID (uint16_t)(SDMMC_CMD_ALL_SEND_CID | SDIO_CMD_WAIT_LONG_RESP) -#define CMD3_SET_REL_ADDR (uint16_t)(SDMMC_CMD_SET_REL_ADDR | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD7_SEL_DESEL_CARD (uint16_t)(SDMMC_CMD_SEL_DESEL_CARD | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD8_HS_SEND_EXT_CSD (uint16_t)(SDMMC_CMD_HS_SEND_EXT_CSD | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD9_SEND_CSD (uint16_t)(SDMMC_CMD_SEND_CSD | SDIO_CMD_WAIT_LONG_RESP) -#define CMD13_SEND_STATUS (uint16_t)(SDMMC_CMD_SEND_STATUS | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD17_READ_SINGLE_BLOCK (uint16_t)(SDMMC_CMD_READ_SINGLE_BLOCK | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD24_WRITE_SINGLE_BLOCK (uint16_t)(SDMMC_CMD_WRITE_SINGLE_BLOCK | SDIO_CMD_WAIT_SHORT_RESP) -#define CMD55_APP_CMD (uint16_t)(SDMMC_CMD_APP_CMD | SDIO_CMD_WAIT_SHORT_RESP) - -#define ACMD6_APP_SD_SET_BUSWIDTH (uint16_t)(SDMMC_ACMD_APP_SD_SET_BUSWIDTH | SDIO_CMD_WAIT_SHORT_RESP) -#define ACMD41_SD_APP_OP_COND (uint16_t)(SDMMC_ACMD_SD_APP_OP_COND | SDIO_CMD_WAIT_SHORT_RESP) -#define ACMD42_SD_APP_SET_CLR_CARD_DETECT (uint16_t)(SDMMC_ACMD_SD_APP_SET_CLR_CARD_DETECT | SDIO_CMD_WAIT_SHORT_RESP) - - -#define SDMMC_ALLZERO 0x00000000U -#define SDMMC_OCR_ERRORBITS 0xFDFFE008U - -#define SDMMC_R6_GENERAL_UNKNOWN_ERROR 0x00002000U -#define SDMMC_R6_ILLEGAL_CMD 0x00004000U -#define SDMMC_R6_COM_CRC_FAILED 0x00008000U - -#define SDMMC_VOLTAGE_WINDOW_SD 0x80100000U -#define SDMMC_HIGH_CAPACITY 0x40000000U -#define SDMMC_STD_CAPACITY 0x00000000U -#define SDMMC_CHECK_PATTERN 0x000001AAU - -#define SDIO_TRANSFER_MODE_BLOCK 0x00000000U -#define SDIO_DPSM_ENABLE 0x00000001U -#define SDIO_TRANSFER_DIR_TO_CARD 0x00000000U -#define SDIO_DATABLOCK_SIZE_512B 0x00000090U -#define SDIO_TRANSFER_DIR_TO_SDIO 0x00000100U -#define SDIO_DMA_ENABLE 0x00001000U - -#define CARD_V1_X 0x00000000U -#define CARD_V2_X 0x00000001U -#define CARD_SDSC 0x00000000U -#define CARD_SDHC_SDXC 0x00000001U - -#define SDIO_RESP1 0 -#define SDIO_RESP2 1 -#define SDIO_RESP3 2 -#define SDIO_RESP4 3 - -#define SDIO_GET_FLAG(__FLAG__) !!((SDIO->STA) & (__FLAG__)) -#define SDIO_CLEAR_FLAG(__FLAG__) (SDIO->ICR = (__FLAG__)) - -#define SDMMC_MAX_VOLT_TRIAL 0x00000FFFU -#define SDIO_CARD_TRANSFER 0x00000004U /* Card is in transfer state */ -#define SDIO_CARD_ERROR 0x000000FFU /* Card response Error */ -#define SDIO_CMDTIMEOUT 200U /* Command send and response timeout */ -#define SDIO_DATA_TIMEOUT 100U /* Read data transfer timeout */ -#define SDIO_WRITE_TIMEOUT 200U /* Write data transfer timeout */ - -#ifndef SDIO_CLOCK - #define SDIO_CLOCK 18000000 /* 18 MHz */ -#endif - -#ifndef SDIO_READ_RETRIES - #define SDIO_READ_RETRIES 3 -#endif - -// ------------------------ -// Types -// ------------------------ - -typedef struct { - uint32_t CardType; // Card Type - uint32_t CardVersion; // Card version - uint32_t Class; // Class of the card class - uint32_t RelCardAdd; // Relative Card Address - uint32_t BlockNbr; // Card Capacity in blocks - uint32_t BlockSize; // One block size in bytes - uint32_t LogBlockNbr; // Card logical Capacity in blocks - uint32_t LogBlockSize; // Logical block size in bytes -} SDIO_CardInfoTypeDef; - -// ------------------------ -// Public functions -// ------------------------ - -inline uint32_t SDIO_GetCardState(); - -bool SDIO_CmdGoIdleState(); -bool SDIO_CmdSendCID(); -bool SDIO_CmdSetRelAdd(uint32_t *rca); -bool SDIO_CmdSelDesel(uint32_t address); -bool SDIO_CmdOperCond(); -bool SDIO_CmdSendCSD(uint32_t argument); -bool SDIO_CmdSendStatus(uint32_t argument); -bool SDIO_CmdReadSingleBlock(uint32_t address); -bool SDIO_CmdWriteSingleBlock(uint32_t address); -bool SDIO_CmdAppCommand(uint32_t rsa); - -bool SDIO_CmdAppSetBusWidth(uint32_t rsa, uint32_t argument); -bool SDIO_CmdAppOperCommand(uint32_t sdType); -bool SDIO_CmdAppSetClearCardDetect(uint32_t rsa); - -void SDIO_SendCommand(uint16_t command, uint32_t argument); -uint8_t SDIO_GetCommandResponse(); -uint32_t SDIO_GetResponse(uint32_t response); -bool SDIO_GetCmdError(); -bool SDIO_GetCmdResp1(uint8_t command); -bool SDIO_GetCmdResp2(); -bool SDIO_GetCmdResp3(); -bool SDIO_GetCmdResp6(uint8_t command, uint32_t *rca); -bool SDIO_GetCmdResp7(); diff --git a/src/HAL/STM32F1/spi_pins.h b/src/HAL/STM32F1/spi_pins.h deleted file mode 100644 index 3d3c8f8..0000000 --- a/src/HAL/STM32F1/spi_pins.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - */ - -/** - * STM32F1 Default SPI Pins - * - * SS SCK MISO MOSI - * +-----------------------------+ - * SPI1 | PA4 PA5 PA6 PA7 | - * SPI2 | PB12 PB13 PB14 PB15 | - * SPI3 | PA15 PB3 PB4 PB5 | - * +-----------------------------+ - * Any pin can be used for Chip Select (SD_SS_PIN) - * SPI1 is enabled by default - */ -#ifndef SD_SCK_PIN - #define SD_SCK_PIN PA5 -#endif -#ifndef SD_MISO_PIN - #define SD_MISO_PIN PA6 -#endif -#ifndef SD_MOSI_PIN - #define SD_MOSI_PIN PA7 -#endif -#ifndef SD_SS_PIN - #define SD_SS_PIN PA4 -#endif -#undef SDSS -#define SDSS SD_SS_PIN - -#ifndef SPI_DEVICE - #define SPI_DEVICE 1 -#endif diff --git a/src/HAL/STM32F1/tft/tft_fsmc.cpp b/src/HAL/STM32F1/tft/tft_fsmc.cpp deleted file mode 100644 index 5b52fb4..0000000 --- a/src/HAL/STM32F1/tft/tft_fsmc.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_FSMC_TFT - -#include "tft_fsmc.h" -#include -#include -#include - -LCD_CONTROLLER_TypeDef *TFT_FSMC::LCD; - -/** - * FSMC LCD IO - */ -#define __ASM __asm -#define __STATIC_INLINE static inline - -__attribute__((always_inline)) __STATIC_INLINE void __DSB() { - __ASM volatile ("dsb 0xF":::"memory"); -} - -#define FSMC_CS_NE1 PD7 - -#if ENABLED(STM32_XL_DENSITY) - #define FSMC_CS_NE2 PG9 - #define FSMC_CS_NE3 PG10 - #define FSMC_CS_NE4 PG12 - - #define FSMC_RS_A0 PF0 - #define FSMC_RS_A1 PF1 - #define FSMC_RS_A2 PF2 - #define FSMC_RS_A3 PF3 - #define FSMC_RS_A4 PF4 - #define FSMC_RS_A5 PF5 - #define FSMC_RS_A6 PF12 - #define FSMC_RS_A7 PF13 - #define FSMC_RS_A8 PF14 - #define FSMC_RS_A9 PF15 - #define FSMC_RS_A10 PG0 - #define FSMC_RS_A11 PG1 - #define FSMC_RS_A12 PG2 - #define FSMC_RS_A13 PG3 - #define FSMC_RS_A14 PG4 - #define FSMC_RS_A15 PG5 -#endif - -#define FSMC_RS_A16 PD11 -#define FSMC_RS_A17 PD12 -#define FSMC_RS_A18 PD13 -#define FSMC_RS_A19 PE3 -#define FSMC_RS_A20 PE4 -#define FSMC_RS_A21 PE5 -#define FSMC_RS_A22 PE6 -#define FSMC_RS_A23 PE2 - -#if ENABLED(STM32_XL_DENSITY) - #define FSMC_RS_A24 PG13 - #define FSMC_RS_A25 PG14 -#endif - -/* Timing configuration */ -#define FSMC_ADDRESS_SETUP_TIME 15 // AddressSetupTime -#define FSMC_DATA_SETUP_TIME 15 // DataSetupTime - -static uint8_t fsmcInit = 0; -void TFT_FSMC::Init() { - uint8_t cs = FSMC_CS_PIN, rs = FSMC_RS_PIN; - uint32_t controllerAddress; - - #if ENABLED(LCD_USE_DMA_FSMC) - dma_init(FSMC_DMA_DEV); - dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - dma_set_priority(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, DMA_PRIORITY_MEDIUM); - #endif - - struct fsmc_nor_psram_reg_map* fsmcPsramRegion; - - if (fsmcInit) return; - fsmcInit = 1; - - switch (cs) { - case FSMC_CS_NE1: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION1; fsmcPsramRegion = FSMC_NOR_PSRAM1_BASE; break; - #if ENABLED(STM32_XL_DENSITY) - case FSMC_CS_NE2: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION2; fsmcPsramRegion = FSMC_NOR_PSRAM2_BASE; break; - case FSMC_CS_NE3: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION3; fsmcPsramRegion = FSMC_NOR_PSRAM3_BASE; break; - case FSMC_CS_NE4: controllerAddress = (uint32_t)FSMC_NOR_PSRAM_REGION4; fsmcPsramRegion = FSMC_NOR_PSRAM4_BASE; break; - #endif - default: return; - } - - #define _ORADDR(N) controllerAddress |= (_BV32(N) - 2) - - switch (rs) { - #if ENABLED(STM32_XL_DENSITY) - case FSMC_RS_A0: _ORADDR( 1); break; - case FSMC_RS_A1: _ORADDR( 2); break; - case FSMC_RS_A2: _ORADDR( 3); break; - case FSMC_RS_A3: _ORADDR( 4); break; - case FSMC_RS_A4: _ORADDR( 5); break; - case FSMC_RS_A5: _ORADDR( 6); break; - case FSMC_RS_A6: _ORADDR( 7); break; - case FSMC_RS_A7: _ORADDR( 8); break; - case FSMC_RS_A8: _ORADDR( 9); break; - case FSMC_RS_A9: _ORADDR(10); break; - case FSMC_RS_A10: _ORADDR(11); break; - case FSMC_RS_A11: _ORADDR(12); break; - case FSMC_RS_A12: _ORADDR(13); break; - case FSMC_RS_A13: _ORADDR(14); break; - case FSMC_RS_A14: _ORADDR(15); break; - case FSMC_RS_A15: _ORADDR(16); break; - #endif - case FSMC_RS_A16: _ORADDR(17); break; - case FSMC_RS_A17: _ORADDR(18); break; - case FSMC_RS_A18: _ORADDR(19); break; - case FSMC_RS_A19: _ORADDR(20); break; - case FSMC_RS_A20: _ORADDR(21); break; - case FSMC_RS_A21: _ORADDR(22); break; - case FSMC_RS_A22: _ORADDR(23); break; - case FSMC_RS_A23: _ORADDR(24); break; - #if ENABLED(STM32_XL_DENSITY) - case FSMC_RS_A24: _ORADDR(25); break; - case FSMC_RS_A25: _ORADDR(26); break; - #endif - default: return; - } - - rcc_clk_enable(RCC_FSMC); - - gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP); // FSMC_D00 - gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP); // FSMC_D01 - gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP); // FSMC_D02 - gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP); // FSMC_D03 - gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP); // FSMC_D04 - gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP); // FSMC_D05 - gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP); // FSMC_D06 - gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP); // FSMC_D07 - gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP); // FSMC_D08 - gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP); // FSMC_D09 - gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP); // FSMC_D10 - gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP); // FSMC_D11 - gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP); // FSMC_D12 - gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP); // FSMC_D13 - gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP); // FSMC_D14 - gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP); // FSMC_D15 - - gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // FSMC_NOE - gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // FSMC_NWE - - gpio_set_mode(PIN_MAP[cs].gpio_device, PIN_MAP[cs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_CS_NEx - gpio_set_mode(PIN_MAP[rs].gpio_device, PIN_MAP[rs].gpio_bit, GPIO_AF_OUTPUT_PP); //FSMC_RS_Ax - - fsmcPsramRegion->BCR = FSMC_BCR_WREN | FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_MBKEN; - fsmcPsramRegion->BTR = (FSMC_DATA_SETUP_TIME << 8) | FSMC_ADDRESS_SETUP_TIME; - - afio_remap(AFIO_REMAP_FSMC_NADV); - - LCD = (LCD_CONTROLLER_TypeDef*)controllerAddress; -} - -void TFT_FSMC::Transmit(uint16_t Data) { - LCD->RAM = Data; - __DSB(); -} - -void TFT_FSMC::WriteReg(uint16_t Reg) { - LCD->REG = Reg; - __DSB(); -} - -uint32_t TFT_FSMC::GetID() { - uint32_t id; - WriteReg(0x0000); - id = LCD->RAM; - - if (id == 0) - id = ReadID(LCD_READ_ID); - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) - id = ReadID(LCD_READ_ID4); - if ((id & 0xFF00) == 0 && (id & 0xFF) != 0) - id = ReadID(LCD_READ_ID4); - return id; -} - - uint32_t TFT_FSMC::ReadID(uint16_t Reg) { - uint32_t id; - WriteReg(Reg); - id = LCD->RAM; // dummy read - id = Reg << 24; - id |= (LCD->RAM & 0x00FF) << 16; - id |= (LCD->RAM & 0x00FF) << 8; - id |= LCD->RAM & 0x00FF; - return id; - } - -bool TFT_FSMC::isBusy() { - return false; -} - -void TFT_FSMC::Abort() { - -} - -void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - #if defined(FSMC_DMA_DEV) && defined(FSMC_DMA_CHANNEL) - dma_setup_transfer(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Data, DMA_SIZE_16BITS, &LCD->RAM, DMA_SIZE_16BITS, DMA_MEM_2_MEM | MemoryIncrease); - dma_set_num_transfers(FSMC_DMA_DEV, FSMC_DMA_CHANNEL, Count); - dma_clear_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - dma_enable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - - while ((dma_get_isr_bits(FSMC_DMA_DEV, FSMC_DMA_CHANNEL) & 0x0A) == 0) {}; - dma_disable(FSMC_DMA_DEV, FSMC_DMA_CHANNEL); - #endif -} - -#endif // HAS_FSMC_TFT diff --git a/src/HAL/STM32F1/tft/tft_fsmc.h b/src/HAL/STM32F1/tft/tft_fsmc.h deleted file mode 100644 index d9ee1f4..0000000 --- a/src/HAL/STM32F1/tft/tft_fsmc.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#include - -#define DATASIZE_8BIT DMA_SIZE_8BITS -#define DATASIZE_16BIT DMA_SIZE_16BITS -#define TFT_IO_DRIVER TFT_FSMC - -typedef struct { - __IO uint16_t REG; - __IO uint16_t RAM; -} LCD_CONTROLLER_TypeDef; - -class TFT_FSMC { - private: - static LCD_CONTROLLER_TypeDef *LCD; - - static uint32_t ReadID(uint16_t Reg); - static void Transmit(uint16_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - - public: - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort(); - - static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {}; - static void DataTransferEnd() {}; - - static void WriteData(uint16_t Data) { Transmit(Data); } - static void WriteReg(uint16_t Reg); - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_MODE, Data, Count); } - static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_CIRC_MODE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - while (Count > 0) { - TransmitDMA(DMA_CIRC_MODE, &Data, Count > 0xFFFF ? 0xFFFF : Count); - Count = Count > 0xFFFF ? Count - 0xFFFF : 0; - } - } -}; diff --git a/src/HAL/STM32F1/tft/tft_spi.cpp b/src/HAL/STM32F1/tft/tft_spi.cpp deleted file mode 100644 index f447cec..0000000 --- a/src/HAL/STM32F1/tft/tft_spi.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_SPI_TFT - -#include "tft_spi.h" - -SPIClass TFT_SPI::SPIx(1); - -void TFT_SPI::Init() { - #if PIN_EXISTS(TFT_RESET) - OUT_WRITE(TFT_RESET_PIN, HIGH); - delay(100); - #endif - - #if PIN_EXISTS(TFT_BACKLIGHT) - OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH); - #endif - - OUT_WRITE(TFT_DC_PIN, HIGH); - OUT_WRITE(TFT_CS_PIN, HIGH); - - /** - * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz - * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 - * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 - */ - #if SPI_DEVICE == 1 - #define SPI_CLOCK_MAX SPI_CLOCK_DIV4 - #else - #define SPI_CLOCK_MAX SPI_CLOCK_DIV2 - #endif - uint8_t clock; - uint8_t spiRate = SPI_FULL_SPEED; - switch (spiRate) { - case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX ; break; - case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4 ; break; - case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8 ; break; - case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; - case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; - case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; - default: clock = SPI_CLOCK_DIV2; // Default from the SPI library - } - SPIx.setModule(1); - SPIx.setClockDivider(clock); - SPIx.setBitOrder(MSBFIRST); - SPIx.setDataMode(SPI_MODE0); -} - -void TFT_SPI::DataTransferBegin(uint16_t DataSize) { - SPIx.setDataSize(DataSize); - SPIx.begin(); - OUT_WRITE(TFT_CS_PIN, LOW); -} - -#ifdef TFT_DEFAULT_DRIVER - #include "../../../lcd/tft_io/tft_ids.h" -#endif - -uint32_t TFT_SPI::GetID() { - uint32_t id; - id = ReadID(LCD_READ_ID); - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) { - id = ReadID(LCD_READ_ID4); - #ifdef TFT_DEFAULT_DRIVER - if ((id & 0xFFFF) == 0 || (id & 0xFFFF) == 0xFFFF) - id = TFT_DEFAULT_DRIVER; - #endif - } - return id; -} - -uint32_t TFT_SPI::ReadID(uint16_t Reg) { - #if !PIN_EXISTS(TFT_MISO) - return 0; - #else - uint8_t d = 0; - uint32_t data = 0; - SPIx.setClockDivider(SPI_CLOCK_DIV16); - DataTransferBegin(DATASIZE_8BIT); - WriteReg(Reg); - - LOOP_L_N(i, 4) { - SPIx.read((uint8_t*)&d, 1); - data = (data << 8) | d; - } - - DataTransferEnd(); - SPIx.setClockDivider(SPI_CLOCK_MAX); - - return data >> 7; - #endif -} - -bool TFT_SPI::isBusy() { return false; } - -void TFT_SPI::Abort() { DataTransferEnd(); } - -void TFT_SPI::Transmit(uint16_t Data) { SPIx.send(Data); } - -void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) { - DataTransferBegin(); - OUT_WRITE(TFT_DC_PIN, HIGH); - SPIx.dmaSend(Data, Count, MemoryIncrease == DMA_MINC_ENABLE); - DataTransferEnd(); -} - -#endif // HAS_SPI_TFT diff --git a/src/HAL/STM32F1/tft/tft_spi.h b/src/HAL/STM32F1/tft/tft_spi.h deleted file mode 100644 index da9a8e0..0000000 --- a/src/HAL/STM32F1/tft/tft_spi.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#include - -#ifndef LCD_READ_ID - #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341) -#endif -#ifndef LCD_READ_ID4 - #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341) -#endif - -#define DATASIZE_8BIT DATA_SIZE_8BIT -#define DATASIZE_16BIT DATA_SIZE_16BIT -#define TFT_IO_DRIVER TFT_SPI - -#define DMA_MINC_ENABLE 1 -#define DMA_MINC_DISABLE 0 - -class TFT_SPI { -private: - static uint32_t ReadID(uint16_t Reg); - static void Transmit(uint16_t Data); - static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count); - -public: - static SPIClass SPIx; - - static void Init(); - static uint32_t GetID(); - static bool isBusy(); - static void Abort(); - - static void DataTransferBegin(uint16_t DataWidth = DATA_SIZE_16BIT); - static void DataTransferEnd() { WRITE(TFT_CS_PIN, HIGH); SPIx.end(); }; - static void DataTransferAbort(); - - static void WriteData(uint16_t Data) { Transmit(Data); } - static void WriteReg(uint16_t Reg) { WRITE(TFT_A0_PIN, LOW); Transmit(Reg); WRITE(TFT_A0_PIN, HIGH); } - - static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); } - static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); } - static void WriteMultiple(uint16_t Color, uint32_t Count) { - static uint16_t Data; Data = Color; - while (Count > 0) { - TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count); - Count = Count > 0xFFFF ? Count - 0xFFFF : 0; - } - } -}; diff --git a/src/HAL/STM32F1/tft/xpt2046.cpp b/src/HAL/STM32F1/tft/xpt2046.cpp deleted file mode 100644 index ac9ad07..0000000 --- a/src/HAL/STM32F1/tft/xpt2046.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS - -#include "xpt2046.h" -#include - -uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; } - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - #include - - SPIClass XPT2046::SPIx(TOUCH_BUTTONS_HW_SPI_DEVICE); - - static void touch_spi_init(uint8_t spiRate) { - /** - * STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz - * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 - * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 - */ - uint8_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break; - case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break; - case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break; - case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break; - case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break; - case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break; - default: clock = SPI_CLOCK_DIV2; // Default from the SPI library - } - XPT2046::SPIx.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE); - XPT2046::SPIx.setClockDivider(clock); - XPT2046::SPIx.setBitOrder(MSBFIRST); - XPT2046::SPIx.setDataMode(SPI_MODE0); - } -#endif // TOUCH_BUTTONS_HW_SPI - -void XPT2046::Init() { - SET_INPUT(TOUCH_MISO_PIN); - SET_OUTPUT(TOUCH_MOSI_PIN); - SET_OUTPUT(TOUCH_SCK_PIN); - OUT_WRITE(TOUCH_CS_PIN, HIGH); - - #if PIN_EXISTS(TOUCH_INT) - // Optional Pendrive interrupt pin - SET_INPUT(TOUCH_INT_PIN); - #endif - - TERN_(TOUCH_BUTTONS_HW_SPI, touch_spi_init(SPI_SPEED_6)); - - // Read once to enable pendrive status pin - getRawData(XPT2046_X); -} - -bool XPT2046::isTouched() { - return isBusy() ? false : ( - #if PIN_EXISTS(TOUCH_INT) - READ(TOUCH_INT_PIN) != HIGH - #else - getRawData(XPT2046_Z1) >= XPT2046_Z1_THRESHOLD - #endif - ); -} - -bool XPT2046::getRawPoint(int16_t *x, int16_t *y) { - if (isBusy()) return false; - if (!isTouched()) return false; - *x = getRawData(XPT2046_X); - *y = getRawData(XPT2046_Y); - return isTouched(); -} - -uint16_t XPT2046::getRawData(const XPTCoordinate coordinate) { - uint16_t data[3]; - - DataTransferBegin(); - TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.begin()); - - for (uint16_t i = 0; i < 3 ; i++) { - IO(coordinate); - data[i] = (IO() << 4) | (IO() >> 4); - } - - TERN_(TOUCH_BUTTONS_HW_SPI, SPIx.end()); - DataTransferEnd(); - - uint16_t delta01 = delta(data[0], data[1]), - delta02 = delta(data[0], data[2]), - delta12 = delta(data[1], data[2]); - - if (delta01 > delta02 || delta01 > delta12) - data[delta02 > delta12 ? 0 : 1] = data[2]; - - return (data[0] + data[1]) >> 1; -} - -uint16_t XPT2046::IO(uint16_t data) { - return TERN(TOUCH_BUTTONS_HW_SPI, HardwareIO, SoftwareIO)(data); -} - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - uint16_t XPT2046::HardwareIO(uint16_t data) { - uint16_t result = SPIx.transfer(data); - return result; - } -#endif - -uint16_t XPT2046::SoftwareIO(uint16_t data) { - uint16_t result = 0; - - for (uint8_t j = 0x80; j; j >>= 1) { - WRITE(TOUCH_SCK_PIN, LOW); - WRITE(TOUCH_MOSI_PIN, data & j ? HIGH : LOW); - if (READ(TOUCH_MISO_PIN)) result |= j; - WRITE(TOUCH_SCK_PIN, HIGH); - } - WRITE(TOUCH_SCK_PIN, LOW); - - return result; -} - -#endif // HAS_TFT_XPT2046 diff --git a/src/HAL/STM32F1/tft/xpt2046.h b/src/HAL/STM32F1/tft/xpt2046.h deleted file mode 100644 index 7c456cf..0000000 --- a/src/HAL/STM32F1/tft/xpt2046.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(TOUCH_BUTTONS_HW_SPI) - #include -#endif - -#ifndef TOUCH_MISO_PIN - #define TOUCH_MISO_PIN SD_MISO_PIN -#endif -#ifndef TOUCH_MOSI_PIN - #define TOUCH_MOSI_PIN SD_MOSI_PIN -#endif -#ifndef TOUCH_SCK_PIN - #define TOUCH_SCK_PIN SD_SCK_PIN -#endif -#ifndef TOUCH_CS_PIN - #define TOUCH_CS_PIN SD_SS_PIN -#endif -#ifndef TOUCH_INT_PIN - #define TOUCH_INT_PIN -1 -#endif - -#define XPT2046_DFR_MODE 0x00 -#define XPT2046_SER_MODE 0x04 -#define XPT2046_CONTROL 0x80 - -enum XPTCoordinate : uint8_t { - XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE, - XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE, -}; - -#ifndef XPT2046_Z1_THRESHOLD - #define XPT2046_Z1_THRESHOLD 10 -#endif - -class XPT2046 { -private: - static bool isBusy() { return false; } - - static uint16_t getRawData(const XPTCoordinate coordinate); - static bool isTouched(); - - static void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); }; - static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); }; - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static uint16_t HardwareIO(uint16_t data); - #endif - static uint16_t SoftwareIO(uint16_t data); - static uint16_t IO(uint16_t data = 0); - -public: - #if ENABLED(TOUCH_BUTTONS_HW_SPI) - static SPIClass SPIx; - #endif - - static void Init(); - static bool getRawPoint(int16_t *x, int16_t *y); -}; diff --git a/src/HAL/STM32F1/timers.cpp b/src/HAL/STM32F1/timers.cpp deleted file mode 100644 index 112c730..0000000 --- a/src/HAL/STM32F1/timers.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - */ - -#ifdef __STM32F1__ - -#include "../../inc/MarlinConfig.h" - -// ------------------------ -// Local defines -// ------------------------ - -// ------------------------ -// Public functions -// ------------------------ - -/** - * Timer_clock1: Prescaler 2 -> 36 MHz - * Timer_clock2: Prescaler 8 -> 9 MHz - * Timer_clock3: Prescaler 32 -> 2.25 MHz - * Timer_clock4: Prescaler 128 -> 562.5 kHz - */ - -/** - * TODO: Calculate Timer prescale value, so we get the 32bit to adjust - */ - -void HAL_timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority) { - nvic_irq_num irq_num; - switch (timer_num) { - case 1: irq_num = NVIC_TIMER1_CC; break; - case 2: irq_num = NVIC_TIMER2; break; - case 3: irq_num = NVIC_TIMER3; break; - case 4: irq_num = NVIC_TIMER4; break; - case 5: irq_num = NVIC_TIMER5; break; - #ifdef STM32_HIGH_DENSITY - // 6 & 7 are basic timers, avoid them - case 8: irq_num = NVIC_TIMER8_CC; break; - #endif - default: - /** - * This should never happen. Add a Sanitycheck for timer number. - * Should be a general timer since basic timers have no CC channels. - */ - return; - } - - nvic_irq_set_priority(irq_num, priority); -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - /** - * Give the Stepper ISR a higher priority (lower number) - * so it automatically preempts the Temperature ISR. - */ - - switch (timer_num) { - case MF_TIMER_STEP: - timer_pause(STEP_TIMER_DEV); - timer_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OUTPUT_COMPARE); // counter - timer_set_count(STEP_TIMER_DEV, 0); - timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1)); - timer_set_reload(STEP_TIMER_DEV, 0xFFFF); - timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change - timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency)); - timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register - timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler); - HAL_timer_set_interrupt_priority(MF_TIMER_STEP, STEP_TIMER_IRQ_PRIO); - timer_generate_update(STEP_TIMER_DEV); - timer_resume(STEP_TIMER_DEV); - break; - case MF_TIMER_TEMP: - timer_pause(TEMP_TIMER_DEV); - timer_set_mode(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, TIMER_OUTPUT_COMPARE); - timer_set_count(TEMP_TIMER_DEV, 0); - timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1)); - timer_set_reload(TEMP_TIMER_DEV, 0xFFFF); - timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency)); - timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler); - HAL_timer_set_interrupt_priority(MF_TIMER_TEMP, TEMP_TIMER_IRQ_PRIO); - timer_generate_update(TEMP_TIMER_DEV); - timer_resume(TEMP_TIMER_DEV); - break; - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: ENABLE_STEPPER_DRIVER_INTERRUPT(); break; - case MF_TIMER_TEMP: ENABLE_TEMPERATURE_INTERRUPT(); break; - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: DISABLE_STEPPER_DRIVER_INTERRUPT(); break; - case MF_TIMER_TEMP: DISABLE_TEMPERATURE_INTERRUPT(); break; - } -} - -static inline bool HAL_timer_irq_enabled(const timer_dev * const dev, const uint8_t interrupt) { - return bool(*bb_perip(&(dev->regs).gen->DIER, interrupt)); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return HAL_timer_irq_enabled(STEP_TIMER_DEV, STEP_TIMER_CHAN); - case MF_TIMER_TEMP: return HAL_timer_irq_enabled(TEMP_TIMER_DEV, TEMP_TIMER_CHAN); - } - return false; -} - -timer_dev* HAL_get_timer_dev(int number) { - switch (number) { - #if STM32_HAVE_TIMER(1) - case 1: return &timer1; - #endif - #if STM32_HAVE_TIMER(2) - case 2: return &timer2; - #endif - #if STM32_HAVE_TIMER(3) - case 3: return &timer3; - #endif - #if STM32_HAVE_TIMER(4) - case 4: return &timer4; - #endif - #if STM32_HAVE_TIMER(5) - case 5: return &timer5; - #endif - #if STM32_HAVE_TIMER(6) - case 6: return &timer6; - #endif - #if STM32_HAVE_TIMER(7) - case 7: return &timer7; - #endif - #if STM32_HAVE_TIMER(8) - case 8: return &timer8; - #endif - #if STM32_HAVE_TIMER(9) - case 9: return &timer9; - #endif - #if STM32_HAVE_TIMER(10) - case 10: return &timer10; - #endif - #if STM32_HAVE_TIMER(11) - case 11: return &timer11; - #endif - #if STM32_HAVE_TIMER(12) - case 12: return &timer12; - #endif - #if STM32_HAVE_TIMER(13) - case 13: return &timer13; - #endif - #if STM32_HAVE_TIMER(14) - case 14: return &timer14; - #endif - default: return nullptr; - } -} - -#endif // __STM32F1__ diff --git a/src/HAL/STM32F1/timers.h b/src/HAL/STM32F1/timers.h deleted file mode 100644 index 0cd807f..0000000 --- a/src/HAL/STM32F1/timers.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for stm32duino.com based on Libmaple and compatible (STM32F1) - */ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include - -// ------------------------ -// Defines -// ------------------------ - -/** - * TODO: Check and confirm what timer we will use for each Temps and stepper driving. - * We should probable drive temps with PWM. - */ - -typedef uint16_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFF - -#define HAL_TIMER_RATE uint32_t(F_CPU) // frequency of timers peripherals - -#ifndef STEP_TIMER_CHAN - #define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts -#endif -#ifndef TEMP_TIMER_CHAN - #define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts -#endif - -/** - * Note: Timers may be used by platforms and libraries - * - * FAN PWMs: - * With FAN_SOFT_PWM disabled the Temperature class uses - * FANx_PIN timers to generate FAN PWM signals. - * - * Speaker: - * When SPEAKER is enabled, one timer is allocated by maple/tone.cpp. - * - If BEEPER_PIN has a timer channel (and USE_PIN_TIMER is - * defined in tone.cpp) it uses the pin's own timer. - * - Otherwise it uses Timer 8 on boards with STM32_HIGH_DENSITY - * or Timer 4 on other boards. - */ -#ifndef MF_TIMER_STEP - #if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8) - #define MF_TIMER_STEP 4 // For C8/CB boards, use timer 4 - #else - #define MF_TIMER_STEP 5 // for other boards, five is fine. - #endif -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 2 // Timer Index for Temperature - //#define MF_TIMER_TEMP 4 // 2->4, Timer 2 for Stepper Current PWM -#endif - -#if MB(BTT_SKR_MINI_E3_V1_0, BTT_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE, MKS_ROBIN_E3D, MKS_ROBIN_E3) - // SKR Mini E3 boards use PA8 as FAN_PIN, so TIMER 1 is used for Fan PWM. - #ifdef STM32_HIGH_DENSITY - #define MF_TIMER_SERVO0 8 // tone.cpp uses Timer 4 - #else - #define MF_TIMER_SERVO0 3 // tone.cpp uses Timer 8 - #endif -#else - #define MF_TIMER_SERVO0 1 // SERVO0 or BLTOUCH -#endif - -#define STEP_TIMER_IRQ_PRIO 2 -#define TEMP_TIMER_IRQ_PRIO 3 -#define SERVO0_TIMER_IRQ_PRIO 1 - -#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz -#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency - -#define STEPPER_TIMER_PRESCALE 18 // prescaler for setting stepper timer, 4Mhz -#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // frequency of stepper timer -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -timer_dev* HAL_get_timer_dev(int number); -#define TIMER_DEV(num) HAL_get_timer_dev(num) -#define STEP_TIMER_DEV TIMER_DEV(MF_TIMER_STEP) -#define TEMP_TIMER_DEV TIMER_DEV(MF_TIMER_TEMP) - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() timer_enable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() timer_disable_irq(STEP_TIMER_DEV, STEP_TIMER_CHAN) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() timer_enable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) -#define DISABLE_TEMPERATURE_INTERRUPT() timer_disable_irq(TEMP_TIMER_DEV, TEMP_TIMER_CHAN) - -#define HAL_timer_get_count(timer_num) timer_get_count(TIMER_DEV(timer_num)) - -// TODO change this - -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() -#endif -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() -#endif - -extern "C" { - void tempTC_Handler(); - void stepTC_Handler(); -} - -// ------------------------ -// Public Variables -// ------------------------ - -//static HardwareTimer StepperTimer(MF_TIMER_STEP); -//static HardwareTimer TempTimer(MF_TIMER_TEMP); - -// ------------------------ -// Public functions -// ------------------------ - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -/** - * NOTE: By default libmaple sets ARPE = 1, which means the Auto reload register is preloaded (will only update with an update event) - * Thus we have to pause the timer, update the value, refresh, resume the timer. - * That seems like a big waste of time and may be better to change the timer config to ARPE = 0, so ARR can be updated any time. - * We are using a Channel in each timer in Capture/Compare mode. We could also instead use the Time Update Event Interrupt, but need to disable ARPE - * so we can change the ARR value on the fly (without calling refresh), and not get an interrupt right there because we caused an UEV. - * This mode pretty much makes 2 timers unusable for PWM since they have their counts updated all the time on ISRs. - * The way Marlin manages timer interrupts doesn't make for an efficient usage in STM32F1 - * Todo: Look at that possibility later. - */ - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - switch (timer_num) { - case MF_TIMER_STEP: - // NOTE: WE have set ARPE = 0, which means the Auto reload register is not preloaded - // and there is no need to use any compare, as in the timer mode used, setting ARR to the compare value - // will result in exactly the same effect, ie triggering an interrupt, and on top, set counter to 0 - timer_set_reload(STEP_TIMER_DEV, compare); // We reload direct ARR as needed during counting up - break; - case MF_TIMER_TEMP: - timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, compare); - break; - } -} - -FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: - // No counter to clear - timer_generate_update(STEP_TIMER_DEV); - return; - case MF_TIMER_TEMP: - timer_set_count(TEMP_TIMER_DEV, 0); - timer_generate_update(TEMP_TIMER_DEV); - return; - } -} - -#define HAL_timer_isr_epilogue(T) NOOP - -// No command is available in framework to turn off ARPE bit, which is turned on by default in libmaple. -// Needed here to reset ARPE=0 for stepper timer -FORCE_INLINE static void timer_no_ARR_preload_ARPE(timer_dev *dev) { - bb_peri_set_bit(&(dev->regs).gen->CR1, TIMER_CR1_ARPE_BIT, 0); -} - -void HAL_timer_set_interrupt_priority(uint_fast8_t timer_num, uint_fast8_t priority); - -#define TIMER_OC_NO_PRELOAD 0 // Need to disable preload also on compare registers. diff --git a/src/HAL/TEENSY31_32/HAL.cpp b/src/HAL/TEENSY31_32/HAL.cpp deleted file mode 100644 index 2892368..0000000 --- a/src/HAL/TEENSY31_32/HAL.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for Teensy 3.2 (MK20DX256) - */ - -#ifdef __MK20DX256__ - -#include "HAL.h" -#include "../shared/Delay.h" - -#include - -// ------------------------ -// Serial ports -// ------------------------ - -#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X) -#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X) -#if WITHIN(SERIAL_PORT, 0, 3) - IMPLEMENT_SERIAL(SERIAL_PORT); -#else - #error "SERIAL_PORT must be from 0 to 3." -#endif -USBSerialType USBSerial(false, SerialUSB); - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -void MarlinHAL::reboot() { _reboot_Teensyduino_(); } - -uint8_t MarlinHAL::get_reset_source() { - switch (RCM_SRS0) { - case 128: return RST_POWER_ON; break; - case 64: return RST_EXTERNAL; break; - case 32: return RST_WATCHDOG; break; - // case 8: return RST_LOSS_OF_LOCK; break; - // case 4: return RST_LOSS_OF_CLOCK; break; - // case 2: return RST_LOW_VOLTAGE; break; - } - return 0; -} - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT_MS TERN(WATCHDOG_DURATION_8S, 8000, 4000) // 4 or 8 second timeout - - void MarlinHAL::watchdog_init() { - WDOG_TOVALH = 0; - WDOG_TOVALL = WDT_TIMEOUT_MS; - WDOG_STCTRLH = WDOG_STCTRLH_WDOGEN; - } - - void MarlinHAL::watchdog_refresh() { - // Watchdog refresh sequence - WDOG_REFRESH = 0xA602; - WDOG_REFRESH = 0xB480; - } - -#endif - -// ------------------------ -// ADC -// ------------------------ - -void MarlinHAL::adc_init() { - analog_init(); - while (ADC0_SC3 & ADC_SC3_CAL) {}; // Wait for calibration to finish - NVIC_ENABLE_IRQ(IRQ_FTM1); -} - -void MarlinHAL::adc_start(const pin_t pin) { - static const uint8_t pin2sc1a[] = { - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13 - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9) - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33 - 0+64, 19+64, 3+64, 31+64, // 34-37 (A10-A13) - 26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0. - }; - ADC0_SC1A = pin2sc1a[pin]; -} - -uint16_t MarlinHAL::adc_value() { return ADC0_RA; } - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -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 // __MK20DX256__ diff --git a/src/HAL/TEENSY31_32/HAL.h b/src/HAL/TEENSY31_32/HAL.h deleted file mode 100644 index a7aa9f0..0000000 --- a/src/HAL/TEENSY31_32/HAL.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Teensy 3.2 (MK20DX256) - */ - -#define CPU_32_BIT - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" - -#include "fastio.h" - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define IS_32BIT_TEENSY 1 -#define IS_TEENSY_31_32 1 -#ifndef IS_TEENSY31 - #define IS_TEENSY32 1 -#endif - -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -// ------------------------ -// Serial ports -// ------------------------ - -#include "../../core/serial_hook.h" - -#define Serial0 Serial -#define _DECLARE_SERIAL(X) \ - typedef ForwardSerial1Class DefaultSerial##X; \ - extern DefaultSerial##X MSerial##X -#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X) - -typedef ForwardSerial1Class USBSerialType; -extern USBSerialType USBSerial; - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if SERIAL_PORT == -1 - #define MYSERIAL1 USBSerial -#elif WITHIN(SERIAL_PORT, 0, 3) - DECLARE_SERIAL(SERIAL_PORT); - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #error "The required SERIAL_PORT must be from 0 to 3, or -1 for Native USB." -#endif - -// ------------------------ -// Types -// ------------------------ - -class libServo; -typedef libServo hal_servo_t; - -typedef int8_t pin_t; - -// ------------------------ -// Interrupts -// ------------------------ - -uint32_t __get_PRIMASK(void); // CMSIS -#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() - -// ------------------------ -// ADC -// ------------------------ - -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) -#endif - -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -// ------------------------ -// Class Utilities -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -extern "C" int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init() {} // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_PRIMASK(); } - static void isr_on() { __enable_irq(); } - static void isr_off() { __disable_irq(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t ch) {} - - // Begin ADC sampling on the given channel. Called from Temperature::isr! - static void adc_start(const pin_t ch); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -}; diff --git a/src/HAL/TEENSY31_32/HAL_SPI.cpp b/src/HAL/TEENSY31_32/HAL_SPI.cpp deleted file mode 100644 index 415c692..0000000 --- a/src/HAL/TEENSY31_32/HAL_SPI.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __MK20DX256__ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include -#include -#include "spi_pins.h" - -static SPISettings spiConfig; - -/** - * Standard SPI functions - */ - -// Initialize SPI bus -void spiBegin() { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - SET_OUTPUT(SD_SCK_PIN); - SET_INPUT(SD_MISO_PIN); - SET_OUTPUT(SD_MOSI_PIN); - - #if 0 && DISABLED(SOFTWARE_SPI) - // set SS high - may be chip select for another SPI device - #if SET_SPI_SS_HIGH - WRITE(SD_SS_PIN, HIGH); - #endif - // set a default rate - spiInit(SPI_HALF_SPEED); // 1 - #endif -} - -// Configure SPI for specified SPI speed -void spiInit(uint8_t spiRate) { - // Use data rates Marlin uses - uint32_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = 10000000; break; - case SPI_HALF_SPEED: clock = 5000000; break; - case SPI_QUARTER_SPEED: clock = 2500000; break; - case SPI_EIGHTH_SPEED: clock = 1250000; break; - case SPI_SPEED_5: clock = 625000; break; - case SPI_SPEED_6: clock = 312500; break; - default: clock = 4000000; // Default from the SPI library - } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - SPI.begin(); -} - -// SPI receive a byte -uint8_t spiRec() { - SPI.beginTransaction(spiConfig); - const uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); - return returnByte; - //SPDR = 0xFF; - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //return SPDR; -} - -// SPI read data -void spiRead(uint8_t *buf, uint16_t nbyte) { - SPI.beginTransaction(spiConfig); - SPI.transfer(buf, nbyte); - SPI.endTransaction(); - //if (nbyte-- == 0) return; - // SPDR = 0xFF; - //for (uint16_t i = 0; i < nbyte; i++) { - // while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - // buf[i] = SPDR; - // SPDR = 0xFF; - //} - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //buf[nbyte] = SPDR; -} - -// SPI send a byte -void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); - SPI.transfer(b); - SPI.endTransaction(); - //SPDR = b; - //while (!TEST(SPSR, SPIF)) { /* nada */ } -} - -// SPI send block -void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI.beginTransaction(spiConfig); - SPDR = token; - for (uint16_t i = 0; i < 512; i += 2) { - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i]; - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i + 1]; - } - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPI.endTransaction(); -} - - -// Begin SPI transaction, set clock, bit order, data mode -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, bitOrder, dataMode); - SPI.beginTransaction(spiConfig); -} - -#endif // __MK20DX256__ diff --git a/src/HAL/TEENSY31_32/MarlinSPI.h b/src/HAL/TEENSY31_32/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/TEENSY31_32/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/TEENSY31_32/Servo.cpp b/src/HAL/TEENSY31_32/Servo.cpp deleted file mode 100644 index 19d57cf..0000000 --- a/src/HAL/TEENSY31_32/Servo.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __MK20DX256__ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "Servo.h" - -uint8_t servoPin[MAX_SERVOS] = { 0 }; - -int8_t libServo::attach(const int inPin) { - if (servoIndex >= MAX_SERVOS) return -1; - if (inPin > 0) servoPin[servoIndex] = inPin; - return super::attach(servoPin[servoIndex]); -} - -int8_t libServo::attach(const int inPin, const int inMin, const int inMax) { - if (inPin > 0) servoPin[servoIndex] = inPin; - return super::attach(servoPin[servoIndex], inMin, inMax); -} - -void libServo::move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - if (attach(0) >= 0) { - write(value); - safe_delay(servo_delay[servoIndex]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -#endif // HAS_SERVOS -#endif // __MK20DX256__ diff --git a/src/HAL/TEENSY31_32/Servo.h b/src/HAL/TEENSY31_32/Servo.h deleted file mode 100644 index 82b601d..0000000 --- a/src/HAL/TEENSY31_32/Servo.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -// Inherit and expand on the official library -class libServo : public Servo { - public: - int8_t attach(const int pin); - int8_t attach(const int pin, const int min, const int max); - void move(const int value); - private: - typedef Servo super; - uint16_t min_ticks; - uint16_t max_ticks; - uint8_t servoIndex; // index into the channel data for this servo -}; diff --git a/src/HAL/TEENSY31_32/eeprom.cpp b/src/HAL/TEENSY31_32/eeprom.cpp deleted file mode 100644 index d1ff940..0000000 --- a/src/HAL/TEENSY31_32/eeprom.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifdef __MK20DX256__ - -/** - * HAL PersistentStore for Teensy 3.2 (MK20DX256) - */ - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -#include "../shared/eeprom_api.h" -#include - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // __MK20DX256__ diff --git a/src/HAL/TEENSY31_32/endstop_interrupts.h b/src/HAL/TEENSY31_32/endstop_interrupts.h deleted file mode 100644 index 9c7e210..0000000 --- a/src/HAL/TEENSY31_32/endstop_interrupts.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Endstop Interrupts - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -/** - * Endstop interrupts for Due based targets. - * On Due, all pins support external interrupt capability. - */ - -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/TEENSY31_32/fastio.h b/src/HAL/TEENSY31_32/fastio.h deleted file mode 100644 index 622799e..0000000 --- a/src/HAL/TEENSY31_32/fastio.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for Teensy 3.5 and Teensy 3.6 - * Use direct port manipulation to save scads of processor time. - * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. - */ - -#ifndef MASK - #define MASK(PIN) _BV(PIN) -#endif - -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW); - * - * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html - */ - -#define _READ(P) bool(CORE_PIN ## P ## _PINREG & CORE_PIN ## P ## _BITMASK) - -#define _WRITE(P,V) do{ \ - if (V) CORE_PIN ## P ## _PORTSET = CORE_PIN ## P ## _BITMASK; \ - else CORE_PIN ## P ## _PORTCLEAR = CORE_PIN ## P ## _BITMASK; \ -}while(0) - -#define _TOGGLE(P) (*(&(CORE_PIN ## P ## _PORTCLEAR)+1) = CORE_PIN ## P ## _BITMASK) - -#define _SET_INPUT(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1); \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \ -}while(0) - -#define _SET_OUTPUT(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 1; \ -}while(0) - -#define _SET_INPUT_PULLUP(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \ -}while(0) - -#define _IS_INPUT(P) ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) -#define _IS_OUTPUT(P) ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) - -#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) _SET_INPUT_PULLUP(IO) -#define SET_INPUT_PULLDOWN SET_INPUT -#define SET_OUTPUT(IO) _SET_OUTPUT(IO) -#define SET_PWM SET_OUTPUT - -#define IS_INPUT(IO) _IS_INPUT(IO) -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -#define PWM_PIN(P) digitalPinHasPWM(P) - -/** - * Ports, functions, and pins - */ - -#define DIO0_PIN 8 diff --git a/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h b/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h deleted file mode 100644 index 54ec166..0000000 --- a/src/HAL/TEENSY31_32/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/TEENSY31_32." -#endif diff --git a/src/HAL/TEENSY31_32/inc/Conditionals_adv.h b/src/HAL/TEENSY31_32/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/TEENSY31_32/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/TEENSY31_32/inc/Conditionals_post.h b/src/HAL/TEENSY31_32/inc/Conditionals_post.h deleted file mode 100644 index 998f1dc..0000000 --- a/src/HAL/TEENSY31_32/inc/Conditionals_post.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define USE_WIRED_EEPROM 1 -#endif diff --git a/src/HAL/TEENSY31_32/inc/SanityCheck.h b/src/HAL/TEENSY31_32/inc/SanityCheck.h deleted file mode 100644 index dbce187..0000000 --- a/src/HAL/TEENSY31_32/inc/SanityCheck.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test TEENSY35_36 specific configuration values for errors at compile-time. - */ - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.1/3.2. Disable EMERGENCY_PARSER to continue." -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 3.1/3.2." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on Teensy 3.1/3.2." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.1/3.2." -#endif - -#if USING_PULLDOWNS - #error "PULLDOWN pin mode is not available on Teensy 3.1/3.2 boards." -#endif diff --git a/src/HAL/TEENSY31_32/pinsDebug.h b/src/HAL/TEENSY31_32/pinsDebug.h deleted file mode 100644 index d4a91ce..0000000 --- a/src/HAL/TEENSY31_32/pinsDebug.h +++ /dev/null @@ -1 +0,0 @@ -#error "PINS_DEBUGGING is not yet supported for Teensy 3.1 / 3.2!" diff --git a/src/HAL/TEENSY31_32/spi_pins.h b/src/HAL/TEENSY31_32/spi_pins.h deleted file mode 100644 index 6d0d05f..0000000 --- a/src/HAL/TEENSY31_32/spi_pins.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define SD_SCK_PIN 13 -#define SD_MISO_PIN 12 -#define SD_MOSI_PIN 11 -#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29 diff --git a/src/HAL/TEENSY31_32/timers.cpp b/src/HAL/TEENSY31_32/timers.cpp deleted file mode 100644 index f217715..0000000 --- a/src/HAL/TEENSY31_32/timers.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Timers for Teensy 3.2 (MK20DX256) - */ - -#ifdef __MK20DX256__ - -#include "../../inc/MarlinConfig.h" - -/** \brief Instruction Synchronization Barrier - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. -*/ -FORCE_INLINE static void __ISB() { - __asm__ __volatile__("isb 0xF":::"memory"); -} - -/** \brief Data Synchronization Barrier - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. -*/ -FORCE_INLINE static void __DSB() { - __asm__ __volatile__("dsb 0xF":::"memory"); -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - switch (timer_num) { - case MF_TIMER_STEP: - FTM0_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; - FTM0_SC = 0x00; // Set this to zero before changing the modulus - FTM0_CNT = 0x0000; // Reset the count to zero - FTM0_MOD = 0xFFFF; // max modulus = 65535 - FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value - FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8 - FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA; - break; - case MF_TIMER_TEMP: - FTM1_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; // Disable write protection, Enable FTM1 - FTM1_SC = 0x00; // Set this to zero before changing the modulus - FTM1_CNT = 0x0000; // Reset the count to zero - FTM1_MOD = 0xFFFF; // max modulus = 65535 - FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535 - FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4 - FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA; - break; - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_ENABLE_IRQ(IRQ_FTM0); break; - case MF_TIMER_TEMP: NVIC_ENABLE_IRQ(IRQ_FTM1); break; - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_DISABLE_IRQ(IRQ_FTM0); break; - case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_FTM1); break; - } - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return NVIC_IS_ENABLED(IRQ_FTM0); - case MF_TIMER_TEMP: return NVIC_IS_ENABLED(IRQ_FTM1); - } - return false; -} - -void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: - FTM0_CNT = 0x0000; - FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag - FTM0_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag - break; - case MF_TIMER_TEMP: - FTM1_CNT = 0x0000; - FTM1_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag - FTM1_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag - break; - } -} - -#endif // __MK20DX256__ diff --git a/src/HAL/TEENSY31_32/timers.h b/src/HAL/TEENSY31_32/timers.h deleted file mode 100644 index 9fcbb6f..0000000 --- a/src/HAL/TEENSY31_32/timers.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Timers for Teensy 3.2 (MK20DX256) - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define FTM0_TIMER_PRESCALE 8 -#define FTM1_TIMER_PRESCALE 4 -#define FTM0_TIMER_PRESCALE_BITS 0b011 -#define FTM1_TIMER_PRESCALE_BITS 0b010 - -#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz -#define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz - -#define HAL_TIMER_RATE (FTM0_TIMER_RATE) - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif - -#define TEMP_TIMER_FREQUENCY 1000 - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() -#endif - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - switch (timer_num) { - case MF_TIMER_STEP: FTM0_C0V = compare; break; - case MF_TIMER_TEMP: FTM1_C0V = compare; break; - } -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return FTM0_C0V; - case MF_TIMER_TEMP: return FTM1_C0V; - } - return 0; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return FTM0_CNT; - case MF_TIMER_TEMP: return FTM1_CNT; - } - return 0; -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -void HAL_timer_isr_prologue(const uint8_t timer_num); -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/TEENSY35_36/HAL.cpp b/src/HAL/TEENSY35_36/HAL.cpp deleted file mode 100644 index bc02ac1..0000000 --- a/src/HAL/TEENSY35_36/HAL.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) - -#include "HAL.h" -#include "../shared/Delay.h" - -#include - -// ------------------------ -// Serial ports -// ------------------------ - -#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X) -#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X) -#if WITHIN(SERIAL_PORT, 0, 3) - IMPLEMENT_SERIAL(SERIAL_PORT); -#endif - -USBSerialType USBSerial(false, SerialUSB); - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -void MarlinHAL::reboot() { _reboot_Teensyduino_(); } - -uint8_t MarlinHAL::get_reset_source() { - switch (RCM_SRS0) { - case 128: return RST_POWER_ON; break; - case 64: return RST_EXTERNAL; break; - case 32: return RST_WATCHDOG; break; - // case 8: return RST_LOSS_OF_LOCK; break; - // case 4: return RST_LOSS_OF_CLOCK; break; - // case 2: return RST_LOW_VOLTAGE; break; - } - return 0; -} - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT_MS TERN(WATCHDOG_DURATION_8S, 8000, 4000) // 4 or 8 second timeout - - void MarlinHAL::watchdog_init() { - WDOG_TOVALH = 0; - WDOG_TOVALL = WDT_TIMEOUT_MS; - WDOG_STCTRLH = WDOG_STCTRLH_WDOGEN; - } - - void MarlinHAL::watchdog_refresh() { - // Watchdog refresh sequence - WDOG_REFRESH = 0xA602; - WDOG_REFRESH = 0xB480; - } - -#endif - -// ------------------------ -// ADC -// ------------------------ - -int8_t MarlinHAL::adc_select; - -void MarlinHAL::adc_init() { - analog_init(); - while (ADC0_SC3 & ADC_SC3_CAL) { /* Wait for calibration to finish */ } - while (ADC1_SC3 & ADC_SC3_CAL) { /* Wait for calibration to finish */ } - NVIC_ENABLE_IRQ(IRQ_FTM1); -} - -void MarlinHAL::adc_start(const pin_t adc_pin) { - static const uint8_t pin2sc1a[] = { - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 19+128, 14+128, 15+128, // 0-13 -> A0-A13 - 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9 - 255, 255, 255, 255, 255, 255, 255, // 24-30 are digital only - 14+128, 15+128, 17, 18, 4+128, 5+128, 6+128, 7+128, 17+128, // 31-39 are A12-A20 - 255, 255, 255, 255, 255, 255, 255, 255, 255, // 40-48 are digital only - 10+128, 11+128, // 49-50 are A23-A24 - 255, 255, 255, 255, 255, 255, 255, // 51-57 are digital only - 255, 255, 255, 255, 255, 255, // 58-63 (sd card pins) are digital only - 3, 19+128, // 64-65 are A10-A11 - 23, 23+128,// 66-67 are A21-A22 (DAC pins) - 1, 1+128, // 68-69 are A25-A26 (unused USB host port on Teensy 3.5) - 26, // 70 is Temperature Sensor - 18+128 // 71 is Vref - }; - const uint16_t pin = pin2sc1a[adc_pin]; - if (pin == 0xFF) { - adc_select = -1; // Digital only - } - else if (pin & 0x80) { - adc_select = 1; - ADC1_SC1A = pin & 0x7F; - } - else { - adc_select = 0; - ADC0_SC1A = pin; - } -} - -uint16_t MarlinHAL::adc_value() { - switch (adc_select) { - case 0: return ADC0_RA; - case 1: return ADC1_RA; - } - return 0; -} - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -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 // __MK64FX512__ || __MK66FX1M0__ diff --git a/src/HAL/TEENSY35_36/HAL.h b/src/HAL/TEENSY35_36/HAL.h deleted file mode 100644 index 2a192e4..0000000 --- a/src/HAL/TEENSY35_36/HAL.h +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#define CPU_32_BIT - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" - -#include "fastio.h" - -#include -#include - -// ------------------------ -// Defines -// ------------------------ - -#define IS_32BIT_TEENSY 1 -#define IS_TEENSY_35_36 1 -#ifdef __MK66FX1M0__ - #define IS_TEENSY36 1 -#else // __MK64FX512__ - #define IS_TEENSY35 1 -#endif - -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -#undef sq -#define sq(x) ((x)*(x)) - -// ------------------------ -// Serial ports -// ------------------------ - -#include "../../core/serial_hook.h" - -#define Serial0 Serial -#define _DECLARE_SERIAL(X) \ - typedef ForwardSerial1Class DefaultSerial##X; \ - extern DefaultSerial##X MSerial##X -#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X) - -typedef ForwardSerial1Class USBSerialType; -extern USBSerialType USBSerial; - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if SERIAL_PORT == -1 - #define MYSERIAL1 USBSerial -#elif WITHIN(SERIAL_PORT, 0, 3) - #define MYSERIAL1 MSERIAL(SERIAL_PORT) - DECLARE_SERIAL(SERIAL_PORT); -#else - #error "SERIAL_PORT must be from 0 to 3, or -1 for Native USB." -#endif - -// ------------------------ -// Types -// ------------------------ - -class libServo; -typedef libServo hal_servo_t; - -typedef int8_t pin_t; - -// ------------------------ -// Interrupts -// ------------------------ - -#define CRITICAL_SECTION_START() const bool irqon = !__get_primask(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() - -// ------------------------ -// ADC -// ------------------------ - -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) -#endif - -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -extern "C" int freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init() {} // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return true; } - static void isr_on() { __enable_irq(); } - static void isr_off() { __disable_irq(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source() {} - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static int8_t adc_select; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t) {} - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -}; diff --git a/src/HAL/TEENSY35_36/HAL_SPI.cpp b/src/HAL/TEENSY35_36/HAL_SPI.cpp deleted file mode 100644 index d80f57b..0000000 --- a/src/HAL/TEENSY35_36/HAL_SPI.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL SPI for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include -#include -#include "spi_pins.h" - -static SPISettings spiConfig; - -void spiBegin() { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - SET_OUTPUT(SD_SCK_PIN); - SET_INPUT(SD_MISO_PIN); - SET_OUTPUT(SD_MOSI_PIN); - - #if 0 && DISABLED(SOFTWARE_SPI) - // set SS high - may be chip select for another SPI device - #if SET_SPI_SS_HIGH - WRITE(SD_SS_PIN, HIGH); - #endif - // set a default rate - spiInit(SPI_HALF_SPEED); // 1 - #endif -} - -void spiInit(uint8_t spiRate) { - // Use Marlin data-rates - uint32_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = 10000000; break; - case SPI_HALF_SPEED: clock = 5000000; break; - case SPI_QUARTER_SPEED: clock = 2500000; break; - case SPI_EIGHTH_SPEED: clock = 1250000; break; - case SPI_SPEED_5: clock = 625000; break; - case SPI_SPEED_6: clock = 312500; break; - default: - clock = 4000000; // Default from the SPI library - } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - SPI.begin(); -} - -uint8_t spiRec() { - SPI.beginTransaction(spiConfig); - uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); - return returnByte; - //SPDR = 0xFF; - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //return SPDR; -} - -void spiRead(uint8_t *buf, uint16_t nbyte) { - SPI.beginTransaction(spiConfig); - SPI.transfer(buf, nbyte); - SPI.endTransaction(); - //if (nbyte-- == 0) return; - // SPDR = 0xFF; - //for (uint16_t i = 0; i < nbyte; i++) { - // while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - // buf[i] = SPDR; - // SPDR = 0xFF; - //} - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //buf[nbyte] = SPDR; -} - -void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); - SPI.transfer(b); - SPI.endTransaction(); - //SPDR = b; - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } -} - -void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI.beginTransaction(spiConfig); - SPDR = token; - for (uint16_t i = 0; i < 512; i += 2) { - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i]; - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i + 1]; - } - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPI.endTransaction(); -} - -// Begin SPI transaction, set clock, bit order, data mode -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, bitOrder, dataMode); - SPI.beginTransaction(spiConfig); -} - -#endif // __MK64FX512__ || __MK66FX1M0__ diff --git a/src/HAL/TEENSY35_36/MarlinSPI.h b/src/HAL/TEENSY35_36/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/TEENSY35_36/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/TEENSY35_36/Servo.cpp b/src/HAL/TEENSY35_36/Servo.cpp deleted file mode 100644 index 0338585..0000000 --- a/src/HAL/TEENSY35_36/Servo.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Servo for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "Servo.h" - -uint8_t servoPin[MAX_SERVOS] = { 0 }; - -int8_t libServo::attach(const int inPin) { - if (servoIndex >= MAX_SERVOS) return -1; - if (inPin > 0) servoPin[servoIndex] = inPin; - return super::attach(servoPin[servoIndex]); -} - -int8_t libServo::attach(const int inPin, const int inMin, const int inMax) { - if (inPin > 0) servoPin[servoIndex] = inPin; - return super::attach(servoPin[servoIndex], inMin, inMax); -} - -void libServo::move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - if (attach(0) >= 0) { - write(value); - safe_delay(servo_delay[servoIndex]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -#endif // HAS_SERVOS -#endif // __MK64FX512__ || __MK66FX1M0__ diff --git a/src/HAL/TEENSY35_36/Servo.h b/src/HAL/TEENSY35_36/Servo.h deleted file mode 100644 index 719011f..0000000 --- a/src/HAL/TEENSY35_36/Servo.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Servo for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#include - -// Inherit and expand on core Servo library -class libServo : public Servo { - public: - int8_t attach(const int pin); - int8_t attach(const int pin, const int min, const int max); - void move(const int value); - private: - typedef Servo super; - uint16_t min_ticks; - uint16_t max_ticks; - uint8_t servoIndex; // Index into the channel data for this servo -}; diff --git a/src/HAL/TEENSY35_36/eeprom.cpp b/src/HAL/TEENSY35_36/eeprom.cpp deleted file mode 100644 index b80e93b..0000000 --- a/src/HAL/TEENSY35_36/eeprom.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) - -/** - * HAL PersistentStore for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -#include "../shared/eeprom_api.h" -#include - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // __MK64FX512__ || __MK66FX1M0__ diff --git a/src/HAL/TEENSY35_36/endstop_interrupts.h b/src/HAL/TEENSY35_36/endstop_interrupts.h deleted file mode 100644 index a300248..0000000 --- a/src/HAL/TEENSY35_36/endstop_interrupts.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Endstop Interrupts for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -/** - * Endstop interrupts for Due based targets. - * On Due, all pins support external interrupt capability. - */ -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/TEENSY35_36/fastio.h b/src/HAL/TEENSY35_36/fastio.h deleted file mode 100644 index 622799e..0000000 --- a/src/HAL/TEENSY35_36/fastio.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O Routines for Teensy 3.5 and Teensy 3.6 - * Use direct port manipulation to save scads of processor time. - * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. - */ - -#ifndef MASK - #define MASK(PIN) _BV(PIN) -#endif - -#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) -#define GPIO_BITBAND(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) - -/** - * Magic I/O routines - * - * Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW); - * - * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html - */ - -#define _READ(P) bool(CORE_PIN ## P ## _PINREG & CORE_PIN ## P ## _BITMASK) - -#define _WRITE(P,V) do{ \ - if (V) CORE_PIN ## P ## _PORTSET = CORE_PIN ## P ## _BITMASK; \ - else CORE_PIN ## P ## _PORTCLEAR = CORE_PIN ## P ## _BITMASK; \ -}while(0) - -#define _TOGGLE(P) (*(&(CORE_PIN ## P ## _PORTCLEAR)+1) = CORE_PIN ## P ## _BITMASK) - -#define _SET_INPUT(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1); \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \ -}while(0) - -#define _SET_OUTPUT(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 1; \ -}while(0) - -#define _SET_INPUT_PULLUP(P) do{ \ - CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; \ - GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \ -}while(0) - -#define _IS_INPUT(P) ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) -#define _IS_OUTPUT(P) ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) - -#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) _SET_INPUT_PULLUP(IO) -#define SET_INPUT_PULLDOWN SET_INPUT -#define SET_OUTPUT(IO) _SET_OUTPUT(IO) -#define SET_PWM SET_OUTPUT - -#define IS_INPUT(IO) _IS_INPUT(IO) -#define IS_OUTPUT(IO) _IS_OUTPUT(IO) - -#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) - -#define PWM_PIN(P) digitalPinHasPWM(P) - -/** - * Ports, functions, and pins - */ - -#define DIO0_PIN 8 diff --git a/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h b/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h deleted file mode 100644 index 632ee53..0000000 --- a/src/HAL/TEENSY35_36/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/TEENSY35_36." -#endif diff --git a/src/HAL/TEENSY35_36/inc/Conditionals_adv.h b/src/HAL/TEENSY35_36/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/TEENSY35_36/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/TEENSY35_36/inc/Conditionals_post.h b/src/HAL/TEENSY35_36/inc/Conditionals_post.h deleted file mode 100644 index 998f1dc..0000000 --- a/src/HAL/TEENSY35_36/inc/Conditionals_post.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define USE_WIRED_EEPROM 1 -#endif diff --git a/src/HAL/TEENSY35_36/inc/SanityCheck.h b/src/HAL/TEENSY35_36/inc/SanityCheck.h deleted file mode 100644 index 3308707..0000000 --- a/src/HAL/TEENSY35_36/inc/SanityCheck.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test TEENSY35_36 specific configuration values for errors at compile-time. - */ - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for Teensy 3.5/3.6. Disable EMERGENCY_PARSER to continue." -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 3.5/3.6." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on Teensy 3.5/3.6." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.5/3.6." -#endif - -#if USING_PULLDOWNS - #error "PULLDOWN pin mode is not available on Teensy 3.5/3.6 boards." -#endif diff --git a/src/HAL/TEENSY35_36/pinsDebug.h b/src/HAL/TEENSY35_36/pinsDebug.h deleted file mode 100644 index 7a2e1d6..0000000 --- a/src/HAL/TEENSY35_36/pinsDebug.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Pins Debugging for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin - -#define FTM0_CH0_PIN 22 -#define FTM0_CH1_PIN 23 -#define FTM0_CH2_PIN 9 -#define FTM0_CH3_PIN 10 -#define FTM0_CH4_PIN 6 -#define FTM0_CH5_PIN 20 -#define FTM0_CH6_PIN 21 -#define FTM0_CH7_PIN 5 -#define FTM1_CH0_PIN 3 -#define FTM1_CH1_PIN 4 -#define FTM2_CH0_PIN 29 -#define FTM2_CH1_PIN 30 -#define FTM3_CH0_PIN 2 -#define FTM3_CH1_PIN 14 -#define FTM3_CH2_PIN 7 -#define FTM3_CH3_PIN 8 -#define FTM3_CH4_PIN 35 -#define FTM3_CH5_PIN 36 -#define FTM3_CH6_PIN 37 -#define FTM3_CH7_PIN 38 -#ifdef __MK66FX1M0__ // Teensy3.6 - #define TPM1_CH0_PIN 16 - #define TPM1_CH1_PIN 17 -#endif - -#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(9)) || ((P) >= analogInputToDigitalPin(12) && (P) <= analogInputToDigitalPin(20)) - -void HAL_print_analog_pin(char buffer[], int8_t pin) { - if (pin <= 23) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 14)); - else if (pin <= 39) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 19)); -} - -void HAL_analog_pin_state(char buffer[], int8_t pin) { - if (pin <= 23) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 14)); - else if (pin <= 39) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 19)); -} - -#define PWM_PRINT(V) do{ sprintf_P(buffer, PSTR("PWM: %4d"), 22); SERIAL_ECHO(buffer); }while(0) -#define FTM_CASE(N,Z) \ - case FTM##N##_CH##Z##_PIN: \ - if (FTM##N##_C##Z##V) { \ - PWM_PRINT(FTM##N##_C##Z##V); \ - return true; \ - } else return false - -/** - * Print a pin's PWM status. - * Return true if it's currently a PWM pin. - */ -bool HAL_pwm_status(int8_t pin) { - char buffer[20]; // for the sprintf statements - switch (pin) { - FTM_CASE(0,0); - FTM_CASE(0,1); - FTM_CASE(0,2); - FTM_CASE(0,3); - FTM_CASE(0,4); - FTM_CASE(0,5); - FTM_CASE(0,6); - FTM_CASE(0,7); - FTM_CASE(1,0); - FTM_CASE(1,1); - FTM_CASE(2,0); - FTM_CASE(2,1); - FTM_CASE(3,0); - FTM_CASE(3,1); - FTM_CASE(3,2); - FTM_CASE(3,3); - FTM_CASE(3,4); - FTM_CASE(3,5); - FTM_CASE(3,6); - FTM_CASE(3,7); - - case NOT_ON_TIMER: - default: - return false; - } - SERIAL_ECHOPGM(" "); -} - -static void HAL_pwm_details(uint8_t pin) { /* TODO */ } diff --git a/src/HAL/TEENSY35_36/spi_pins.h b/src/HAL/TEENSY35_36/spi_pins.h deleted file mode 100644 index cfffdc9..0000000 --- a/src/HAL/TEENSY35_36/spi_pins.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL SPI Pins for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#define SD_SCK_PIN 13 -#define SD_MISO_PIN 12 -#define SD_MOSI_PIN 11 -#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29 diff --git a/src/HAL/TEENSY35_36/timers.cpp b/src/HAL/TEENSY35_36/timers.cpp deleted file mode 100644 index 39095fb..0000000 --- a/src/HAL/TEENSY35_36/timers.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Timers for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#if defined(__MK64FX512__) || defined(__MK66FX1M0__) - -#include "../../inc/MarlinConfig.h" - -/** \brief Instruction Synchronization Barrier - Instruction Synchronization Barrier flushes the pipeline in the processor, - so that all instructions following the ISB are fetched from cache or - memory, after the instruction has been completed. -*/ -FORCE_INLINE static void __ISB() { - __asm__ __volatile__("isb 0xF":::"memory"); -} - -/** \brief Data Synchronization Barrier - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. -*/ -FORCE_INLINE static void __DSB() { - __asm__ __volatile__("dsb 0xF":::"memory"); -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - switch (timer_num) { - case MF_TIMER_STEP: - FTM0_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; - FTM0_SC = 0x00; // Set this to zero before changing the modulus - FTM0_CNT = 0x0000; // Reset the count to zero - FTM0_MOD = 0xFFFF; // max modulus = 65535 - FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value - FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8 - FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA; - break; - case MF_TIMER_TEMP: - FTM1_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; // Disable write protection, Enable FTM1 - FTM1_SC = 0x00; // Set this to zero before changing the modulus - FTM1_CNT = 0x0000; // Reset the count to zero - FTM1_MOD = 0xFFFF; // max modulus = 65535 - FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535 - FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4 - FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA; - break; - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_ENABLE_IRQ(IRQ_FTM0); break; - case MF_TIMER_TEMP: NVIC_ENABLE_IRQ(IRQ_FTM1); break; - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_DISABLE_IRQ(IRQ_FTM0); break; - case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_FTM1); break; - } - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - __DSB(); - __ISB(); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return NVIC_IS_ENABLED(IRQ_FTM0); - case MF_TIMER_TEMP: return NVIC_IS_ENABLED(IRQ_FTM1); - } - return false; -} - -void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: - FTM0_CNT = 0x0000; - FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag - FTM0_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag - break; - case MF_TIMER_TEMP: - FTM1_CNT = 0x0000; - FTM1_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag - FTM1_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag - break; - } -} - -#endif // Teensy3.5 or Teensy3.6 diff --git a/src/HAL/TEENSY35_36/timers.h b/src/HAL/TEENSY35_36/timers.h deleted file mode 100644 index 8af79d7..0000000 --- a/src/HAL/TEENSY35_36/timers.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Timers for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF - -#define FTM0_TIMER_PRESCALE 8 -#define FTM1_TIMER_PRESCALE 4 -#define FTM0_TIMER_PRESCALE_BITS 0b011 -#define FTM1_TIMER_PRESCALE_BITS 0b010 - -#define FTM0_TIMER_RATE (F_BUS / FTM0_TIMER_PRESCALE) // 60MHz / 8 = 7500kHz -#define FTM1_TIMER_RATE (F_BUS / FTM1_TIMER_PRESCALE) // 60MHz / 4 = 15MHz - -#define HAL_TIMER_RATE (FTM0_TIMER_RATE) - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif - -#define TEMP_TIMER_FREQUENCY 1000 - -#define STEPPER_TIMER_RATE HAL_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void ftm0_isr() //void TC3_Handler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void ftm1_isr() //void TC4_Handler() -#endif - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - switch (timer_num) { - case MF_TIMER_STEP: FTM0_C0V = compare; break; - case MF_TIMER_TEMP: FTM1_C0V = compare; break; - } -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return FTM0_C0V; - case MF_TIMER_TEMP: return FTM1_C0V; - } - return 0; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return FTM0_CNT; - case MF_TIMER_TEMP: return FTM1_CNT; - } - return 0; -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -void HAL_timer_isr_prologue(const uint8_t timer_num); -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/TEENSY40_41/HAL.cpp b/src/HAL/TEENSY40_41/HAL.cpp deleted file mode 100644 index 1d02ab8..0000000 --- a/src/HAL/TEENSY40_41/HAL.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL for Teensy 4.0 / 4.1 (IMXRT1062) - */ - -#ifdef __IMXRT1062__ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include "../shared/Delay.h" -#include "timers.h" -#include - -// ------------------------ -// Serial ports -// ------------------------ - -#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X) -#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X) -#if WITHIN(SERIAL_PORT, 0, 3) - IMPLEMENT_SERIAL(SERIAL_PORT); -#endif -USBSerialType USBSerial(false, SerialUSB); - -// ------------------------ -// FastIO -// ------------------------ - -bool is_output(pin_t pin) { - const struct digital_pin_bitband_and_config_table_struct *p; - p = digital_pin_to_info_PGM + pin; - return (*(p->reg + 1) & p->mask); -} - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -void MarlinHAL::reboot() { _reboot_Teensyduino_(); } - -uint8_t MarlinHAL::get_reset_source() { - switch (SRC_SRSR & 0xFF) { - case 1: return RST_POWER_ON; break; - case 2: return RST_SOFTWARE; break; - case 4: return RST_EXTERNAL; break; - //case 8: return RST_BROWN_OUT; break; - case 16: return RST_WATCHDOG; break; - case 64: return RST_JTAG; break; - //case 128: return RST_OVERTEMP; break; - } - return 0; -} - -void MarlinHAL::clear_reset_source() { - uint32_t reset_source = SRC_SRSR; - SRC_SRSR = reset_source; -} - -// ------------------------ -// Watchdog Timer -// ------------------------ - -#if ENABLED(USE_WATCHDOG) - - #define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8, 4) // 4 or 8 second timeout - - constexpr uint8_t timeoutval = (WDT_TIMEOUT - 0.5f) / 0.5f; - - void MarlinHAL::watchdog_init() { - CCM_CCGR3 |= CCM_CCGR3_WDOG1(3); // enable WDOG1 clocks - WDOG1_WMCR = 0; // disable power down PDE - WDOG1_WCR |= WDOG_WCR_SRS | WDOG_WCR_WT(timeoutval); - WDOG1_WCR |= WDOG_WCR_WDE | WDOG_WCR_WDT | WDOG_WCR_SRE; - } - - void MarlinHAL::watchdog_refresh() { - // Watchdog refresh sequence - WDOG1_WSR = 0x5555; - WDOG1_WSR = 0xAAAA; - } - -#endif - -// ------------------------ -// ADC -// ------------------------ - -int8_t MarlinHAL::adc_select; - -void MarlinHAL::adc_init() { - analog_init(); - while (ADC1_GC & ADC_GC_CAL) { /* wait */ } - while (ADC2_GC & ADC_GC_CAL) { /* wait */ } -} - -void MarlinHAL::adc_start(const pin_t adc_pin) { - static const uint8_t pin2sc1a[] = { - 0x07, // 0/A0 AD_B1_02 - 0x08, // 1/A1 AD_B1_03 - 0x0C, // 2/A2 AD_B1_07 - 0x0B, // 3/A3 AD_B1_06 - 0x06, // 4/A4 AD_B1_01 - 0x05, // 5/A5 AD_B1_00 - 0x0F, // 6/A6 AD_B1_10 - 0x00, // 7/A7 AD_B1_11 - 0x0D, // 8/A8 AD_B1_08 - 0x0E, // 9/A9 AD_B1_09 - 0x01, // 24/A10 AD_B0_12 - 0x02, // 25/A11 AD_B0_13 - 0x83, // 26/A12 AD_B1_14 - only on ADC2, 3 - 0x84, // 27/A13 AD_B1_15 - only on ADC2, 4 - 0x07, // 14/A0 AD_B1_02 - 0x08, // 15/A1 AD_B1_03 - 0x0C, // 16/A2 AD_B1_07 - 0x0B, // 17/A3 AD_B1_06 - 0x06, // 18/A4 AD_B1_01 - 0x05, // 19/A5 AD_B1_00 - 0x0F, // 20/A6 AD_B1_10 - 0x00, // 21/A7 AD_B1_11 - 0x0D, // 22/A8 AD_B1_08 - 0x0E, // 23/A9 AD_B1_09 - 0x01, // 24/A10 AD_B0_12 - 0x02, // 25/A11 AD_B0_13 - 0x83, // 26/A12 AD_B1_14 - only on ADC2, 3 - 0x84, // 27/A13 AD_B1_15 - only on ADC2, 4 - #ifdef ARDUINO_TEENSY41 - 0xFF, // 28 - 0xFF, // 29 - 0xFF, // 30 - 0xFF, // 31 - 0xFF, // 32 - 0xFF, // 33 - 0xFF, // 34 - 0xFF, // 35 - 0xFF, // 36 - 0xFF, // 37 - 0x81, // 38/A14 AD_B1_12 - only on ADC2, 1 - 0x82, // 39/A15 AD_B1_13 - only on ADC2, 2 - 0x09, // 40/A16 AD_B1_04 - 0x0A, // 41/A17 AD_B1_05 - #endif - }; - const uint16_t pin = pin2sc1a[adc_pin]; - if (pin == 0xFF) { - adc_select = -1; // Digital only - } - else if (pin & 0x80) { - adc_select = 1; - ADC2_HC0 = pin & 0x7F; - } - else { - adc_select = 0; - ADC1_HC0 = pin; - } -} - -uint16_t MarlinHAL::adc_value() { - switch (adc_select) { - case 0: - while (!(ADC1_HS & ADC_HS_COCO0)) { /* wait */ } - return ADC1_R0; - case 1: - while (!(ADC2_HS & ADC_HS_COCO0)) { /* wait */ } - return ADC2_R0; - } - return 0; -} - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#define __bss_end _ebss - -extern "C" { - extern char __bss_end; - extern char __heap_start; - extern void* __brkval; - - // Doesn't work on Teensy 4.x - uint32_t freeMemory() { - uint32_t free_memory; - free_memory = ((uint32_t)&free_memory) - (((uint32_t)__brkval) ?: ((uint32_t)&__bss_end)); - return free_memory; - } -} - -#endif // __IMXRT1062__ diff --git a/src/HAL/TEENSY40_41/HAL.h b/src/HAL/TEENSY40_41/HAL.h deleted file mode 100644 index c54a2e8..0000000 --- a/src/HAL/TEENSY40_41/HAL.h +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#define CPU_32_BIT - -#include "../shared/Marduino.h" -#include "../shared/math_32bit.h" -#include "../shared/HAL_SPI.h" - -#include "fastio.h" - -#include -#include - -#if HAS_ETHERNET - #include "../../feature/ethernet.h" -#endif - -// ------------------------ -// Defines -// ------------------------ - -#define IS_32BIT_TEENSY 1 -#define IS_TEENSY_40_41 1 -#ifndef IS_TEENSY40 - #define IS_TEENSY41 1 -#endif - -#define CPU_ST7920_DELAY_1 600 -#define CPU_ST7920_DELAY_2 750 -#define CPU_ST7920_DELAY_3 750 - -#undef sq -#define sq(x) ((x)*(x)) - -// Don't place string constants in PROGMEM -#undef PSTR -#define PSTR(str) ({static const char *data = (str); &data[0];}) - -// ------------------------ -// Serial ports -// ------------------------ - -#include "../../core/serial_hook.h" - -#define Serial0 Serial -#define _DECLARE_SERIAL(X) \ - typedef ForwardSerial1Class DefaultSerial##X; \ - extern DefaultSerial##X MSerial##X -#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X) - -typedef ForwardSerial1Class USBSerialType; -extern USBSerialType USBSerial; - -#define _MSERIAL(X) MSerial##X -#define MSERIAL(X) _MSERIAL(X) - -#if SERIAL_PORT == -1 - #define MYSERIAL1 SerialUSB -#elif WITHIN(SERIAL_PORT, 0, 8) - DECLARE_SERIAL(SERIAL_PORT); - #define MYSERIAL1 MSERIAL(SERIAL_PORT) -#else - #error "The required SERIAL_PORT must be from 0 to 8, or -1 for Native USB." -#endif - -#ifdef SERIAL_PORT_2 - #if SERIAL_PORT_2 == -1 - #define MYSERIAL2 usbSerial - #elif SERIAL_PORT_2 == -2 - #define MYSERIAL2 ethernet.telnetClient - #elif WITHIN(SERIAL_PORT_2, 0, 8) - #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) - #else - #error "SERIAL_PORT_2 must be from 0 to 8, or -1 for Native USB, or -2 for Ethernet." - #endif -#endif - -// ------------------------ -// Types -// ------------------------ - -class libServo; -typedef libServo hal_servo_t; - -typedef int8_t pin_t; - -// ------------------------ -// Interrupts -// ------------------------ - -#define CRITICAL_SECTION_START() const bool irqon = !__get_primask(); __disable_irq() -#define CRITICAL_SECTION_END() if (irqon) __enable_irq() - -// ------------------------ -// ADC -// ------------------------ - -#ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) -#endif - -#define HAL_ADC_VREF 3.3 -#define HAL_ADC_RESOLUTION 10 -#define HAL_ADC_FILTERED // turn off ADC oversampling - -// -// Pin Mapping for M42, M43, M226 -// -#define GET_PIN_MAP_PIN(index) index -#define GET_PIN_MAP_INDEX(pin) pin -#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval) - -// FastIO -bool is_output(pin_t pin); - -// ------------------------ -// Free Memory Accessor -// ------------------------ - -#pragma GCC diagnostic push -#if GCC_VERSION <= 50000 - #pragma GCC diagnostic ignored "-Wunused-function" -#endif - -extern "C" uint32_t freeMemory(); - -#pragma GCC diagnostic pop - -// ------------------------ -// MarlinHAL Class -// ------------------------ - -class MarlinHAL { -public: - - // Earliest possible init, before setup() - MarlinHAL() {} - - // Watchdog - static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); - static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); - - static void init() {} // Called early in setup() - static void init_board() {} // Called less early in setup() - static void reboot(); // Restart the firmware from 0x0 - - // Interrupts - static bool isr_state() { return !__get_primask(); } - static void isr_on() { __enable_irq(); } - static void isr_off() { __disable_irq(); } - - static void delay_ms(const int ms) { delay(ms); } - - // Tasks, called from idle() - static void idletask() {} - - // Reset - static uint8_t get_reset_source(); - static void clear_reset_source(); - - // Free SRAM - static int freeMemory() { return ::freeMemory(); } - - // - // ADC Methods - // - - static int8_t adc_select; - - // Called by Temperature::init once at startup - static void adc_init(); - - // Called by Temperature::init for each sensor at startup - static void adc_enable(const pin_t pin) {} - - // Begin ADC sampling on the given pin. Called from Temperature::isr! - static void adc_start(const pin_t pin); - - // Is the ADC ready for reading? - static bool adc_ready() { return true; } - - // The current value of the ADC register - static uint16_t adc_value(); - - /** - * Set the PWM duty cycle for the pin to the given value. - * No option to invert the duty cycle [default = false] - * No option to change the scale of the provided value to enable finer PWM duty control [default = 255] - */ - static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { - analogWrite(pin, v); - } - -}; diff --git a/src/HAL/TEENSY40_41/HAL_SPI.cpp b/src/HAL/TEENSY40_41/HAL_SPI.cpp deleted file mode 100644 index 9dcb812..0000000 --- a/src/HAL/TEENSY40_41/HAL_SPI.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL SPI for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#ifdef __IMXRT1062__ - -#include "../../inc/MarlinConfig.h" -#include "HAL.h" - -#include -#include -#include "spi_pins.h" - -static SPISettings spiConfig; - -// ------------------------ -// Public functions -// ------------------------ - -#if ENABLED(SOFTWARE_SPI) - // ------------------------ - // Software SPI - // ------------------------ - #error "Software SPI not supported for Teensy 4. Use Hardware SPI." -#else - -// ------------------------ -// Hardware SPI -// ------------------------ - -void spiBegin() { - #if PIN_EXISTS(SD_SS) - OUT_WRITE(SD_SS_PIN, HIGH); - #endif - //SET_OUTPUT(SD_SCK_PIN); - //SET_INPUT(SD_MISO_PIN); - //SET_OUTPUT(SD_MOSI_PIN); - - #if 0 && DISABLED(SOFTWARE_SPI) - // set SS high - may be chip select for another SPI device - #if SET_SPI_SS_HIGH - WRITE(SD_SS_PIN, HIGH); - #endif - // set a default rate - spiInit(SPI_HALF_SPEED); // 1 - #endif -} - -void spiInit(uint8_t spiRate) { - // Use Marlin data-rates - uint32_t clock; - switch (spiRate) { - case SPI_FULL_SPEED: clock = 10000000; break; - case SPI_HALF_SPEED: clock = 5000000; break; - case SPI_QUARTER_SPEED: clock = 2500000; break; - case SPI_EIGHTH_SPEED: clock = 1250000; break; - case SPI_SPEED_5: clock = 625000; break; - case SPI_SPEED_6: clock = 312500; break; - default: - clock = 4000000; // Default from the SPI library - } - spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0); - SPI.begin(); -} - -uint8_t spiRec() { - SPI.beginTransaction(spiConfig); - uint8_t returnByte = SPI.transfer(0xFF); - SPI.endTransaction(); - return returnByte; - //SPDR = 0xFF; - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //return SPDR; -} - -void spiRead(uint8_t *buf, uint16_t nbyte) { - SPI.beginTransaction(spiConfig); - SPI.transfer(buf, nbyte); - SPI.endTransaction(); - //if (nbyte-- == 0) return; - // SPDR = 0xFF; - //for (uint16_t i = 0; i < nbyte; i++) { - // while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - // buf[i] = SPDR; - // SPDR = 0xFF; - //} - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } - //buf[nbyte] = SPDR; -} - -void spiSend(uint8_t b) { - SPI.beginTransaction(spiConfig); - SPI.transfer(b); - SPI.endTransaction(); - //SPDR = b; - //while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ } -} - -void spiSendBlock(uint8_t token, const uint8_t *buf) { - SPI.beginTransaction(spiConfig); - SPDR = token; - for (uint16_t i = 0; i < 512; i += 2) { - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i]; - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPDR = buf[i + 1]; - } - while (!TEST(SPSR, SPIF)) { /* nada */ }; - SPI.endTransaction(); -} - -// Begin SPI transaction, set clock, bit order, data mode -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { - spiConfig = SPISettings(spiClock, bitOrder, dataMode); - SPI.beginTransaction(spiConfig); -} - -#endif // SOFTWARE_SPI -#endif // __IMXRT1062__ diff --git a/src/HAL/TEENSY40_41/MarlinSPI.h b/src/HAL/TEENSY40_41/MarlinSPI.h deleted file mode 100644 index 0c447ba..0000000 --- a/src/HAL/TEENSY40_41/MarlinSPI.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -using MarlinSPI = SPIClass; diff --git a/src/HAL/TEENSY40_41/Servo.cpp b/src/HAL/TEENSY40_41/Servo.cpp deleted file mode 100644 index ffb1102..0000000 --- a/src/HAL/TEENSY40_41/Servo.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Servo for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#ifdef __IMXRT1062__ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "Servo.h" - -int8_t libServo::attach(const int inPin) { - if (inPin > 0) servoPin = inPin; - return super::attach(servoPin); -} - -int8_t libServo::attach(const int inPin, const int inMin, const int inMax) { - if (inPin > 0) servoPin = inPin; - return super::attach(servoPin, inMin, inMax); -} - -void libServo::move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - if (attach(0) >= 0) { - write(value); - safe_delay(servo_delay[servoIndex]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -void libServo::detach() { - // PWMServo library does not have detach() function - //super::detach(); -} - -#endif // HAS_SERVOS -#endif // __IMXRT1062__ diff --git a/src/HAL/TEENSY40_41/Servo.h b/src/HAL/TEENSY40_41/Servo.h deleted file mode 100644 index 699fd70..0000000 --- a/src/HAL/TEENSY40_41/Servo.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Servo for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#include - -// Inherit and expand on core Servo library -class libServo : public PWMServo { - public: - int8_t attach(const int pin); - int8_t attach(const int pin, const int min, const int max); - void move(const int value); - void detach(void); - private: - typedef PWMServo super; - uint8_t servoPin; - uint16_t min_ticks; - uint16_t max_ticks; - uint8_t servoIndex; // Index into the channel data for this servo -}; diff --git a/src/HAL/TEENSY40_41/eeprom.cpp b/src/HAL/TEENSY40_41/eeprom.cpp deleted file mode 100644 index 3cd376e..0000000 --- a/src/HAL/TEENSY40_41/eeprom.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#ifdef __IMXRT1062__ - -/** - * HAL PersistentStore for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#include "../../inc/MarlinConfig.h" - -#if USE_WIRED_EEPROM - -#include "../shared/eeprom_api.h" -#include - -#ifndef MARLIN_EEPROM_SIZE - #define MARLIN_EEPROM_SIZE size_t(E2END + 1) -#endif -size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; } - -bool PersistentStore::access_start() { return true; } -bool PersistentStore::access_finish() { return true; } - -bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { - uint16_t written = 0; - while (size--) { - uint8_t * const p = (uint8_t * const)pos; - uint8_t v = *value; - if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed! - eeprom_write_byte(p, v); - if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes - if (eeprom_read_byte(p) != v) { - SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE); - return true; - } - } - crc16(crc, &v, 1); - pos++; - value++; - } - return false; -} - -bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { - do { - uint8_t c = eeprom_read_byte((uint8_t*)pos); - if (writing) *value = c; - crc16(crc, &c, 1); - pos++; - value++; - } while (--size); - return false; -} - -#endif // USE_WIRED_EEPROM -#endif // __IMXRT1062__ diff --git a/src/HAL/TEENSY40_41/endstop_interrupts.h b/src/HAL/TEENSY40_41/endstop_interrupts.h deleted file mode 100644 index 4c3ddec..0000000 --- a/src/HAL/TEENSY40_41/endstop_interrupts.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Endstop Interrupts for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - * - * Without endstop interrupts the endstop pins must be polled continually in - * the temperature-ISR via endstops.update(), most of the time finding no change. - * With this feature endstops.update() is called only when we know that at - * least one endstop has changed state, saving valuable CPU cycles. - * - * This feature only works when all used endstop pins can generate an 'external interrupt'. - * - * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. - * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) - */ - -#include "../../module/endstops.h" - -// One ISR for all EXT-Interrupts -void endstop_ISR() { endstops.update(); } - -/** - * Endstop interrupts for Due based targets. - * On Due, all pins support external interrupt capability. - */ -void setup_endstop_interrupts() { - #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) - TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN)); - TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN)); - TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN)); - TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN)); - TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN)); - TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN)); - TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN)); - TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN)); - TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN)); - TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN)); - TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN)); - TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN)); - TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN)); - TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN)); - TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN)); - TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN)); - TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN)); - TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN)); - TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN)); - TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN)); - TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN)); - TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN)); - TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN)); -} diff --git a/src/HAL/TEENSY40_41/fastio.h b/src/HAL/TEENSY40_41/fastio.h deleted file mode 100644 index 52f991d..0000000 --- a/src/HAL/TEENSY40_41/fastio.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2017 Victor Perez - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Fast I/O interfaces for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - * These use GPIO functions instead of Direct Port Manipulation, as on AVR. - */ - -#ifndef PWM - #define PWM OUTPUT -#endif - -#define READ(IO) digitalRead(IO) -#define WRITE(IO,V) digitalWrite(IO,V) - -#define _GET_MODE(IO) !is_output(IO) -#define _SET_MODE(IO,M) pinMode(IO, M) -#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT) /*!< Output Push Pull Mode & GPIO_NOPULL */ - -#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) - -#define SET_INPUT(IO) _SET_MODE(IO, INPUT) /*!< Input Floating Mode */ -#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, INPUT_PULLUP) /*!< Input with Pull-up activation */ -#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, INPUT_PULLDOWN) /*!< Input with Pull-down activation */ -#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW) -#define SET_PWM(IO) _SET_MODE(IO, PWM) - -#define TOGGLE(IO) OUT_WRITE(IO, !READ(IO)) - -#define IS_INPUT(IO) !is_output(IO) -#define IS_OUTPUT(IO) is_output(IO) - -#define PWM_PIN(P) digitalPinHasPWM(P) - -// digitalRead/Write wrappers -#define extDigitalRead(IO) digitalRead(IO) -#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h b/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h deleted file mode 100644 index 6a85409..0000000 --- a/src/HAL/TEENSY40_41/inc/Conditionals_LCD.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if HAS_SPI_TFT || HAS_FSMC_TFT - #error "Sorry! TFT displays are not available for HAL/TEENSY40_41." -#endif diff --git a/src/HAL/TEENSY40_41/inc/Conditionals_adv.h b/src/HAL/TEENSY40_41/inc/Conditionals_adv.h deleted file mode 100644 index 5f1c4b1..0000000 --- a/src/HAL/TEENSY40_41/inc/Conditionals_adv.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once diff --git a/src/HAL/TEENSY40_41/inc/Conditionals_post.h b/src/HAL/TEENSY40_41/inc/Conditionals_post.h deleted file mode 100644 index 998f1dc..0000000 --- a/src/HAL/TEENSY40_41/inc/Conditionals_post.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if USE_FALLBACK_EEPROM - #define USE_WIRED_EEPROM 1 -#endif diff --git a/src/HAL/TEENSY40_41/inc/SanityCheck.h b/src/HAL/TEENSY40_41/inc/SanityCheck.h deleted file mode 100644 index 3d2668d..0000000 --- a/src/HAL/TEENSY40_41/inc/SanityCheck.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Test TEENSY41 specific configuration values for errors at compile-time. - */ - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for Teensy 4.0/4.1. Disable EMERGENCY_PARSER to continue." -#endif - -#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY - #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on Teensy 4.0/4.1." -#endif - -#if HAS_TMC_SW_SERIAL - #error "TMC220x Software Serial is not supported on Teensy 4.0/4.1." -#endif - -#if ENABLED(POSTMORTEM_DEBUGGING) - #error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 4.0/4.1." -#endif diff --git a/src/HAL/TEENSY40_41/pinsDebug.h b/src/HAL/TEENSY40_41/pinsDebug.h deleted file mode 100644 index 94b85ea..0000000 --- a/src/HAL/TEENSY40_41/pinsDebug.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Pins Debugging for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#warning "PINS_DEBUGGING is not fully supported for Teensy 4.0 / 4.1 so 'M43' may cause hangs." - -#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS - -#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin -#define PRINT_PORT(p) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) -#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17)) -#define pwm_status(pin) HAL_pwm_status(pin) -#define GET_PINMODE(PIN) (VALID_PIN(pin) && IS_OUTPUT(pin)) -#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin - -struct pwm_pin_info_struct { - uint8_t type; // 0=no pwm, 1=flexpwm, 2=quad - uint8_t module; // 0-3, 0-3 - uint8_t channel; // 0=X, 1=A, 2=B - uint8_t muxval; // -}; - -#define M(a, b) ((((a) - 1) << 4) | (b)) - -const struct pwm_pin_info_struct pwm_pin_info[] = { - {1, M(1, 1), 0, 4}, // FlexPWM1_1_X 0 // AD_B0_03 - {1, M(1, 0), 0, 4}, // FlexPWM1_0_X 1 // AD_B0_02 - {1, M(4, 2), 1, 1}, // FlexPWM4_2_A 2 // EMC_04 - {1, M(4, 2), 2, 1}, // FlexPWM4_2_B 3 // EMC_05 - {1, M(2, 0), 1, 1}, // FlexPWM2_0_A 4 // EMC_06 - {1, M(2, 1), 1, 1}, // FlexPWM2_1_A 5 // EMC_08 - {1, M(2, 2), 1, 2}, // FlexPWM2_2_A 6 // B0_10 - {1, M(1, 3), 2, 6}, // FlexPWM1_3_B 7 // B1_01 - {1, M(1, 3), 1, 6}, // FlexPWM1_3_A 8 // B1_00 - {1, M(2, 2), 2, 2}, // FlexPWM2_2_B 9 // B0_11 - {2, M(1, 0), 0, 1}, // QuadTimer1_0 10 // B0_00 - {2, M(1, 2), 0, 1}, // QuadTimer1_2 11 // B0_02 - {2, M(1, 1), 0, 1}, // QuadTimer1_1 12 // B0_01 - {2, M(2, 0), 0, 1}, // QuadTimer2_0 13 // B0_03 - {2, M(3, 2), 0, 1}, // QuadTimer3_2 14 // AD_B1_02 - {2, M(3, 3), 0, 1}, // QuadTimer3_3 15 // AD_B1_03 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {2, M(3, 1), 0, 1}, // QuadTimer3_1 18 // AD_B1_01 - {2, M(3, 0), 0, 1}, // QuadTimer3_0 19 // AD_B1_00 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {1, M(4, 0), 1, 1}, // FlexPWM4_0_A 22 // AD_B1_08 - {1, M(4, 1), 1, 1}, // FlexPWM4_1_A 23 // AD_B1_09 - {1, M(1, 2), 0, 4}, // FlexPWM1_2_X 24 // AD_B0_12 - {1, M(1, 3), 0, 4}, // FlexPWM1_3_X 25 // AD_B0_13 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {1, M(3, 1), 2, 1}, // FlexPWM3_1_B 28 // EMC_32 - {1, M(3, 1), 1, 1}, // FlexPWM3_1_A 29 // EMC_31 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {1, M(2, 0), 2, 1}, // FlexPWM2_0_B 33 // EMC_07 - #ifdef ARDUINO_TEENSY40 - {1, M(1, 1), 2, 1}, // FlexPWM1_1_B 34 // SD_B0_03 - {1, M(1, 1), 1, 1}, // FlexPWM1_1_A 35 // SD_B0_02 - {1, M(1, 0), 2, 1}, // FlexPWM1_0_B 36 // SD_B0_01 - {1, M(1, 0), 1, 1}, // FlexPWM1_0_A 37 // SD_B0_00 - {1, M(1, 2), 2, 1}, // FlexPWM1_2_B 38 // SD_B0_05 - {1, M(1, 2), 1, 1}, // FlexPWM1_2_A 39 // SD_B0_04 - #endif - #ifdef ARDUINO_TEENSY41 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {1, M(2, 3), 1, 6}, // FlexPWM2_3_A 36 // B1_00 - {1, M(2, 3), 2, 6}, // FlexPWM2_3_B 37 // B1_01 - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {0, M(1, 0), 0, 0}, - {1, M(1, 1), 2, 1}, // FlexPWM1_1_B 42 // SD_B0_03 - {1, M(1, 1), 1, 1}, // FlexPWM1_1_A 43 // SD_B0_02 - {1, M(1, 0), 2, 1}, // FlexPWM1_0_B 44 // SD_B0_01 - {1, M(1, 0), 1, 1}, // FlexPWM1_0_A 45 // SD_B0_00 - {1, M(1, 2), 2, 1}, // FlexPWM1_2_B 46 // SD_B0_05 - {1, M(1, 2), 1, 1}, // FlexPWM1_2_A 47 // SD_B0_04 - {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_0_B - {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_2_A - {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_2_B - {1, M(3, 3), 2, 1}, // FlexPWM3_3_B 51 // EMC_22 - {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_1_B - {0, M(1, 0), 0, 0}, // duplicate FlexPWM1_1_A - {1, M(3, 0), 1, 1}, // FlexPWM3_0_A 53 // EMC_29 - #endif -}; - -void HAL_print_analog_pin(char buffer[], int8_t pin) { - if (pin <= 23) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 14)); - else if (pin <= 41) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 24)); -} - -void HAL_analog_pin_state(char buffer[], int8_t pin) { - if (pin <= 23) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 14)); - else if (pin <= 41) sprintf_P(buffer, PSTR("Analog in =% 5d"), analogRead(pin - 24)); -} - -#define PWM_PRINT(V) do{ sprintf_P(buffer, PSTR("PWM: %4d"), V); SERIAL_ECHO(buffer); }while(0) - -/** - * Print a pin's PWM status. - * Return true if it's currently a PWM pin. - */ -bool HAL_pwm_status(int8_t pin) { - char buffer[20]; // for the sprintf statements - const struct pwm_pin_info_struct *info; - - if (pin >= CORE_NUM_DIGITAL) return 0; - info = pwm_pin_info + pin; - - if (info->type == 0) return 0; - - /* TODO decode pwm value from timers */ - // for now just indicate if output is set as pwm - PWM_PRINT(*(portConfigRegister(pin)) == info->muxval); - return (*(portConfigRegister(pin)) == info->muxval); -} - -static void pwm_details(uint8_t pin) { /* TODO */ } diff --git a/src/HAL/TEENSY40_41/spi_pins.h b/src/HAL/TEENSY40_41/spi_pins.h deleted file mode 100644 index ba4a2c7..0000000 --- a/src/HAL/TEENSY40_41/spi_pins.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL SPI Pins for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#define SD_SCK_PIN 13 -#define SD_MISO_PIN 12 -#define SD_MOSI_PIN 11 -#define SD_SS_PIN 20 // SDSS // A.28, A.29, B.21, C.26, C.29 diff --git a/src/HAL/TEENSY40_41/timers.cpp b/src/HAL/TEENSY40_41/timers.cpp deleted file mode 100644 index ed99f65..0000000 --- a/src/HAL/TEENSY40_41/timers.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL Timers for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#ifdef __IMXRT1062__ - -#include "../../inc/MarlinConfig.h" - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { - switch (timer_num) { - case MF_TIMER_STEP: - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode - CCM_CCGR1 |= CCM_CCGR1_GPT1_BUS(CCM_CCGR_ON); - - GPT1_CR = 0; // disable timer - GPT1_SR = 0x3F; // clear all prior status - GPT1_PR = GPT1_TIMER_PRESCALE - 1; - GPT1_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) - GPT1_CR |= GPT_CR_ENMOD; //reset count to zero before enabling - GPT1_CR |= GPT_CR_OM1(1); // toggle mode - GPT1_OCR1 = (GPT1_TIMER_RATE / frequency) -1; // Initial compare value - GPT1_IR = GPT_IR_OF1IE; // Compare3 value - GPT1_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz - - OUT_WRITE(15, HIGH); - attachInterruptVector(IRQ_GPT1, &stepTC_Handler); - NVIC_SET_PRIORITY(IRQ_GPT1, 16); - break; - case MF_TIMER_TEMP: - CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode - CCM_CCGR0 |= CCM_CCGR0_GPT2_BUS(CCM_CCGR_ON); - - GPT2_CR = 0; // disable timer - GPT2_SR = 0x3F; // clear all prior status - GPT2_PR = GPT2_TIMER_PRESCALE - 1; - GPT2_CR |= GPT_CR_CLKSRC(1); //clock selection #1 (peripheral clock = 150 MHz) - GPT2_CR |= GPT_CR_ENMOD; //reset count to zero before enabling - GPT2_CR |= GPT_CR_OM1(1); // toggle mode - GPT2_OCR1 = (GPT2_TIMER_RATE / frequency) -1; // Initial compare value - GPT2_IR = GPT_IR_OF1IE; // Compare3 value - GPT2_CR |= GPT_CR_EN; //enable GPT2 counting at 150 MHz - - OUT_WRITE(14, HIGH); - attachInterruptVector(IRQ_GPT2, &tempTC_Handler); - NVIC_SET_PRIORITY(IRQ_GPT2, 32); - break; - } -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_ENABLE_IRQ(IRQ_GPT1); break; - case MF_TIMER_TEMP: NVIC_ENABLE_IRQ(IRQ_GPT2); break; - } -} - -void HAL_timer_disable_interrupt(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: NVIC_DISABLE_IRQ(IRQ_GPT1); break; - case MF_TIMER_TEMP: NVIC_DISABLE_IRQ(IRQ_GPT2); break; - } - - // We NEED memory barriers to ensure Interrupts are actually disabled! - // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) - asm volatile("dsb"); -} - -bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return (NVIC_IS_ENABLED(IRQ_GPT1)); - case MF_TIMER_TEMP: return (NVIC_IS_ENABLED(IRQ_GPT2)); - } - return false; -} - -void HAL_timer_isr_prologue(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: GPT1_SR = GPT_IR_OF1IE; break; // clear OF3 bit - case MF_TIMER_TEMP: GPT2_SR = GPT_IR_OF1IE; break; // clear OF3 bit - } - asm volatile("dsb"); -} - -#endif // __IMXRT1062__ diff --git a/src/HAL/TEENSY40_41/timers.h b/src/HAL/TEENSY40_41/timers.h deleted file mode 100644 index 77fe095..0000000 --- a/src/HAL/TEENSY40_41/timers.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL Timers for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) - */ - -#include - -// ------------------------ -// Defines -// ------------------------ - -#define FORCE_INLINE __attribute__((always_inline)) inline - -typedef uint32_t hal_timer_t; -#define HAL_TIMER_TYPE_MAX 0xFFFFFFFE - -#define GPT_TIMER_RATE F_BUS_ACTUAL // 150MHz - -#define GPT1_TIMER_PRESCALE 2 -#define GPT2_TIMER_PRESCALE 10 - -#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 75MHz -#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 15MHz - -#ifndef MF_TIMER_STEP - #define MF_TIMER_STEP 0 // Timer Index for Stepper -#endif -#ifndef MF_TIMER_PULSE - #define MF_TIMER_PULSE MF_TIMER_STEP -#endif -#ifndef MF_TIMER_TEMP - #define MF_TIMER_TEMP 1 // Timer Index for Temperature -#endif - -#define TEMP_TIMER_RATE 1000000 -#define TEMP_TIMER_FREQUENCY 1000 - -#define STEPPER_TIMER_RATE GPT1_TIMER_RATE -#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) -#define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US) - -#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer -#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE -#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US - -#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) -#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) -#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) - -#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) -#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) - -#ifndef HAL_STEP_TIMER_ISR - #define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler() // GPT1_Handler() -#endif -#ifndef HAL_TEMP_TIMER_ISR - #define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler() // GPT2_Handler() -#endif - -extern "C" { - void stepTC_Handler(); - void tempTC_Handler(); -} - -void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); - -FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { - switch (timer_num) { - case MF_TIMER_STEP: GPT1_OCR1 = compare - 1; break; - case MF_TIMER_TEMP: GPT2_OCR1 = compare - 1; break; - } -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return GPT1_OCR1; - case MF_TIMER_TEMP: return GPT2_OCR1; - } - return 0; -} - -FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { - switch (timer_num) { - case MF_TIMER_STEP: return GPT1_CNT; - case MF_TIMER_TEMP: return GPT2_CNT; - } - return 0; -} - -void HAL_timer_enable_interrupt(const uint8_t timer_num); -void HAL_timer_disable_interrupt(const uint8_t timer_num); -bool HAL_timer_interrupt_enabled(const uint8_t timer_num); - -void HAL_timer_isr_prologue(const uint8_t timer_num); -//void HAL_timer_isr_epilogue(const uint8_t timer_num) {} -#define HAL_timer_isr_epilogue(T) NOOP diff --git a/src/HAL/platforms.h b/src/HAL/platforms.h deleted file mode 100644 index 28fe28e..0000000 --- a/src/HAL/platforms.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#define XSTR(V...) #V - -#ifdef __AVR__ - #define HAL_PATH(PATH, NAME) XSTR(PATH/AVR/NAME) -#elif defined(ARDUINO_ARCH_SAM) - #define HAL_PATH(PATH, NAME) XSTR(PATH/DUE/NAME) -#elif defined(__MK20DX256__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY31_32/NAME) -#elif defined(__MK64FX512__) || defined(__MK66FX1M0__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY35_36/NAME) -#elif defined(__IMXRT1062__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/TEENSY40_41/NAME) -#elif defined(TARGET_LPC1768) - #define HAL_PATH(PATH, NAME) XSTR(PATH/LPC1768/NAME) -#elif defined(__STM32F1__) || defined(TARGET_STM32F1) - #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32F1/NAME) -#elif defined(ARDUINO_ARCH_STM32) - #ifndef HAL_STM32 - #define HAL_STM32 - #endif - #define HAL_PATH(PATH, NAME) XSTR(PATH/STM32/NAME) -#elif defined(ARDUINO_ARCH_ESP32) - #define HAL_PATH(PATH, NAME) XSTR(PATH/ESP32/NAME) -#elif defined(__PLAT_LINUX__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/LINUX/NAME) -#elif defined(__PLAT_NATIVE_SIM__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/NATIVE_SIM/NAME) -#elif defined(__SAMD51__) - #define HAL_PATH(PATH, NAME) XSTR(PATH/SAMD51/NAME) -#else - #error "Unsupported Platform!" -#endif diff --git a/src/HAL/shared/Delay.cpp b/src/HAL/shared/Delay.cpp deleted file mode 100644 index c64376d..0000000 --- a/src/HAL/shared/Delay.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "Delay.h" - -#include "../../inc/MarlinConfig.h" - -#if defined(__arm__) || defined(__thumb__) - - static uint32_t ASM_CYCLES_PER_ITERATION = 4; // Initial bet which will be adjusted in calibrate_delay_loop - - // Simple assembler loop counting down - void delay_asm(uint32_t cy) { - cy = _MAX(cy / ASM_CYCLES_PER_ITERATION, 1U); // Zero is forbidden here - __asm__ __volatile__( - A(".syntax unified") // is to prevent CM0,CM1 non-unified syntax - L("1") - A("subs %[cnt],#1") - A("bne 1b") - : [cnt]"+r"(cy) // output: +r means input+output - : // input: - : "cc" // clobbers: - ); - } - - // We can't use CMSIS since it's not available on all platform, so fallback to hardcoded register values - #define HW_REG(X) *(volatile uint32_t *)(X) - #define _DWT_CTRL 0xE0001000 - #define _DWT_CYCCNT 0xE0001004 // CYCCNT is 32bits, takes 37s or so to wrap. - #define _DEM_CR 0xE000EDFC - #define _LAR 0xE0001FB0 - - // Use hardware cycle counter instead, it's much safer - void delay_dwt(uint32_t count) { - // Reuse the ASM_CYCLES_PER_ITERATION variable to avoid wasting another useless variable - uint32_t start = HW_REG(_DWT_CYCCNT) - ASM_CYCLES_PER_ITERATION, elapsed; - do { - elapsed = HW_REG(_DWT_CYCCNT) - start; - } while (elapsed < count); - } - - // Pointer to asm function, calling the functions has a ~20 cycles overhead - DelayImpl DelayCycleFnc = delay_asm; - - void calibrate_delay_loop() { - // Check if we have a working DWT implementation in the CPU (see https://developer.arm.com/documentation/ddi0439/b/Data-Watchpoint-and-Trace-Unit/DWT-Programmers-Model) - if (!HW_REG(_DWT_CTRL)) { - // No DWT present, so fallback to plain old ASM nop counting - // Unfortunately, we don't exactly know how many iteration it'll take to decrement a counter in a loop - // It depends on the CPU architecture, the code current position (flash vs SRAM) - // So, instead of wild guessing and making mistake, instead - // compute it once for all - ASM_CYCLES_PER_ITERATION = 1; - // We need to fetch some reference clock before waiting - cli(); - uint32_t start = micros(); - delay_asm(1000); // On a typical CPU running in MHz, waiting 1000 "unknown cycles" means it'll take between 1ms to 6ms, that's perfectly acceptable - uint32_t end = micros(); - sei(); - uint32_t expectedCycles = (end - start) * ((F_CPU) / 1000000UL); // Convert microseconds to cycles - // Finally compute the right scale - ASM_CYCLES_PER_ITERATION = (uint32_t)(expectedCycles / 1000); - - // No DWT present, likely a Cortex M0 so NOP counting is our best bet here - DelayCycleFnc = delay_asm; - } - else { - // Enable DWT counter - // From https://stackoverflow.com/a/41188674/1469714 - HW_REG(_DEM_CR) = HW_REG(_DEM_CR) | 0x01000000; // Enable trace - #if __CORTEX_M == 7 - HW_REG(_LAR) = 0xC5ACCE55; // Unlock access to DWT registers, see https://developer.arm.com/documentation/ihi0029/e/ section B2.3.10 - #endif - HW_REG(_DWT_CYCCNT) = 0; // Clear DWT cycle counter - HW_REG(_DWT_CTRL) = HW_REG(_DWT_CTRL) | 1; // Enable DWT cycle counter - - // Then calibrate the constant offset from the counter - ASM_CYCLES_PER_ITERATION = 0; - uint32_t s = HW_REG(_DWT_CYCCNT); - uint32_t e = HW_REG(_DWT_CYCCNT); // (e - s) contains the number of cycle required to read the cycle counter - delay_dwt(0); - uint32_t f = HW_REG(_DWT_CYCCNT); // (f - e) contains the delay to call the delay function + the time to read the cycle counter - ASM_CYCLES_PER_ITERATION = (f - e) - (e - s); - - // Use safer DWT function - DelayCycleFnc = delay_dwt; - } - } - - #if ENABLED(MARLIN_DEV_MODE) - void dump_delay_accuracy_check() { - auto report_call_time = [](FSTR_P const name, FSTR_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) { - SERIAL_ECHOPGM("Calling "); - SERIAL_ECHOF(name); - SERIAL_ECHOLNPGM(" for ", cycles); - SERIAL_ECHOF(unit); - SERIAL_ECHOLNPGM(" took: ", total); - SERIAL_CHAR(' '); - SERIAL_ECHOF(unit); - if (do_flush) SERIAL_FLUSHTX(); - }; - - uint32_t s, e; - - SERIAL_ECHOLNPGM("Computed delay calibration value: ", ASM_CYCLES_PER_ITERATION); - SERIAL_FLUSH(); - // Display the results of the calibration above - constexpr uint32_t testValues[] = { 1, 5, 10, 20, 50, 100, 150, 200, 350, 500, 750, 1000 }; - for (auto i : testValues) { - s = micros(); DELAY_US(i); e = micros(); - report_call_time(F("delay"), F("us"), i, e - s); - } - - if (HW_REG(_DWT_CTRL)) { - static FSTR_P cyc = F("cycles"); - static FSTR_P dcd = F("DELAY_CYCLES directly "); - - for (auto i : testValues) { - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(i); e = HW_REG(_DWT_CYCCNT); - report_call_time(F("runtime delay"), cyc, i, e - s); - } - - // Measure the delay to call a real function compared to a function pointer - s = HW_REG(_DWT_CYCCNT); delay_dwt(1); e = HW_REG(_DWT_CYCCNT); - report_call_time(F("delay_dwt"), cyc, 1, e - s); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES( 1); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 1, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES( 5); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 5, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(10); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 10, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(20); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 20, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(50); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 50, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(100); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 100, e - s, false); - - s = HW_REG(_DWT_CYCCNT); DELAY_CYCLES(200); e = HW_REG(_DWT_CYCCNT); - report_call_time(dcd, cyc, 200, e - s, false); - } - } - #endif // MARLIN_DEV_MODE - - -#else - - void calibrate_delay_loop() {} - #if ENABLED(MARLIN_DEV_MODE) - void dump_delay_accuracy_check() { SERIAL_ECHOPGM("N/A on this platform"); } - #endif - -#endif diff --git a/src/HAL/shared/Delay.h b/src/HAL/shared/Delay.h deleted file mode 100644 index a6795a7..0000000 --- a/src/HAL/shared/Delay.h +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfigPre.h" - -/** - * Busy wait delay cycles routines: - * - * DELAY_CYCLES(count): Delay execution in cycles - * DELAY_NS(count): Delay execution in nanoseconds - * DELAY_US(count): Delay execution in microseconds - */ - -#include "../../core/macros.h" - -void calibrate_delay_loop(); - -#if defined(__arm__) || defined(__thumb__) - - // We want to have delay_cycle function with the lowest possible overhead, so we adjust at the function at runtime based on the current CPU best feature - typedef void (*DelayImpl)(uint32_t); - extern DelayImpl DelayCycleFnc; - - // I've measured 36 cycles on my system to call the cycle waiting method, but it shouldn't change much to have a bit more margin, it only consume a bit more flash - #define TRIP_POINT_FOR_CALLING_FUNCTION 40 - - // A simple recursive template class that output exactly one 'nop' of code per recursion - template struct NopWriter { - FORCE_INLINE static void build() { - __asm__ __volatile__("nop"); - NopWriter::build(); - } - }; - // End the loop - template <> struct NopWriter<0> { FORCE_INLINE static void build() {} }; - - namespace Private { - // Split recursing template in 2 different class so we don't reach the maximum template instantiation depth limit - template struct Helper { - FORCE_INLINE static void build() { - DelayCycleFnc(N - 2); // Approximative cost of calling the function (might be off by one or 2 cycles) - } - }; - - template struct Helper { - FORCE_INLINE static void build() { - NopWriter::build(); - } - }; - - template <> struct Helper { - FORCE_INLINE static void build() {} - }; - - } - // Select a behavior based on the constexpr'ness of the parameter - // If called with a compile-time parameter, then write as many NOP as required to reach the asked cycle count - // (there is some tripping point here to start looping when it's more profitable than gruntly executing NOPs) - // If not called from a compile-time parameter, fallback to a runtime loop counting version instead - template - struct SmartDelay { - FORCE_INLINE SmartDelay(int) { - if (Cycles == 0) return; - Private::Helper::build(); - } - }; - // Runtime version below. There is no way this would run under less than ~TRIP_POINT_FOR_CALLING_FUNCTION cycles - template - struct SmartDelay { - FORCE_INLINE SmartDelay(int v) { DelayCycleFnc(v); } - }; - - #define DELAY_CYCLES(X) do { SmartDelay _smrtdly_X(X); } while(0) - - #if GCC_VERSION <= 70000 - #define DELAY_CYCLES_VAR(X) DelayCycleFnc(X) - #else - #define DELAY_CYCLES_VAR DELAY_CYCLES - #endif - - // For delay in microseconds, no smart delay selection is required, directly call the delay function - // Teensy compiler is too old and does not accept smart delay compile-time / run-time selection correctly - #define DELAY_US(x) DelayCycleFnc((x) * ((F_CPU) / 1000000UL)) - -#elif defined(__AVR__) - FORCE_INLINE static void __delay_up_to_3c(uint8_t cycles) { - switch (cycles) { - case 3: - __asm__ __volatile__(A("RJMP .+0") A("NOP")); - break; - case 2: - __asm__ __volatile__(A("RJMP .+0")); - break; - case 1: - __asm__ __volatile__(A("NOP")); - break; - } - } - - // Delay in cycles - FORCE_INLINE static void DELAY_CYCLES(uint16_t cycles) { - if (__builtin_constant_p(cycles)) { - if (cycles <= 3) { - __delay_up_to_3c(cycles); - } - else if (cycles == 4) { - __delay_up_to_3c(2); - __delay_up_to_3c(2); - } - else { - cycles -= 1 + 4; // Compensate for the first LDI (1) and the first round (4) - __delay_up_to_3c(cycles % 4); - - cycles /= 4; - // The following code burns [1 + 4 * (rounds+1)] cycles - uint16_t dummy; - __asm__ __volatile__( - // "manually" load counter from constants, otherwise the compiler may optimize this part away - A("LDI %A[rounds], %[l]") // 1c - A("LDI %B[rounds], %[h]") // 1c (compensating the non branching BRCC) - L("1") - A("SBIW %[rounds], 1") // 2c - A("BRCC 1b") // 2c when branching, else 1c (end of loop) - : // Outputs ... - [rounds] "=w" (dummy) // Restrict to a wo (=) 16 bit register pair (w) - : // Inputs ... - [l] "M" (cycles%256), // Restrict to 0..255 constant (M) - [h] "M" (cycles/256) // Restrict to 0..255 constant (M) - :// Clobbers ... - "cc" // Indicate we are modifying flags like Carry (cc) - ); - } - } - else { - __asm__ __volatile__( - L("1") - A("SBIW %[cycles], 4") // 2c - A("BRCC 1b") // 2c when branching, else 1c (end of loop) - : [cycles] "+w" (cycles) // output: Restrict to a rw (+) 16 bit register pair (w) - : // input: - - : "cc" // clobbers: We are modifying flags like Carry (cc) - ); - } - } - - // Delay in microseconds - #define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL)) - - #define DELAY_CYCLES_VAR DELAY_CYCLES - -#elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__) - - // DELAY_CYCLES specified inside platform - - // Delay in microseconds - #define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL)) -#else - - #error "Unsupported MCU architecture" - -#endif - -/************************************************************** - * Delay in nanoseconds. Requires the F_CPU macro. - * These macros follow avr-libc delay conventions. - * - * For AVR there are three possible operation modes, due to its - * slower clock speeds and thus coarser delay resolution. For - * example, when F_CPU = 16000000 the resolution is 62.5ns. - * - * Round up (default) - * Round up the delay according to the CPU clock resolution. - * e.g., 100 will give a delay of 2 cycles (125ns). - * - * Round down (DELAY_NS_ROUND_DOWN) - * Round down the delay according to the CPU clock resolution. - * e.g., 100 will be rounded down to 1 cycle (62.5ns). - * - * Nearest (DELAY_NS_ROUND_CLOSEST) - * Round the delay to the nearest number of clock cycles. - * e.g., 165 will be rounded up to 3 cycles (187.5ns) because - * it's closer to the requested delay than 2 cycle (125ns). - */ - -#ifndef __AVR__ - #undef DELAY_NS_ROUND_DOWN - #undef DELAY_NS_ROUND_CLOSEST -#endif - -#if ENABLED(DELAY_NS_ROUND_DOWN) - #define _NS_TO_CYCLES(x) ( (x) * ((F_CPU) / 1000000UL) / 1000UL) // floor -#elif ENABLED(DELAY_NS_ROUND_CLOSEST) - #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 500) / 1000UL) // round -#else - #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 999) / 1000UL) // "ceil" -#endif - -#define DELAY_NS(x) DELAY_CYCLES(_NS_TO_CYCLES(x)) -#define DELAY_NS_VAR(x) DELAY_CYCLES_VAR(_NS_TO_CYCLES(x)) diff --git a/src/HAL/shared/HAL.cpp b/src/HAL/shared/HAL.cpp deleted file mode 100644 index 4d92aed..0000000 --- a/src/HAL/shared/HAL.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * HAL/shared/HAL.cpp - */ - -#include "../../inc/MarlinConfig.h" - -MarlinHAL hal; - -#if ENABLED(SOFT_RESET_VIA_SERIAL) - - // Global for use by e_parser.h - void HAL_reboot() { hal.reboot(); } - -#endif diff --git a/src/HAL/shared/HAL_SPI.h b/src/HAL/shared/HAL_SPI.h deleted file mode 100644 index 6611f9e..0000000 --- a/src/HAL/shared/HAL_SPI.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL/shared/HAL_SPI.h - * Core Marlin definitions for SPI, implemented in the HALs - */ - -#include "Marduino.h" -#include - -/** - * SPI speed where 0 <= index <= 6 - * - * Approximate rates : - * - * 0 : 8 - 10 MHz - * 1 : 4 - 5 MHz - * 2 : 2 - 2.5 MHz - * 3 : 1 - 1.25 MHz - * 4 : 500 - 625 kHz - * 5 : 250 - 312 kHz - * 6 : 125 - 156 kHz - * - * On AVR, actual speed is F_CPU/2^(1 + index). - * On other platforms, speed should be in range given above where possible. - */ - -#define SPI_FULL_SPEED 0 // Set SCK to max rate -#define SPI_HALF_SPEED 1 // Set SCK rate to half of max rate -#define SPI_QUARTER_SPEED 2 // Set SCK rate to quarter of max rate -#define SPI_EIGHTH_SPEED 3 // Set SCK rate to 1/8 of max rate -#define SPI_SIXTEENTH_SPEED 4 // Set SCK rate to 1/16 of max rate -#define SPI_SPEED_5 5 // Set SCK rate to 1/32 of max rate -#define SPI_SPEED_6 6 // Set SCK rate to 1/64 of max rate - -// -// Standard SPI functions -// - -// Initialize SPI bus -void spiBegin(); - -// Configure SPI for specified SPI speed -void spiInit(uint8_t spiRate); - -// Write single byte to SPI -void spiSend(uint8_t b); - -// Read single byte from SPI -uint8_t spiRec(); - -// Read from SPI into buffer -void spiRead(uint8_t *buf, uint16_t nbyte); - -// Write token and then write from 512 byte buffer to SPI (for SD card) -void spiSendBlock(uint8_t token, const uint8_t *buf); - -// Begin SPI transaction, set clock, bit order, data mode -void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode); - -// -// Extended SPI functions taking a channel number (Hardware SPI only) -// - -// Write single byte to specified SPI channel -void spiSend(uint32_t chan, byte b); - -// Write buffer to specified SPI channel -void spiSend(uint32_t chan, const uint8_t *buf, size_t n); - -// Read single byte from specified SPI channel -uint8_t spiRec(uint32_t chan); diff --git a/src/HAL/shared/HAL_ST7920.h b/src/HAL/shared/HAL_ST7920.h deleted file mode 100644 index 4e362f9..0000000 --- a/src/HAL/shared/HAL_ST7920.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL/ST7920.h - * For the HALs that provide direct access to the ST7920 display - * (bypassing U8G), it will allow the LIGHTWEIGHT_UI to operate. - */ - -#if BOTH(HAS_MARLINUI_U8GLIB, LIGHTWEIGHT_UI) - void ST7920_cs(); - void ST7920_ncs(); - void ST7920_set_cmd(); - void ST7920_set_dat(); - void ST7920_write_byte(const uint8_t data); -#endif diff --git a/src/HAL/shared/HAL_spi_L6470.cpp b/src/HAL/shared/HAL_spi_L6470.cpp deleted file mode 100644 index 5d4ce89..0000000 --- a/src/HAL/shared/HAL_spi_L6470.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Software L6470 SPI functions originally from Arduino Sd2Card Library - * Copyright (c) 2009 by William Greiman - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_L64XX - -#include "Delay.h" - -#include "../../core/serial.h" -#include "../../libs/L64XX/L64XX_Marlin.h" - -// Make sure GCC optimizes this file. -// Note that this line triggers a bug in GCC which is fixed by casting. -// See the note below. -#pragma GCC optimize (3) - -// run at ~4Mhz -inline uint8_t L6470_SpiTransfer_Mode_0(uint8_t b) { // using Mode 0 - for (uint8_t bits = 8; bits--;) { - WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80); - b <<= 1; // little setup time - - WRITE(L6470_CHAIN_SCK_PIN, HIGH); - DELAY_NS(125); // 10 cycles @ 84mhz - - b |= (READ(L6470_CHAIN_MISO_PIN) != 0); - - WRITE(L6470_CHAIN_SCK_PIN, LOW); - DELAY_NS(125); // 10 cycles @ 84mhz - } - return b; -} - -inline uint8_t L6470_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3 - for (uint8_t bits = 8; bits--;) { - WRITE(L6470_CHAIN_SCK_PIN, LOW); - WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80); - - DELAY_NS(125); // 10 cycles @ 84mhz - WRITE(L6470_CHAIN_SCK_PIN, HIGH); - DELAY_NS(125); // Need more delay for fast CPUs - - b <<= 1; // little setup time - b |= (READ(L6470_CHAIN_MISO_PIN) != 0); - } - DELAY_NS(125); // 10 cycles @ 84mhz - return b; -} - -/** - * L64XX methods for SPI init and transfer - */ -void L64XX_Marlin::spi_init() { - OUT_WRITE(L6470_CHAIN_SS_PIN, HIGH); - OUT_WRITE(L6470_CHAIN_SCK_PIN, HIGH); - OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH); - SET_INPUT(L6470_CHAIN_MISO_PIN); - - #if PIN_EXISTS(L6470_BUSY) - SET_INPUT(L6470_BUSY_PIN); - #endif - - OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH); -} - -uint8_t L64XX_Marlin::transfer_single(uint8_t data, int16_t ss_pin) { - // First device in chain has data sent last - extDigitalWrite(ss_pin, LOW); - - hal.isr_off(); // Disable interrupts during SPI transfer (can't allow partial command to chips) - const uint8_t data_out = L6470_SpiTransfer_Mode_3(data); - hal.isr_on(); // Enable interrupts - - extDigitalWrite(ss_pin, HIGH); - return data_out; -} - -uint8_t L64XX_Marlin::transfer_chain(uint8_t data, int16_t ss_pin, uint8_t chain_position) { - uint8_t data_out = 0; - - // first device in chain has data sent last - extDigitalWrite(ss_pin, LOW); - - for (uint8_t i = L64XX::chain[0]; !L64xxManager.spi_abort && i >= 1; i--) { // Send data unless aborted - hal.isr_off(); // Disable interrupts during SPI transfer (can't allow partial command to chips) - const uint8_t temp = L6470_SpiTransfer_Mode_3(uint8_t(i == chain_position ? data : dSPIN_NOP)); - hal.isr_on(); // Enable interrupts - if (i == chain_position) data_out = temp; - } - - extDigitalWrite(ss_pin, HIGH); - return data_out; -} - -/** - * Platform-supplied L6470 buffer transfer method - */ -void L64XX_Marlin::transfer(uint8_t L6470_buf[], const uint8_t length) { - // First device in chain has its data sent last - - if (spi_active) { // Interrupted SPI transfer so need to - WRITE(L6470_CHAIN_SS_PIN, HIGH); // guarantee min high of 650ns - DELAY_US(1); - } - - WRITE(L6470_CHAIN_SS_PIN, LOW); - for (uint8_t i = length; i >= 1; i--) - L6470_SpiTransfer_Mode_3(uint8_t(L6470_buf[i])); - WRITE(L6470_CHAIN_SS_PIN, HIGH); -} - -#pragma GCC reset_options - -#endif // HAS_L64XX diff --git a/src/HAL/shared/Marduino.h b/src/HAL/shared/Marduino.h deleted file mode 100644 index 0e2a021..0000000 --- a/src/HAL/shared/Marduino.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * HAL/shared/Marduino.h - */ - -#undef DISABLED // Redefined by ESP32 -#undef M_PI // Redefined by all -#undef _BV // Redefined by some -#undef SBI // Redefined by arduino/const_functions.h -#undef CBI // Redefined by arduino/const_functions.h -#undef sq // Redefined by teensy3/wiring.h -#undef UNUSED // Redefined by stm32f4xx_hal_def.h - -#include // NOTE: If included earlier then this line is a NOOP - -#undef DISABLED -#define DISABLED(V...) DO(DIS,&&,V) - -#undef _BV -#define _BV(b) (1 << (b)) -#ifndef SBI - #define SBI(A,B) (A |= _BV(B)) -#endif -#ifndef CBI - #define CBI(A,B) (A &= ~_BV(B)) -#endif - -#undef sq -#define sq(x) ((x)*(x)) - -#ifndef __AVR__ - #ifndef strchr_P // Some platforms define a macro (DUE, teensy35) - inline const char* strchr_P(const char *s, int c) { return strchr(s,c); } - //#define strchr_P(s,c) strchr(s,c) - #endif - - #ifndef snprintf_P - #define snprintf_P snprintf - #endif - #ifndef vsnprintf_P - #define vsnprintf_P vsnprintf - #endif -#endif - -// Restart causes -#define RST_POWER_ON 1 -#define RST_EXTERNAL 2 -#define RST_BROWN_OUT 4 -#define RST_WATCHDOG 8 -#define RST_JTAG 16 -#define RST_SOFTWARE 32 -#define RST_BACKUP 64 - -#ifndef M_PI - #define M_PI 3.14159265358979323846f -#endif - -// Remove compiler warning on an unused variable -#ifndef UNUSED - #define UNUSED(x) ((void)(x)) -#endif - -#ifndef FORCE_INLINE - #define FORCE_INLINE __attribute__((always_inline)) inline -#endif - -#include "progmem.h" - -class __FlashStringHelper; -typedef const __FlashStringHelper* FSTR_P; -#ifndef FPSTR - #define FPSTR(S) (reinterpret_cast(S)) -#endif -#define FTOP(S) (reinterpret_cast(S)) diff --git a/src/HAL/shared/MinSerial.cpp b/src/HAL/shared/MinSerial.cpp deleted file mode 100644 index 2e718d8..0000000 --- a/src/HAL/shared/MinSerial.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General 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 "MinSerial.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - -void HAL_min_serial_init_default() {} -void HAL_min_serial_out_default(char ch) { SERIAL_CHAR(ch); } -void (*HAL_min_serial_init)() = &HAL_min_serial_init_default; -void (*HAL_min_serial_out)(char) = &HAL_min_serial_out_default; - -bool MinSerial::force_using_default_output = false; - -#endif diff --git a/src/HAL/shared/MinSerial.h b/src/HAL/shared/MinSerial.h deleted file mode 100644 index 3089b8a..0000000 --- a/src/HAL/shared/MinSerial.h +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/serial.h" -#include - -// Serial stuff here -// Inside an exception handler, the CPU state is not safe, we can't expect the handler to resume -// and the software to continue. UART communication can't rely on later callback/interrupt as it might never happen. -// So, you need to provide some method to send one byte to the usual UART with the interrupts disabled -// By default, the method uses SERIAL_CHAR but it's 100% guaranteed to break (couldn't be worse than nothing...)7 -extern void (*HAL_min_serial_init)(); -extern void (*HAL_min_serial_out)(char ch); - -struct MinSerial { - static bool force_using_default_output; - // Serial output - static void TX(char ch) { - if (force_using_default_output) - SERIAL_CHAR(ch); - else - HAL_min_serial_out(ch); - } - // Send String through UART - static void TX(const char *s) { while (*s) TX(*s++); } - // Send a digit through UART - static void TXDigit(uint32_t d) { - if (d < 10) TX((char)(d+'0')); - else if (d < 16) TX((char)(d+'A'-10)); - else TX('?'); - } - - // Send Hex number through UART - static void TXHex(uint32_t v) { - TX("0x"); - for (uint8_t i = 0; i < 8; i++, v <<= 4) - TXDigit((v >> 28) & 0xF); - } - - // Send Decimal number through UART - static void TXDec(uint32_t v) { - if (!v) { - TX('0'); - return; - } - - char nbrs[14]; - char *p = &nbrs[0]; - while (v != 0) { - *p++ = '0' + (v % 10); - v /= 10; - } - do { - p--; - TX(*p); - } while (p != &nbrs[0]); - } - static void init() { if (!force_using_default_output) HAL_min_serial_init(); } -}; diff --git a/src/HAL/shared/backtrace/backtrace.cpp b/src/HAL/shared/backtrace/backtrace.cpp deleted file mode 100644 index 33e8e65..0000000 --- a/src/HAL/shared/backtrace/backtrace.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#if defined(__arm__) || defined(__thumb__) - -#include "backtrace.h" -#include "unwinder.h" -#include "unwmemaccess.h" - -#include "../MinSerial.h" -#include - -// Dump a backtrace entry -static bool UnwReportOut(void *ctx, const UnwReport *bte) { - int *p = (int*)ctx; - - (*p)++; - - const uint32_t a = bte->address, f = bte->function; - MinSerial::TX('#'); MinSerial::TXDec(*p); MinSerial::TX(" : "); - MinSerial::TX(bte->name?:"unknown"); MinSerial::TX('@'); MinSerial::TXHex(f); - MinSerial::TX('+'); MinSerial::TXDec(a - f); - MinSerial::TX(" PC:"); MinSerial::TXHex(a); - MinSerial::TX('\n'); - return true; -} - -#ifdef UNW_DEBUG - void UnwPrintf(const char *format, ...) { - char dest[256]; - va_list argptr; - va_start(argptr, format); - vsprintf(dest, format, argptr); - va_end(argptr); - MinSerial::TX(&dest[0]); - } -#endif - -/* Table of function pointers for passing to the unwinder */ -static const UnwindCallbacks UnwCallbacks = { - UnwReportOut, - UnwReadW, - UnwReadH, - UnwReadB - #ifdef UNW_DEBUG - , UnwPrintf - #endif -}; - -// Perform a backtrace to the serial port -void backtrace() { - - unsigned long sp = 0, lr = 0, pc = 0; - - // Capture the values of the registers to perform the traceback - __asm__ __volatile__ ( - " mov %[lrv],lr\n" - " mov %[spv],sp\n" - " mov %[pcv],pc\n" - : [spv]"+r"( sp ), - [lrv]"+r"( lr ), - [pcv]"+r"( pc ) - :: - ); - - backtrace_ex(sp, lr, pc); -} - -void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) { - UnwindFrame btf; - - // Fill the traceback structure - btf.sp = sp; - btf.fp = btf.sp; - btf.lr = lr; - btf.pc = pc | 1; // Force Thumb, as CORTEX only support it - - // Perform a backtrace - MinSerial::TX("Backtrace:"); - int ctr = 0; - UnwindStart(&btf, &UnwCallbacks, &ctr); -} - -#else // !__arm__ && !__thumb__ - -void backtrace() {} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/backtrace.h b/src/HAL/shared/backtrace/backtrace.h deleted file mode 100644 index 5d2ba60..0000000 --- a/src/HAL/shared/backtrace/backtrace.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// Perform a backtrace to the serial port -void backtrace(); - -// Perform a backtrace to the serial port -void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc); diff --git a/src/HAL/shared/backtrace/unwarm.cpp b/src/HAL/shared/backtrace/unwarm.cpp deleted file mode 100644 index adbcca6..0000000 --- a/src/HAL/shared/backtrace/unwarm.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Utility functions and glue for ARM unwinding sub-modules. - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - -#define MODULE_NAME "UNWARM" - -#include -#include -#include -#include -#include "unwarm.h" -#include "unwarmmem.h" - -#ifdef UNW_DEBUG - -/** - * Printf wrapper. - * This is used such that alternative outputs for any output can be selected - * by modification of this wrapper function. - */ -void UnwPrintf(const char *format, ...) { - va_list args; - - va_start( args, format ); - vprintf(format, args ); -} -#endif - -/** - * Invalidate all general purpose registers. - */ -void UnwInvalidateRegisterFile(RegData *regFile) { - uint8_t t = 0; - do { - regFile[t].o = REG_VAL_INVALID; - t++; - } while (t < 13); -} - - -/** - * Initialize the data used for unwinding. - */ -void UnwInitState(UnwState * const state, /**< Pointer to structure to fill. */ - const UnwindCallbacks *cb, /**< Callbacks. */ - void *rptData, /**< Data to pass to report function. */ - uint32_t pcValue, /**< PC at which to start unwinding. */ - uint32_t spValue) { /**< SP at which to start unwinding. */ - - UnwInvalidateRegisterFile(state->regData); - - /* Store the pointer to the callbacks */ - state->cb = cb; - state->reportData = rptData; - - /* Setup the SP and PC */ - state->regData[13].v = spValue; - state->regData[13].o = REG_VAL_FROM_CONST; - state->regData[15].v = pcValue; - state->regData[15].o = REG_VAL_FROM_CONST; - - UnwPrintd3("\nInitial: PC=0x%08x SP=0x%08x\n", pcValue, spValue); - - /* Invalidate all memory addresses */ - memset(state->memData.used, 0, sizeof(state->memData.used)); -} - -// Detect if function names are available -static int __attribute__ ((noinline)) has_function_names() { - uint32_t flag_word = ((uint32_t*)(((uint32_t)(&has_function_names)) & (-4))) [-1]; - return ((flag_word & 0xFF000000) == 0xFF000000) ? 1 : 0; -} - -/** - * Call the report function to indicate some return address. - * This returns the value of the report function, which if true - * indicates that unwinding may continue. - */ -bool UnwReportRetAddr(UnwState * const state, uint32_t addr) { - - UnwReport entry; - - // We found two acceptable values. - entry.name = nullptr; - entry.address = addr & 0xFFFFFFFE; // Remove Thumb bit - entry.function = 0; - - // If there are function names, try to solve name - if (has_function_names()) { - - // Lets find the function name, if possible - - // Align address to 4 bytes - uint32_t pf = addr & (-4); - - // Scan backwards until we find the function name - uint32_t v; - while (state->cb->readW(pf-4,&v)) { - - // Check if name descriptor is valid - if ((v & 0xFFFFFF00) == 0xFF000000 && (v & 0xFF) > 1) { - // Assume the name was found! - entry.name = ((const char*)pf) - 4 - (v & 0xFF); - entry.function = pf; - break; - } - - // Go backwards to the previous word - pf -= 4; - } - } - - /* Cast away const from reportData. - * The const is only to prevent the unw module modifying the data. - */ - return state->cb->report((void *)state->reportData, &entry); -} - - -/** - * Write some register to memory. - * This will store some register and meta data onto the virtual stack. - * The address for the write - * \param state [in/out] The unwinding state. - * \param wAddr [in] The address at which to write the data. - * \param reg [in] The register to store. - * \return true if the write was successful, false otherwise. - */ -bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegData * const reg) { - return UnwMemHashWrite(&state->memData, addr, reg->v, M_IsOriginValid(reg->o)); -} - -/** - * Read a register from memory. - * This will read a register from memory, and setup the meta data. - * If the register has been previously written to memory using - * UnwMemWriteRegister, the local hash will be used to return the - * value while respecting whether the data was valid or not. If the - * register was previously written and was invalid at that point, - * REG_VAL_INVALID will be returned in *reg. - * \param state [in] The unwinding state. - * \param addr [in] The address to read. - * \param reg [out] The result, containing the data value and the origin - * which will be REG_VAL_FROM_MEMORY, or REG_VAL_INVALID. - * \return true if the address could be read and *reg has been filled in. - * false is the data could not be read. - */ -bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg) { - bool tracked; - - // Check if the value can be found in the hash - if (UnwMemHashRead(&state->memData, addr, ®->v, &tracked)) { - reg->o = tracked ? REG_VAL_FROM_MEMORY : REG_VAL_INVALID; - return true; - } - else if (state->cb->readW(addr, ®->v)) { // Not in the hash, so read from real memory - reg->o = REG_VAL_FROM_MEMORY; - return true; - } - else return false; // Not in the hash, and failed to read from memory -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwarm.h b/src/HAL/shared/backtrace/unwarm.h deleted file mode 100644 index edae906..0000000 --- a/src/HAL/shared/backtrace/unwarm.h +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Internal interface between the ARM unwinding sub-modules. - **************************************************************************/ - -#pragma once - -#include "unwinder.h" - -/** The maximum number of instructions to interpet in a function. - * Unwinding will be unconditionally stopped and UNWIND_EXHAUSTED returned - * if more than this number of instructions are interpreted in a single - * function without unwinding a stack frame. This prevents infinite loops - * or corrupted program memory from preventing unwinding from progressing. - */ -#define UNW_MAX_INSTR_COUNT 500 - -/** The size of the hash used to track reads and writes to memory. - * This should be a prime value for efficiency. - */ -#define MEM_HASH_SIZE 31 - -/*************************************************************************** - * Type Definitions - **************************************************************************/ - -typedef enum { - /** Invalid value. */ - REG_VAL_INVALID = 0x00, - REG_VAL_FROM_STACK = 0x01, - REG_VAL_FROM_MEMORY = 0x02, - REG_VAL_FROM_CONST = 0x04, - REG_VAL_ARITHMETIC = 0x80 -} RegValOrigin; - - -/** Type for tracking information about a register. - * This stores the register value, as well as other data that helps unwinding. - */ -typedef struct { - - /** The value held in the register. */ - uint32_t v; - - /** The origin of the register value. - * This is used to track how the value in the register was loaded. - */ - int o; /* (RegValOrigin) */ -} RegData; - - -/** Structure used to track reads and writes to memory. - * This structure is used as a hash to store a small number of writes - * to memory. - */ -typedef struct { - /** Memory contents. */ - uint32_t v[MEM_HASH_SIZE]; - - /** Address at which v[n] represents. */ - uint32_t a[MEM_HASH_SIZE]; - - /** Indicates whether the data in v[n] and a[n] is occupied. - * Each bit represents one hash value. - */ - uint8_t used[(MEM_HASH_SIZE + 7) / 8]; - - /** Indicates whether the data in v[n] is valid. - * This allows a[n] to be set, but for v[n] to be marked as invalid. - * Specifically this is needed for when an untracked register value - * is written to memory. - */ - uint8_t tracked[(MEM_HASH_SIZE + 7) / 8]; -} MemData; - - -/** Structure that is used to keep track of unwinding meta-data. - * This data is passed between all the unwinding functions. - */ -typedef struct { - /** The register values and meta-data. */ - RegData regData[16]; - - /** Memory tracking data. */ - MemData memData; - - /** Pointer to the callback functions */ - const UnwindCallbacks *cb; - - /** Pointer to pass to the report function. */ - const void *reportData; -} UnwState; - -/*************************************************************************** - * Macros - **************************************************************************/ - -#define M_IsOriginValid(v) !!((v) & 0x7F) -#define M_Origin2Str(v) ((v) ? "VALID" : "INVALID") - -#ifdef UNW_DEBUG -#define UnwPrintd1(a) state->cb->printf(a) -#define UnwPrintd2(a,b) state->cb->printf(a,b) -#define UnwPrintd3(a,b,c) state->cb->printf(a,b,c) -#define UnwPrintd4(a,b,c,d) state->cb->printf(a,b,c,d) -#define UnwPrintd5(a,b,c,d,e) state->cb->printf(a,b,c,d,e) -#define UnwPrintd6(a,b,c,d,e,f) state->cb->printf(a,b,c,d,e,f) -#define UnwPrintd7(a,b,c,d,e,f,g) state->cb->printf(a,b,c,d,e,f,g) -#define UnwPrintd8(a,b,c,d,e,f,g,h) state->cb->printf(a,b,c,d,e,f,g,h) -#else -#define UnwPrintd1(a) -#define UnwPrintd2(a,b) -#define UnwPrintd3(a,b,c) -#define UnwPrintd4(a,b,c,d) -#define UnwPrintd5(a,b,c,d,e) -#define UnwPrintd6(a,b,c,d,e,f) -#define UnwPrintd7(a,b,c,d,e,f,g) -#define UnwPrintd8(a,b,c,d,e,f,g,h) -#endif - -/*************************************************************************** - * Function Prototypes - **************************************************************************/ - -UnwResult UnwStartArm(UnwState * const state); -UnwResult UnwStartThumb(UnwState * const state); -void UnwInvalidateRegisterFile(RegData *regFile); -void UnwInitState(UnwState * const state, const UnwindCallbacks *cb, void *rptData, uint32_t pcValue, uint32_t spValue); -bool UnwReportRetAddr(UnwState * const state, uint32_t addr); -bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegData * const reg); -bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg); -void UnwMemHashGC(UnwState * const state); diff --git a/src/HAL/shared/backtrace/unwarm_arm.cpp b/src/HAL/shared/backtrace/unwarm_arm.cpp deleted file mode 100644 index decf74e..0000000 --- a/src/HAL/shared/backtrace/unwarm_arm.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Abstract interpreter for ARM mode. - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - -#define MODULE_NAME "UNWARM_ARM" - -#include -#include "unwarm.h" - -/** Check if some instruction is a data-processing instruction. - * Decodes the passed instruction, checks if it is a data-processing and - * verifies that the parameters and operation really indicate a data- - * processing instruction. This is needed because some parts of the - * instruction space under this instruction can be extended or represent - * other operations such as MRS, MSR. - * - * \param[in] inst The instruction word. - * \retval true Further decoding of the instruction indicates that this is - * a valid data-processing instruction. - * \retval false This is not a data-processing instruction, - */ -static bool isDataProc(uint32_t instr) { - uint8_t opcode = (instr & 0x01E00000) >> 21; - if ((instr & 0xFC000000) != 0xE0000000) return false; - - /* TST, TEQ, CMP and CMN all require S to be set */ - bool S = !!(instr & 0x00100000); - if (!S && opcode >= 8 && opcode <= 11) return false; - - return true; -} - -UnwResult UnwStartArm(UnwState * const state) { - uint16_t t = UNW_MAX_INSTR_COUNT; - - for (;;) { - uint32_t instr; - - /* Attempt to read the instruction */ - if (!state->cb->readW(state->regData[15].v, &instr)) - return UNWIND_IREAD_W_FAIL; - - UnwPrintd4("A %x %x %08x:", state->regData[13].v, state->regData[15].v, instr); - - /* Check that the PC is still on Arm alignment */ - if (state->regData[15].v & 0x3) { - UnwPrintd1("\nError: PC misalignment\n"); - return UNWIND_INCONSISTENT; - } - - /* Check that the SP and PC have not been invalidated */ - if (!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) { - UnwPrintd1("\nError: PC or SP invalidated\n"); - return UNWIND_INCONSISTENT; - } - - /* Branch and Exchange (BX) - * This is tested prior to data processing to prevent - * mis-interpretation as an invalid TEQ instruction. - */ - if ((instr & 0xFFFFFFF0) == 0xE12FFF10) { - uint8_t rn = instr & 0xF; - - UnwPrintd4("BX r%d\t ; r%d %s\n", rn, rn, M_Origin2Str(state->regData[rn].o)); - - if (!M_IsOriginValid(state->regData[rn].o)) { - UnwPrintd1("\nUnwind failure: BX to untracked register\n"); - return UNWIND_FAILURE; - } - - /* Set the new PC value */ - state->regData[15].v = state->regData[rn].v; - - /* Check if the return value is from the stack */ - if (state->regData[rn].o == REG_VAL_FROM_STACK) { - - /* Now have the return address */ - UnwPrintd2(" Return PC=%x\n", state->regData[15].v & (~0x1)); - - /* Report the return address */ - if (!UnwReportRetAddr(state, state->regData[rn].v)) - return UNWIND_TRUNCATED; - } - - /* Determine the return mode */ - if (state->regData[rn].v & 0x1) /* Branching to THUMB */ - return UnwStartThumb(state); - - /* Branch to ARM */ - /* Account for the auto-increment which isn't needed */ - state->regData[15].v -= 4; - } - /* Branch */ - else if ((instr & 0xFF000000) == 0xEA000000) { - - int32_t offset = (instr & 0x00FFFFFF) << 2; - - /* Sign extend if needed */ - if (offset & 0x02000000) offset |= 0xFC000000; - - UnwPrintd2("B %d\n", offset); - - /* Adjust PC */ - state->regData[15].v += offset; - - /* Account for pre-fetch, where normally the PC is 8 bytes - * ahead of the instruction just executed. - */ - state->regData[15].v += 4; - } - - /* MRS */ - else if ((instr & 0xFFBF0FFF) == 0xE10F0000) { - uint8_t rd = (instr & 0x0000F000) >> 12; - #ifdef UNW_DEBUG - const bool R = !!(instr & 0x00400000); - UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd); - #endif - - /* Status registers untracked */ - state->regData[rd].o = REG_VAL_INVALID; - } - /* MSR */ - else if ((instr & 0xFFB0F000) == 0xE120F000) { - #ifdef UNW_DEBUG - UnwPrintd2("MSR %s_?, ???", (instr & 0x00400000) ? "SPSR" : "CPSR"); - #endif - - /* Status registers untracked. - * Potentially this could change processor mode and switch - * banked registers r8-r14. Most likely is that r13 (sp) will - * be banked. However, invalidating r13 will stop unwinding - * when potentially this write is being used to disable/enable - * interrupts (a common case). Therefore no invalidation is - * performed. - */ - } - /* Data processing */ - else if (isDataProc(instr)) { - bool I = !!(instr & 0x02000000); - uint8_t opcode = (instr & 0x01E00000) >> 21; - #ifdef UNW_DEBUG - bool S = !!(instr & 0x00100000); - #endif - uint8_t rn = (instr & 0x000F0000) >> 16; - uint8_t rd = (instr & 0x0000F000) >> 12; - uint16_t operand2 = (instr & 0x00000FFF); - uint32_t op2val; - int op2origin; - - switch (opcode) { - case 0: UnwPrintd4("AND%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 1: UnwPrintd4("EOR%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 2: UnwPrintd4("SUB%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 3: UnwPrintd4("RSB%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 4: UnwPrintd4("ADD%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 5: UnwPrintd4("ADC%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 6: UnwPrintd4("SBC%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 7: UnwPrintd4("RSC%s r%d,r%d,", S ? "S" : "", rd, rn); break; - case 8: UnwPrintd3("TST%s r%d,", S ? "S" : "", rn); break; - case 9: UnwPrintd3("TEQ%s r%d,", S ? "S" : "", rn); break; - case 10: UnwPrintd3("CMP%s r%d,", S ? "S" : "", rn); break; - case 11: UnwPrintd3("CMN%s r%d,", S ? "S" : "", rn); break; - case 12: UnwPrintd3("ORR%s r%d,", S ? "S" : "", rn); break; - case 13: UnwPrintd3("MOV%s r%d,", S ? "S" : "", rd); break; - case 14: UnwPrintd4("BIC%s r%d,r%d", S ? "S" : "", rd, rn); break; - case 15: UnwPrintd3("MVN%s r%d,", S ? "S" : "", rd); break; - } - - /* Decode operand 2 */ - if (I) { - uint8_t shiftDist = (operand2 & 0x0F00) >> 8; - uint8_t shiftConst = (operand2 & 0x00FF); - - /* rotate const right by 2 * shiftDist */ - shiftDist *= 2; - op2val = (shiftConst >> shiftDist) | - (shiftConst << (32 - shiftDist)); - op2origin = REG_VAL_FROM_CONST; - - UnwPrintd2("#0x%x", op2val); - } - else { - - /* Register and shift */ - uint8_t rm = (operand2 & 0x000F); - uint8_t regShift = !!(operand2 & 0x0010); - uint8_t shiftType = (operand2 & 0x0060) >> 5; - uint32_t shiftDist; - #ifdef UNW_DEBUG - const char * const shiftMnu[4] = { "LSL", "LSR", "ASR", "ROR" }; - #endif - UnwPrintd2("r%d ", rm); - - /* Get the shift distance */ - if (regShift) { - uint8_t rs = (operand2 & 0x0F00) >> 8; - - if (operand2 & 0x00800) { - UnwPrintd1("\nError: Bit should be zero\n"); - return UNWIND_ILLEGAL_INSTR; - } - else if (rs == 15) { - UnwPrintd1("\nError: Cannot use R15 with register shift\n"); - return UNWIND_ILLEGAL_INSTR; - } - - /* Get shift distance */ - shiftDist = state->regData[rs].v; - op2origin = state->regData[rs].o; - - UnwPrintd7("%s r%d\t; r%d %s r%d %s", shiftMnu[shiftType], rs, rm, M_Origin2Str(state->regData[rm].o), rs, M_Origin2Str(state->regData[rs].o)); - } - else { - shiftDist = (operand2 & 0x0F80) >> 7; - op2origin = REG_VAL_FROM_CONST; - if (shiftDist) UnwPrintd3("%s #%d", shiftMnu[shiftType], shiftDist); - UnwPrintd3("\t; r%d %s", rm, M_Origin2Str(state->regData[rm].o)); - } - - /* Apply the shift type to the source register */ - switch (shiftType) { - case 0: /* logical left */ - op2val = state->regData[rm].v << shiftDist; - break; - - case 1: /* logical right */ - if (!regShift && shiftDist == 0) shiftDist = 32; - op2val = state->regData[rm].v >> shiftDist; - break; - - case 2: /* arithmetic right */ - if (!regShift && shiftDist == 0) shiftDist = 32; - - if (state->regData[rm].v & 0x80000000) { - /* Register shifts maybe greater than 32 */ - if (shiftDist >= 32) - op2val = 0xFFFFFFFF; - else - op2val = (state->regData[rm].v >> shiftDist) | (0xFFFFFFFF << (32 - shiftDist)); - } - else - op2val = state->regData[rm].v >> shiftDist; - break; - - case 3: /* rotate right */ - - if (!regShift && shiftDist == 0) { - /* Rotate right with extend. - * This uses the carry bit and so always has an - * untracked result. - */ - op2origin = REG_VAL_INVALID; - op2val = 0; - } - else { - /* Limit shift distance to 0-31 incase of register shift */ - shiftDist &= 0x1F; - - op2val = (state->regData[rm].v >> shiftDist) | - (state->regData[rm].v << (32 - shiftDist)); - } - break; - - default: - UnwPrintd2("\nError: Invalid shift type: %d\n", shiftType); - return UNWIND_FAILURE; - } - - /* Decide the data origin */ - if (M_IsOriginValid(op2origin) && M_IsOriginValid(state->regData[rm].o)) - op2origin = REG_VAL_ARITHMETIC | state->regData[rm].o; - else - op2origin = REG_VAL_INVALID; - } - - /* Propagate register validity */ - switch (opcode) { - case 0: /* AND: Rd := Op1 AND Op2 */ - case 1: /* EOR: Rd := Op1 EOR Op2 */ - case 2: /* SUB: Rd:= Op1 - Op2 */ - case 3: /* RSB: Rd:= Op2 - Op1 */ - case 4: /* ADD: Rd:= Op1 + Op2 */ - case 12: /* ORR: Rd:= Op1 OR Op2 */ - case 14: /* BIC: Rd:= Op1 AND NOT Op2 */ - if (!M_IsOriginValid(state->regData[rn].o) || - !M_IsOriginValid(op2origin)) { - state->regData[rd].o = REG_VAL_INVALID; - } - else { - state->regData[rd].o = state->regData[rn].o; - state->regData[rd].o = (RegValOrigin)(state->regData[rd].o | op2origin); - } - break; - - case 5: /* ADC: Rd:= Op1 + Op2 + C */ - case 6: /* SBC: Rd:= Op1 - Op2 + C */ - case 7: /* RSC: Rd:= Op2 - Op1 + C */ - /* CPSR is not tracked */ - state->regData[rd].o = REG_VAL_INVALID; - break; - - case 8: /* TST: set condition codes on Op1 AND Op2 */ - case 9: /* TEQ: set condition codes on Op1 EOR Op2 */ - case 10: /* CMP: set condition codes on Op1 - Op2 */ - case 11: /* CMN: set condition codes on Op1 + Op2 */ - break; - - case 13: /* MOV: Rd:= Op2 */ - case 15: /* MVN: Rd:= NOT Op2 */ - state->regData[rd].o = (RegValOrigin) op2origin; - break; - } - - /* Account for pre-fetch by temporarily adjusting PC */ - if (rn == 15) { - - /* If the shift amount is specified in the instruction, - * the PC will be 8 bytes ahead. If a register is used - * to specify the shift amount the PC will be 12 bytes - * ahead. - */ - state->regData[rn].v += ((!I && (operand2 & 0x0010)) ? 12 : 8); - } - - /* Compute values */ - switch (opcode) { - case 0: /* AND: Rd := Op1 AND Op2 */ - state->regData[rd].v = state->regData[rn].v & op2val; - break; - - case 1: /* EOR: Rd := Op1 EOR Op2 */ - state->regData[rd].v = state->regData[rn].v ^ op2val; - break; - - case 2: /* SUB: Rd:= Op1 - Op2 */ - state->regData[rd].v = state->regData[rn].v - op2val; - break; - case 3: /* RSB: Rd:= Op2 - Op1 */ - state->regData[rd].v = op2val - state->regData[rn].v; - break; - - case 4: /* ADD: Rd:= Op1 + Op2 */ - state->regData[rd].v = state->regData[rn].v + op2val; - break; - - case 5: /* ADC: Rd:= Op1 + Op2 + C */ - case 6: /* SBC: Rd:= Op1 - Op2 + C */ - case 7: /* RSC: Rd:= Op2 - Op1 + C */ - case 8: /* TST: set condition codes on Op1 AND Op2 */ - case 9: /* TEQ: set condition codes on Op1 EOR Op2 */ - case 10: /* CMP: set condition codes on Op1 - Op2 */ - case 11: /* CMN: set condition codes on Op1 + Op2 */ - UnwPrintd1("\t; ????"); - break; - - case 12: /* ORR: Rd:= Op1 OR Op2 */ - state->regData[rd].v = state->regData[rn].v | op2val; - break; - - case 13: /* MOV: Rd:= Op2 */ - state->regData[rd].v = op2val; - break; - - case 14: /* BIC: Rd:= Op1 AND NOT Op2 */ - state->regData[rd].v = state->regData[rn].v & (~op2val); - break; - - case 15: /* MVN: Rd:= NOT Op2 */ - state->regData[rd].v = ~op2val; - break; - } - - /* Remove the prefetch offset from the PC */ - if (rd != 15 && rn == 15) - state->regData[rn].v -= ((!I && (operand2 & 0x0010)) ? 12 : 8); - } - - /* Block Data Transfer - * LDM, STM - */ - else if ((instr & 0xFE000000) == 0xE8000000) { - - bool P = !!(instr & 0x01000000), - U = !!(instr & 0x00800000), - S = !!(instr & 0x00400000), - W = !!(instr & 0x00200000), - L = !!(instr & 0x00100000); - uint16_t baseReg = (instr & 0x000F0000) >> 16; - uint16_t regList = (instr & 0x0000FFFF); - uint32_t addr = state->regData[baseReg].v; - bool addrValid = M_IsOriginValid(state->regData[baseReg].o); - int8_t r; - - #ifdef UNW_DEBUG - /* Display the instruction */ - if (L) - UnwPrintd6("LDM%c%c r%d%s, {reglist}%s\n", P ? 'E' : 'F', U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); - else - UnwPrintd6("STM%c%c r%d%s, {reglist}%s\n", !P ? 'E' : 'F', !U ? 'D' : 'A', baseReg, W ? "!" : "", S ? "^" : ""); - #endif - - /* S indicates that banked registers (untracked) are used, unless - * this is a load including the PC when the S-bit indicates that - * that CPSR is loaded from SPSR (also untracked, but ignored). - */ - if (S && (!L || (regList & (0x01 << 15)) == 0)) { - UnwPrintd1("\nError:S-bit set requiring banked registers\n"); - return UNWIND_FAILURE; - } - else if (baseReg == 15) { - UnwPrintd1("\nError: r15 used as base register\n"); - return UNWIND_FAILURE; - } - else if (regList == 0) { - UnwPrintd1("\nError: Register list empty\n"); - return UNWIND_FAILURE; - } - - /* Check if ascending or descending. - * Registers are loaded/stored in order of address. - * i.e. r0 is at the lowest address, r15 at the highest. - */ - r = U ? 0 : 15; - do { - - /* Check if the register is to be transferred */ - if (regList & (0x01 << r)) { - - if (P) addr += U ? 4 : -4; - - if (L) { - - if (addrValid) { - - if (!UnwMemReadRegister(state, addr, &state->regData[r])) - return UNWIND_DREAD_W_FAIL; - - /* Update the origin if read via the stack pointer */ - if (M_IsOriginValid(state->regData[r].o) && baseReg == 13) - state->regData[r].o = REG_VAL_FROM_STACK; - - UnwPrintd5(" R%d = 0x%08x\t; r%d %s\n",r,state->regData[r].v,r, M_Origin2Str(state->regData[r].o)); - } - else { - /* Invalidate the register as the base reg was invalid */ - state->regData[r].o = REG_VAL_INVALID; - UnwPrintd2(" R%d = ???\n", r); - } - } - else { - if (addrValid && !UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DWRITE_W_FAIL; - - UnwPrintd2(" R%d = 0x%08x\n", r); - } - - if (!P) addr += U ? 4 : -4; - } - - /* Check the next register */ - r += U ? 1 : -1; - - } while (r >= 0 && r <= 15); - - /* Check the writeback bit */ - if (W) state->regData[baseReg].v = addr; - - /* Check if the PC was loaded */ - if (L && (regList & (0x01 << 15))) { - if (!M_IsOriginValid(state->regData[15].o)) { - /* Return address is not valid */ - UnwPrintd1("PC popped with invalid address\n"); - return UNWIND_FAILURE; - } - else { - /* Store the return address */ - if (!UnwReportRetAddr(state, state->regData[15].v)) - return UNWIND_TRUNCATED; - - UnwPrintd2(" Return PC=0x%x", state->regData[15].v); - - /* Determine the return mode */ - if (state->regData[15].v & 0x1) { - /* Branching to THUMB */ - return UnwStartThumb(state); - } - else { - /* Branch to ARM */ - - /* Account for the auto-increment which isn't needed */ - state->regData[15].v -= 4; - } - } - } - } - else { - UnwPrintd1("????"); - - /* Unknown/undecoded. May alter some register, so invalidate file */ - UnwInvalidateRegisterFile(state->regData); - } - - UnwPrintd1("\n"); - - /* Should never hit the reset vector */ - if (state->regData[15].v == 0) return UNWIND_RESET; - - /* Check next address */ - state->regData[15].v += 4; - - /* Garbage collect the memory hash (used only for the stack) */ - UnwMemHashGC(state); - - if (--t == 0) return UNWIND_EXHAUSTED; - - } - - return UNWIND_UNSUPPORTED; -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwarm_thumb.cpp b/src/HAL/shared/backtrace/unwarm_thumb.cpp deleted file mode 100644 index 0c6a706..0000000 --- a/src/HAL/shared/backtrace/unwarm_thumb.cpp +++ /dev/null @@ -1,1066 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Abstract interpretation for Thumb mode. - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - -#define MODULE_NAME "UNWARM_THUMB" - -#include -#include "unwarm.h" - -/** Sign extend an 11 bit value. - * This function simply inspects bit 11 of the input \a value, and if - * set, the top 5 bits are set to give a 2's compliment signed value. - * \param value The value to sign extend. - * \return The signed-11 bit value stored in a 16bit data type. - */ -static int32_t signExtend11(const uint16_t value) { - return (value & 0x400) ? value | 0xFFFFF800 : value; -} - -UnwResult UnwStartThumb(UnwState * const state) { - uint16_t t = UNW_MAX_INSTR_COUNT; - uint32_t lastJumpAddr = 0; // Last JUMP address, to try to detect infinite loops - bool loopDetected = false; // If a loop was detected - - for (;;) { - uint16_t instr; - - /* Attempt to read the instruction */ - if (!state->cb->readH(state->regData[15].v & (~0x1), &instr)) - return UNWIND_IREAD_H_FAIL; - - UnwPrintd4("T %x %x %04x:", state->regData[13].v, state->regData[15].v, instr); - - /* Check that the PC is still on Thumb alignment */ - if (!(state->regData[15].v & 0x1)) { - UnwPrintd1("\nError: PC misalignment\n"); - return UNWIND_INCONSISTENT; - } - - /* Check that the SP and PC have not been invalidated */ - if (!M_IsOriginValid(state->regData[13].o) || !M_IsOriginValid(state->regData[15].o)) { - UnwPrintd1("\nError: PC or SP invalidated\n"); - return UNWIND_INCONSISTENT; - } - - /* - * Detect 32bit thumb instructions - */ - if ((instr & 0xE000) == 0xE000 && (instr & 0x1800) != 0) { - uint16_t instr2; - - /* Check next address */ - state->regData[15].v += 2; - - /* Attempt to read the 2nd part of the instruction */ - if (!state->cb->readH(state->regData[15].v & (~0x1), &instr2)) - return UNWIND_IREAD_H_FAIL; - - UnwPrintd3(" %x %04x:", state->regData[15].v, instr2); - - /* - * Load/Store multiple: Only interpret - * PUSH and POP - */ - if ((instr & 0xFE6F) == 0xE82D) { - bool L = !!(instr & 0x10); - uint16_t rList = instr2; - - if (L) { - uint8_t r; - - /* Load from memory: POP */ - UnwPrintd1("POP {Rlist}\n"); - - /* Load registers from stack */ - for (r = 0; r < 16; r++) { - if (rList & (0x1 << r)) { - - /* Read the word */ - if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DREAD_W_FAIL; - - /* Alter the origin to be from the stack if it was valid */ - if (M_IsOriginValid(state->regData[r].o)) { - - state->regData[r].o = REG_VAL_FROM_STACK; - - /* If restoring the PC */ - if (r == 15) { - - /* The bottom bit should have been set to indicate that - * the caller was from Thumb. This would allow return - * by BX for interworking APCS. - */ - if ((state->regData[15].v & 0x1) == 0) { - UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); - - /* Pop into the PC will not switch mode */ - return UNWIND_INCONSISTENT; - } - - /* Store the return address */ - if (!UnwReportRetAddr(state, state->regData[15].v)) - return UNWIND_TRUNCATED; - - /* Now have the return address */ - UnwPrintd2(" Return PC=%x\n", state->regData[15].v); - - /* Compensate for the auto-increment, which isn't needed here */ - state->regData[15].v -= 2; - - } - - } else { - - if (r == 15) { - /* Return address is not valid */ - UnwPrintd1("PC popped with invalid address\n"); - return UNWIND_FAILURE; - } - } - - state->regData[13].v += 4; - - UnwPrintd3(" r%d = 0x%08x\n", r, state->regData[r].v); - } - } - } - else { - int8_t r; - - /* Store to memory: PUSH */ - UnwPrintd1("PUSH {Rlist}"); - - for (r = 15; r >= 0; r--) { - if (rList & (0x1 << r)) { - UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o)); - - state->regData[13].v -= 4; - - if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DWRITE_W_FAIL; - } - } - } - } - /* - * PUSH register - */ - else if (instr == 0xF84D && (instr2 & 0x0FFF) == 0x0D04) { - uint8_t r = instr2 >> 12; - - /* Store to memory: PUSH */ - UnwPrintd2("PUSH {R%d}\n", r); - UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o)); - - state->regData[13].v -= 4; - - if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DWRITE_W_FAIL; - } - /* - * POP register - */ - else if (instr == 0xF85D && (instr2 & 0x0FFF) == 0x0B04) { - uint8_t r = instr2 >> 12; - - /* Load from memory: POP */ - UnwPrintd2("POP {R%d}\n", r); - - /* Read the word */ - if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DREAD_W_FAIL; - - /* Alter the origin to be from the stack if it was valid */ - if (M_IsOriginValid(state->regData[r].o)) { - - state->regData[r].o = REG_VAL_FROM_STACK; - - /* If restoring the PC */ - if (r == 15) { - - /* The bottom bit should have been set to indicate that - * the caller was from Thumb. This would allow return - * by BX for interworking APCS. - */ - if ((state->regData[15].v & 0x1) == 0) { - UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); - - /* Pop into the PC will not switch mode */ - return UNWIND_INCONSISTENT; - } - - /* Store the return address */ - if (!UnwReportRetAddr(state, state->regData[15].v)) - return UNWIND_TRUNCATED; - - /* Now have the return address */ - UnwPrintd2(" Return PC=%x\n", state->regData[15].v); - - /* Compensate for the auto-increment, which isn't needed here */ - state->regData[15].v -= 2; - - } - - } else { - - if (r == 15) { - /* Return address is not valid */ - UnwPrintd1("PC popped with invalid address\n"); - return UNWIND_FAILURE; - } - } - - state->regData[13].v += 4; - - UnwPrintd3(" r%d = 0x%08x\n", r, state->regData[r].v); - } - /* - * TBB / TBH - */ - else if ((instr & 0xFFF0) == 0xE8D0 && (instr2 & 0xFFE0) == 0xF000) { - /* We are only interested in - * the forms - * TBB [PC, ...] - * TBH [PC, ..., LSL #1] - * as those are used by the C compiler to implement - * the switch clauses - */ - uint8_t rn = instr & 0xF; - bool H = !!(instr2 & 0x10); - - UnwPrintd5("TB%c [r%d,r%d%s]\n", H ? 'H' : 'B', rn, (instr2 & 0xF), H ? ",LSL #1" : ""); - - // We are only interested if the RN is the PC. Let's choose the 1st destination - if (rn == 15) { - if (H) { - uint16_t rv; - if (!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) - return UNWIND_DREAD_H_FAIL; - state->regData[15].v += rv * 2; - } - else { - uint8_t rv; - if (!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) - return UNWIND_DREAD_B_FAIL; - state->regData[15].v += rv * 2; - } - } - } - /* - * Unconditional branch - */ - else if ((instr & 0xF800) == 0xF000 && (instr2 & 0xD000) == 0x9000) { - uint32_t v; - - uint8_t S = (instr & 0x400) >> 10; - uint16_t imm10 = (instr & 0x3FF); - uint8_t J1 = (instr2 & 0x2000) >> 13; - uint8_t J2 = (instr2 & 0x0800) >> 11; - uint16_t imm11 = (instr2 & 0x7FF); - - uint8_t I1 = J1 ^ S ^ 1; - uint8_t I2 = J2 ^ S ^ 1; - uint32_t imm32 = (S << 24) | (I1 << 23) | (I2 << 22) |(imm10 << 12) | (imm11 << 1); - if (S) imm32 |= 0xFE000000; - - UnwPrintd2("B %d \n", imm32); - - /* Update PC */ - state->regData[15].v += imm32; - - /* Need to advance by a word to account for pre-fetch. - * Advance by a half word here, allowing the normal address - * advance to account for the other half word. - */ - state->regData[15].v += 2; - - /* Compute the jump address */ - v = state->regData[15].v + 2; - - /* Display PC of next instruction */ - UnwPrintd2(" New PC=%x", v); - - /* Did we detect an infinite loop ? */ - loopDetected = lastJumpAddr == v; - - /* Remember the last address we jumped to */ - lastJumpAddr = v; - } - - /* - * Branch with link - */ - else if ((instr & 0xF800) == 0xF000 && (instr2 & 0xD000) == 0xD000) { - - uint8_t S = (instr & 0x400) >> 10; - uint16_t imm10 = (instr & 0x3FF); - uint8_t J1 = (instr2 & 0x2000) >> 13; - uint8_t J2 = (instr2 & 0x0800) >> 11; - uint16_t imm11 = (instr2 & 0x7FF); - - uint8_t I1 = J1 ^ S ^ 1; - uint8_t I2 = J2 ^ S ^ 1; - uint32_t imm32 = (S << 24) | (I1 << 23) | (I2 << 22) |(imm10 << 12) | (imm11 << 1); - if (S) imm32 |= 0xFE000000; - - UnwPrintd2("BL %d \n", imm32); - - /* Never taken, as we are unwinding the stack */ - if (0) { - - /* Store return address in LR register */ - state->regData[14].v = state->regData[15].v + 2; - state->regData[14].o = REG_VAL_FROM_CONST; - - /* Update PC */ - state->regData[15].v += imm32; - - /* Need to advance by a word to account for pre-fetch. - * Advance by a half word here, allowing the normal address - * advance to account for the other half word. - */ - state->regData[15].v += 2; - - /* Display PC of next instruction */ - UnwPrintd2(" Return PC=%x", state->regData[15].v); - - /* Report the return address, including mode bit */ - if (!UnwReportRetAddr(state, state->regData[15].v)) - return UNWIND_TRUNCATED; - - /* Determine the new mode */ - if (state->regData[15].v & 0x1) { - /* Branching to THUMB */ - - /* Account for the auto-increment which isn't needed */ - state->regData[15].v -= 2; - } - else { - /* Branch to ARM */ - return UnwStartArm(state); - } - } - } - - /* - * Conditional branches. Usually not taken, unless infinite loop is detected - */ - else if ((instr & 0xF800) == 0xF000 && (instr2 & 0xD000) == 0x8000) { - - uint8_t S = (instr & 0x400) >> 10; - uint16_t imm6 = (instr & 0x3F); - uint8_t J1 = (instr2 & 0x2000) >> 13; - uint8_t J2 = (instr2 & 0x0800) >> 11; - uint16_t imm11 = (instr2 & 0x7FF); - - uint8_t I1 = J1 ^ S ^ 1; - uint8_t I2 = J2 ^ S ^ 1; - uint32_t imm32 = (S << 20) | (I1 << 19) | (I2 << 18) |(imm6 << 12) | (imm11 << 1); - if (S) imm32 |= 0xFFE00000; - - UnwPrintd2("Bcond %d\n", imm32); - - /* Take the jump only if a loop is detected */ - if (loopDetected) { - - /* Update PC */ - state->regData[15].v += imm32; - - /* Need to advance by a word to account for pre-fetch. - * Advance by a half word here, allowing the normal address - * advance to account for the other half word. - */ - state->regData[15].v += 2; - - /* Display PC of next instruction */ - UnwPrintd2(" New PC=%x", state->regData[15].v + 2); - } - } - /* - * PC-relative load - * LDR Rd,[PC, #+/-imm] - */ - else if ((instr & 0xFF7F) == 0xF85F) { - uint8_t rt = (instr2 & 0xF000) >> 12; - uint8_t imm12 = (instr2 & 0x0FFF); - bool A = !!(instr & 0x80); - uint32_t address; - - /* Compute load address, adding a word to account for prefetch */ - address = (state->regData[15].v & (~0x3)) + 4; - if (A) address += imm12; - else address -= imm12; - - UnwPrintd4("LDR r%d,[PC #%c0x%08x]", rt, A?'+':'-', address); - - if (!UnwMemReadRegister(state, address, &state->regData[rt])) - return UNWIND_DREAD_W_FAIL; - } - /* - * LDR immediate. - * We are only interested when destination is PC. - * LDR Rt,[Rn , #n] - */ - else if ((instr & 0xFFF0) == 0xF8D0) { - uint8_t rn = (instr & 0xF); - uint8_t rt = (instr2 & 0xF000) >> 12; - uint16_t imm12 = (instr2 & 0xFFF); - - /* If destination is PC and we don't know the source value, then fail */ - if (!M_IsOriginValid(state->regData[rn].o)) { - state->regData[rt].o = state->regData[rn].o; - } - else { - uint32_t address = state->regData[rn].v + imm12; - if (!UnwMemReadRegister(state, address, &state->regData[rt])) - return UNWIND_DREAD_W_FAIL; - } - } - /* - * LDR immediate - * We are only interested when destination is PC. - * LDR Rt,[Rn , #-n] - * LDR Rt,[Rn], #+/-n] - * LDR Rt,[Rn, #+/-n]! - */ - else if ((instr & 0xFFF0) == 0xF850 && (instr2 & 0x0800) == 0x0800) { - uint8_t rn = (instr & 0xF); - uint8_t rt = (instr2 & 0xF000) >> 12; - uint16_t imm8 = (instr2 & 0xFF); - bool P = !!(instr2 & 0x400); - bool U = !!(instr2 & 0x200); - bool W = !!(instr2 & 0x100); - - if (!M_IsOriginValid(state->regData[rn].o)) - state->regData[rt].o = state->regData[rn].o; - else { - uint32_t offaddress = state->regData[rn].v + (U ? imm8 + imm8 : 0), - address = P ? offaddress : state->regData[rn].v; - - if (!UnwMemReadRegister(state, address, &state->regData[rt])) - return UNWIND_DREAD_W_FAIL; - - if (W) state->regData[rn].v = offaddress; - } - } - /* - * LDR (register). - * We are interested in the form - * ldr Rt, [Rn, Rm, lsl #x] - * Where Rt is PC, Rn value is known, Rm is not known or unknown - */ - else if ((instr & 0xFFF0) == 0xF850 && (instr2 & 0x0FC0) == 0x0000) { - const uint8_t rn = (instr & 0xF), - rt = (instr2 & 0xF000) >> 12, - rm = (instr2 & 0xF), - imm2 = (instr2 & 0x30) >> 4; - - if (!M_IsOriginValid(state->regData[rn].o) || !M_IsOriginValid(state->regData[rm].o)) { - - /* If Rt is PC, and Rn is known, then do an exception and assume - Rm equals 0 => This takes the first case in a switch() */ - if (rt == 15 && M_IsOriginValid(state->regData[rn].o)) { - uint32_t address = state->regData[rn].v; - if (!UnwMemReadRegister(state, address, &state->regData[rt])) - return UNWIND_DREAD_W_FAIL; - } - else /* Propagate unknown value */ - state->regData[rt].o = state->regData[rn].o; - - } - else { - uint32_t address = state->regData[rn].v + (state->regData[rm].v << imm2); - if (!UnwMemReadRegister(state, address, &state->regData[rt])) - return UNWIND_DREAD_W_FAIL; - } - } - else { - UnwPrintd1("???? (32)"); - - /* Unknown/undecoded. May alter some register, so invalidate file */ - UnwInvalidateRegisterFile(state->regData); - } - /* End of thumb 32bit code */ - - } - /* Format 1: Move shifted register - * LSL Rd, Rs, #Offset5 - * LSR Rd, Rs, #Offset5 - * ASR Rd, Rs, #Offset5 - */ - else if ((instr & 0xE000) == 0x0000 && (instr & 0x1800) != 0x1800) { - bool signExtend; - const uint8_t op = (instr & 0x1800) >> 11, - offset5 = (instr & 0x07C0) >> 6, - rs = (instr & 0x0038) >> 3, - rd = (instr & 0x0007); - - switch (op) { - case 0: /* LSL */ - UnwPrintd6("LSL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o)); - state->regData[rd].v = state->regData[rs].v << offset5; - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - - case 1: /* LSR */ - UnwPrintd6("LSR r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o)); - state->regData[rd].v = state->regData[rs].v >> offset5; - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - - case 2: /* ASR */ - UnwPrintd6("ASL r%d, r%d, #%d\t; r%d %s", rd, rs, offset5, rs, M_Origin2Str(state->regData[rs].o)); - - signExtend = !!(state->regData[rs].v & 0x8000); - state->regData[rd].v = state->regData[rs].v >> offset5; - if (signExtend) state->regData[rd].v |= 0xFFFFFFFF << (32 - offset5); - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - } - } - /* Format 2: add/subtract - * ADD Rd, Rs, Rn - * ADD Rd, Rs, #Offset3 - * SUB Rd, Rs, Rn - * SUB Rd, Rs, #Offset3 - */ - else if ((instr & 0xF800) == 0x1800) { - bool I = !!(instr & 0x0400); - bool op = !!(instr & 0x0200); - uint8_t rn = (instr & 0x01C0) >> 6; - uint8_t rs = (instr & 0x0038) >> 3; - uint8_t rd = (instr & 0x0007); - - /* Print decoding */ - UnwPrintd6("%s r%d, r%d, %c%d\t;",op ? "SUB" : "ADD",rd, rs,I ? '#' : 'r',rn); - UnwPrintd5("r%d %s, r%d %s",rd, M_Origin2Str(state->regData[rd].o),rs, M_Origin2Str(state->regData[rs].o)); - if (!I) { - - UnwPrintd3(", r%d %s", rn, M_Origin2Str(state->regData[rn].o)); - - /* Perform calculation */ - state->regData[rd].v = state->regData[rs].v + (op ? -state->regData[rn].v : state->regData[rn].v); - - /* Propagate the origin */ - if (M_IsOriginValid(state->regData[rs].o) && M_IsOriginValid(state->regData[rn].o)) { - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - } - else - state->regData[rd].o = REG_VAL_INVALID; - } - else { - /* Perform calculation */ - state->regData[rd].v = state->regData[rs].v + (op ? -rn : rn); - - /* Propagate the origin */ - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - } - } - /* Format 3: move/compare/add/subtract immediate - * MOV Rd, #Offset8 - * CMP Rd, #Offset8 - * ADD Rd, #Offset8 - * SUB Rd, #Offset8 - */ - else if ((instr & 0xE000) == 0x2000) { - - uint8_t op = (instr & 0x1800) >> 11; - uint8_t rd = (instr & 0x0700) >> 8; - uint8_t offset8 = (instr & 0x00FF); - - switch (op) { - case 0: /* MOV */ - UnwPrintd3("MOV r%d, #0x%x", rd, offset8); - state->regData[rd].v = offset8; - state->regData[rd].o = REG_VAL_FROM_CONST; - break; - - case 1: /* CMP */ - /* Irrelevant to unwinding */ - UnwPrintd1("CMP ???"); - break; - - case 2: /* ADD */ - UnwPrintd5("ADD r%d, #0x%x\t; r%d %s", rd, offset8, rd, M_Origin2Str(state->regData[rd].o)); - state->regData[rd].v += offset8; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - - case 3: /* SUB */ - UnwPrintd5("SUB r%d, #0x%d\t; r%d %s", rd, offset8, rd, M_Origin2Str(state->regData[rd].o)); - state->regData[rd].v -= offset8; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - } - } - /* Format 4: ALU operations - * AND Rd, Rs - * EOR Rd, Rs - * LSL Rd, Rs - * LSR Rd, Rs - * ASR Rd, Rs - * ADC Rd, Rs - * SBC Rd, Rs - * ROR Rd, Rs - * TST Rd, Rs - * NEG Rd, Rs - * CMP Rd, Rs - * CMN Rd, Rs - * ORR Rd, Rs - * MUL Rd, Rs - * BIC Rd, Rs - * MVN Rd, Rs - */ - else if ((instr & 0xFC00) == 0x4000) { - uint8_t op = (instr & 0x03C0) >> 6; - uint8_t rs = (instr & 0x0038) >> 3; - uint8_t rd = (instr & 0x0007); - -#ifdef UNW_DEBUG - static const char * const mnu[16] = { - "AND", "EOR", "LSL", "LSR", - "ASR", "ADC", "SBC", "ROR", - "TST", "NEG", "CMP", "CMN", - "ORR", "MUL", "BIC", "MVN" }; -#endif - /* Print the mnemonic and registers */ - switch (op) { - case 0: /* AND */ - case 1: /* EOR */ - case 2: /* LSL */ - case 3: /* LSR */ - case 4: /* ASR */ - case 7: /* ROR */ - case 9: /* NEG */ - case 12: /* ORR */ - case 13: /* MUL */ - case 15: /* MVN */ - UnwPrintd8("%s r%d ,r%d\t; r%d %s, r%d %s",mnu[op],rd, rs, rd, M_Origin2Str(state->regData[rd].o), rs, M_Origin2Str(state->regData[rs].o)); - break; - - case 5: /* ADC */ - case 6: /* SBC */ - UnwPrintd4("%s r%d, r%d", mnu[op], rd, rs); - break; - - case 8: /* TST */ - case 10: /* CMP */ - case 11: /* CMN */ - /* Irrelevant to unwinding */ - UnwPrintd2("%s ???", mnu[op]); - break; - - case 14: /* BIC */ - UnwPrintd5("r%d ,r%d\t; r%d %s", rd, rs, rs, M_Origin2Str(state->regData[rs].o)); - break; - } - - /* Perform operation */ - switch (op) { - case 0: /* AND */ - state->regData[rd].v &= state->regData[rs].v; - break; - - case 1: /* EOR */ - state->regData[rd].v ^= state->regData[rs].v; - break; - - case 2: /* LSL */ - state->regData[rd].v <<= state->regData[rs].v; - break; - - case 3: /* LSR */ - state->regData[rd].v >>= state->regData[rs].v; - break; - - case 4: /* ASR */ - if (state->regData[rd].v & 0x80000000) { - state->regData[rd].v >>= state->regData[rs].v; - state->regData[rd].v |= 0xFFFFFFFF << (32 - state->regData[rs].v); - } - else { - state->regData[rd].v >>= state->regData[rs].v; - } - - break; - - case 5: /* ADC */ - case 6: /* SBC */ - case 8: /* TST */ - case 10: /* CMP */ - case 11: /* CMN */ - break; - - case 7: /* ROR */ - state->regData[rd].v = (state->regData[rd].v >> state->regData[rs].v) | - (state->regData[rd].v << (32 - state->regData[rs].v)); - break; - - case 9: /* NEG */ - state->regData[rd].v = -state->regData[rs].v; - break; - - case 12: /* ORR */ - state->regData[rd].v |= state->regData[rs].v; - break; - - case 13: /* MUL */ - state->regData[rd].v *= state->regData[rs].v; - break; - - case 14: /* BIC */ - state->regData[rd].v &= ~state->regData[rs].v; - break; - - case 15: /* MVN */ - state->regData[rd].v = ~state->regData[rs].v; - break; - } - - /* Propagate data origins */ - switch (op) { - case 0: /* AND */ - case 1: /* EOR */ - case 2: /* LSL */ - case 3: /* LSR */ - case 4: /* ASR */ - case 7: /* ROR */ - case 12: /* ORR */ - case 13: /* MUL */ - case 14: /* BIC */ - if (M_IsOriginValid(state->regData[rd].o) && M_IsOriginValid(state->regData[rs].o)) { - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - } - else - state->regData[rd].o = REG_VAL_INVALID; - break; - - case 5: /* ADC */ - case 6: /* SBC */ - /* C-bit not tracked */ - state->regData[rd].o = REG_VAL_INVALID; - break; - - case 8: /* TST */ - case 10: /* CMP */ - case 11: /* CMN */ - /* Nothing propagated */ - break; - - case 9: /* NEG */ - case 15: /* MVN */ - state->regData[rd].o = state->regData[rs].o; - state->regData[rd].o |= REG_VAL_ARITHMETIC; - break; - } - } - /* Format 5: Hi register operations/branch exchange - * ADD Rd, Hs - * CMP Hd, Rs - * MOV Hd, Hs - */ - else if ((instr & 0xFC00) == 0x4400) { - uint8_t op = (instr & 0x0300) >> 8; - bool h1 = (instr & 0x0080) ? true: false; - bool h2 = (instr & 0x0040) ? true: false; - uint8_t rhs = (instr & 0x0038) >> 3; - uint8_t rhd = (instr & 0x0007); - - /* Adjust the register numbers */ - if (h2) rhs += 8; - if (h1) rhd += 8; - - switch (op) { - case 0: /* ADD */ - UnwPrintd5("ADD r%d, r%d\t; r%d %s", rhd, rhs, rhs, M_Origin2Str(state->regData[rhs].o)); - state->regData[rhd].v += state->regData[rhs].v; - state->regData[rhd].o = state->regData[rhs].o; - state->regData[rhd].o |= REG_VAL_ARITHMETIC; - break; - - case 1: /* CMP */ - /* Irrelevant to unwinding */ - UnwPrintd1("CMP ???"); - break; - - case 2: /* MOV */ - UnwPrintd5("MOV r%d, r%d\t; r%d %s", rhd, rhs, rhd, M_Origin2Str(state->regData[rhs].o)); - state->regData[rhd].v = state->regData[rhs].v; - state->regData[rhd].o = state->regData[rhs].o; - break; - - case 3: /* BX */ - UnwPrintd4("BX r%d\t; r%d %s\n", rhs, rhs, M_Origin2Str(state->regData[rhs].o)); - - /* Only follow BX if the data was from the stack or BX LR */ - if (rhs == 14 || state->regData[rhs].o == REG_VAL_FROM_STACK) { - UnwPrintd2(" Return PC=0x%x\n", state->regData[rhs].v & (~0x1)); - - /* Report the return address, including mode bit */ - if (!UnwReportRetAddr(state, state->regData[rhs].v)) - return UNWIND_TRUNCATED; - - /* Update the PC */ - state->regData[15].v = state->regData[rhs].v; - - /* Determine the new mode */ - if (state->regData[rhs].v & 0x1) { - /* Branching to THUMB */ - - /* Account for the auto-increment which isn't needed */ - state->regData[15].v -= 2; - } - else /* Branch to ARM */ - return UnwStartArm(state); - } - else { - UnwPrintd4("\nError: BX to invalid register: r%d = 0x%x (%s)\n", rhs, state->regData[rhs].o, M_Origin2Str(state->regData[rhs].o)); - return UNWIND_FAILURE; - } - } - } - /* Format 9: PC-relative load - * LDR Rd,[PC, #imm] - */ - else if ((instr & 0xF800) == 0x4800) { - uint8_t rd = (instr & 0x0700) >> 8; - uint8_t word8 = (instr & 0x00FF); - uint32_t address; - - /* Compute load address, adding a word to account for prefetch */ - address = (state->regData[15].v & (~0x3)) + 4 + (word8 << 2); - - UnwPrintd3("LDR r%d, 0x%08x", rd, address); - - if (!UnwMemReadRegister(state, address, &state->regData[rd])) - return UNWIND_DREAD_W_FAIL; - } - /* Format 13: add offset to Stack Pointer - * ADD sp,#+imm - * ADD sp,#-imm - */ - else if ((instr & 0xFF00) == 0xB000) { - uint8_t value = (instr & 0x7F) * 4; - - /* Check the negative bit */ - if ((instr & 0x80) != 0) { - UnwPrintd2("SUB sp,#0x%x", value); - state->regData[13].v -= value; - } - else { - UnwPrintd2("ADD sp,#0x%x", value); - state->regData[13].v += value; - } - } - /* Format 14: push/pop registers - * PUSH {Rlist} - * PUSH {Rlist, LR} - * POP {Rlist} - * POP {Rlist, PC} - */ - else if ((instr & 0xF600) == 0xB400) { - bool L = !!(instr & 0x0800); - bool R = !!(instr & 0x0100); - uint8_t rList = (instr & 0x00FF); - - if (L) { - uint8_t r; - - /* Load from memory: POP */ - UnwPrintd2("POP {Rlist%s}\n", R ? ", PC" : ""); - - for (r = 0; r < 8; r++) { - if (rList & (0x1 << r)) { - - /* Read the word */ - if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DREAD_W_FAIL; - - /* Alter the origin to be from the stack if it was valid */ - if (M_IsOriginValid(state->regData[r].o)) - state->regData[r].o = REG_VAL_FROM_STACK; - - state->regData[13].v += 4; - - UnwPrintd3(" r%d = 0x%08x\n", r, state->regData[r].v); - } - } - - /* Check if the PC is to be popped */ - if (R) { - /* Get the return address */ - if (!UnwMemReadRegister(state, state->regData[13].v, &state->regData[15])) - return UNWIND_DREAD_W_FAIL; - - /* Alter the origin to be from the stack if it was valid */ - if (!M_IsOriginValid(state->regData[15].o)) { - /* Return address is not valid */ - UnwPrintd1("PC popped with invalid address\n"); - return UNWIND_FAILURE; - } - else { - /* The bottom bit should have been set to indicate that - * the caller was from Thumb. This would allow return - * by BX for interworking APCS. - */ - if ((state->regData[15].v & 0x1) == 0) { - UnwPrintd2("Warning: Return address not to Thumb: 0x%08x\n", state->regData[15].v); - - /* Pop into the PC will not switch mode */ - return UNWIND_INCONSISTENT; - } - - /* Store the return address */ - if (!UnwReportRetAddr(state, state->regData[15].v)) - return UNWIND_TRUNCATED; - - /* Now have the return address */ - UnwPrintd2(" Return PC=%x\n", state->regData[15].v); - - /* Update the pc */ - state->regData[13].v += 4; - - /* Compensate for the auto-increment, which isn't needed here */ - state->regData[15].v -= 2; - } - } - } - else { - int8_t r; - - /* Store to memory: PUSH */ - UnwPrintd2("PUSH {Rlist%s}", R ? ", LR" : ""); - - /* Check if the LR is to be pushed */ - if (R) { - UnwPrintd3("\n lr = 0x%08x\t; %s", state->regData[14].v, M_Origin2Str(state->regData[14].o)); - - state->regData[13].v -= 4; - - /* Write the register value to memory */ - if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[14])) - return UNWIND_DWRITE_W_FAIL; - } - - for (r = 7; r >= 0; r--) { - if (rList & (0x1 << r)) { - UnwPrintd4("\n r%d = 0x%08x\t; %s", r, state->regData[r].v, M_Origin2Str(state->regData[r].o)); - - state->regData[13].v -= 4; - - if (!UnwMemWriteRegister(state, state->regData[13].v, &state->regData[r])) - return UNWIND_DWRITE_W_FAIL; - } - } - } - } - - /* - * Conditional branches - * Bcond - */ - else if ((instr & 0xF000) == 0xD000) { - int32_t branchValue = (instr & 0xFF); - if (branchValue & 0x80) branchValue |= 0xFFFFFF00; - - /* Branch distance is twice that specified in the instruction. */ - branchValue *= 2; - - UnwPrintd2("Bcond %d \n", branchValue); - - /* Only take the branch if a loop was detected */ - if (loopDetected) { - - /* Update PC */ - state->regData[15].v += branchValue; - - /* Need to advance by a word to account for pre-fetch. - * Advance by a half word here, allowing the normal address - * advance to account for the other half word. - */ - state->regData[15].v += 2; - - /* Display PC of next instruction */ - UnwPrintd2(" New PC=%x", state->regData[15].v + 2); - } - } - - /* Format 18: unconditional branch - * B label - */ - else if ((instr & 0xF800) == 0xE000) { - uint32_t v; - int32_t branchValue = signExtend11(instr & 0x07FF); - - /* Branch distance is twice that specified in the instruction. */ - branchValue *= 2; - - UnwPrintd2("B %d \n", branchValue); - - /* Update PC */ - state->regData[15].v += branchValue; - - /* Need to advance by a word to account for pre-fetch. - * Advance by a half word here, allowing the normal address - * advance to account for the other half word. - */ - state->regData[15].v += 2; - - /* Compute the jump address */ - v = state->regData[15].v + 2; - - /* Display PC of next instruction */ - UnwPrintd2(" New PC=%x", v); - - /* Did we detect an infinite loop ? */ - loopDetected = lastJumpAddr == v; - - /* Remember the last address we jumped to */ - lastJumpAddr = v; - } - else { - UnwPrintd1("????"); - - /* Unknown/undecoded. May alter some register, so invalidate file */ - UnwInvalidateRegisterFile(state->regData); - } - - UnwPrintd1("\n"); - - /* Should never hit the reset vector */ - if (state->regData[15].v == 0) return UNWIND_RESET; - - /* Check next address */ - state->regData[15].v += 2; - - /* Garbage collect the memory hash (used only for the stack) */ - UnwMemHashGC(state); - - if (--t == 0) return UNWIND_EXHAUSTED; - - } - - return UNWIND_SUCCESS; -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwarmbytab.cpp b/src/HAL/shared/backtrace/unwarmbytab.cpp deleted file mode 100644 index 148927a..0000000 --- a/src/HAL/shared/backtrace/unwarmbytab.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Libbacktrace - * Copyright 2015 Stephen Street - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://www.mozilla.org/en-US/MPL/2.0/ - * - * This library was modified, some bugs fixed, stack address validated - * and adapted to be used in Marlin 3D printer firmware as backtracer - * for exceptions for debugging purposes in 2018 by Eduardo José Tagle. - */ - -#if defined(__arm__) || defined(__thumb__) - -#include "unwarmbytab.h" - -#include -#include - -/* These symbols point to the unwind index and should be provide by the linker script */ -extern "C" const UnwTabEntry __exidx_start[]; -extern "C" const UnwTabEntry __exidx_end[]; - -/* This prevents the linking of libgcc unwinder code */ -void __aeabi_unwind_cpp_pr0() {}; -void __aeabi_unwind_cpp_pr1() {}; -void __aeabi_unwind_cpp_pr2() {}; - -static inline __attribute__((always_inline)) uint32_t prel31_to_addr(const uint32_t *prel31) { - uint32_t offset = (((uint32_t)(*prel31)) << 1) >> 1; - return ((uint32_t)prel31 + offset) & 0x7FFFFFFF; -} - -static const UnwTabEntry *UnwTabSearchIndex(const UnwTabEntry *start, const UnwTabEntry *end, uint32_t ip) { - const UnwTabEntry *middle; - - /* Perform a binary search of the unwind index */ - while (start < end - 1) { - middle = start + ((end - start + 1) >> 1); - if (ip < prel31_to_addr(&middle->addr_offset)) - end = middle; - else - start = middle; - } - return start; -} - -/* - * Get the function name or nullptr if not found - */ -static const char *UnwTabGetFunctionName(const UnwindCallbacks *cb, uint32_t address) { - uint32_t flag_word = 0; - if (!cb->readW(address-4,&flag_word)) - return nullptr; - - if ((flag_word & 0xFF000000) == 0xFF000000) { - return (const char *)(address - 4 - (flag_word & 0x00FFFFFF)); - } - return nullptr; -} - -/** - * Get the next frame unwinding instruction - * - * Return either the instruction or -1 to signal no more instructions - * are available - */ -static int UnwTabGetNextInstruction(const UnwindCallbacks *cb, UnwTabState *ucb) { - int instruction; - - /* Are there more instructions */ - if (ucb->remaining == 0) - return -1; - - /* Extract the current instruction */ - uint32_t v = 0; - if (!cb->readW(ucb->current, &v)) - return -1; - instruction = (v >> (ucb->byte << 3)) & 0xFF; - - /* Move the next byte */ - --ucb->byte; - if (ucb->byte < 0) { - ucb->current += 4; - ucb->byte = 3; - } - --ucb->remaining; - - return instruction; -} - -/** - * Initialize the frame unwinding state - */ -static UnwResult UnwTabStateInit(const UnwindCallbacks *cb, UnwTabState *ucb, uint32_t instructions, const UnwindFrame *frame) { - - /* Initialize control block */ - memset(ucb, 0, sizeof(UnwTabState)); - ucb->current = instructions; - - /* Is a short unwind description */ - uint32_t v = 0; - if (!cb->readW(instructions, &v)) - return UNWIND_DREAD_W_FAIL; - - if ((v & 0xFF000000) == 0x80000000) { - ucb->remaining = 3; - ucb->byte = 2; - /* Is a long unwind description */ - } else if ((v & 0xFF000000) == 0x81000000) { - ucb->remaining = ((v & 0x00FF0000) >> 14) + 2; - ucb->byte = 1; - } else - return UNWIND_UNSUPPORTED_DWARF_PERSONALITY; - - /* Initialize the virtual register set */ - ucb->vrs[7] = frame->fp; - ucb->vrs[13] = frame->sp; - ucb->vrs[14] = frame->lr; - ucb->vrs[15] = 0; - - /* All good */ - return UNWIND_SUCCESS; -} - -/* - * Execute unwinding instructions - */ -static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabState *ucb) { - int instruction; - uint32_t mask, reg, vsp; - - /* Consume all instruction byte */ - while ((instruction = UnwTabGetNextInstruction(cb, ucb)) != -1) { - - if ((instruction & 0xC0) == 0x00) { // ARM_EXIDX_CMD_DATA_POP - /* vsp += (xxxxxx << 2) + 4 */ - ucb->vrs[13] += ((instruction & 0x3F) << 2) + 4; - } - else if ((instruction & 0xC0) == 0x40) { // ARM_EXIDX_CMD_DATA_PUSH - /* vsp -= (xxxxxx << 2) - 4 */ - ucb->vrs[13] -= ((instruction & 0x3F) << 2) - 4; - } - else if ((instruction & 0xF0) == 0x80) { - /* pop under mask {r15-r12},{r11-r4} or refuse to unwind */ - instruction = instruction << 8 | UnwTabGetNextInstruction(cb, ucb); - - /* Check for refuse to unwind */ - if (instruction == 0x8000) // ARM_EXIDX_CMD_REFUSED - return UNWIND_REFUSED; - - /* Pop registers using mask */ // ARM_EXIDX_CMD_REG_POP - vsp = ucb->vrs[13]; - mask = instruction & 0xFFF; - - reg = 4; - while (mask) { - if ((mask & 1) != 0) { - uint32_t v; - if (!cb->readW(vsp,&v)) - return UNWIND_DREAD_W_FAIL; - ucb->vrs[reg] = v; - v += 4; - } - mask >>= 1; - ++reg; - } - - /* Patch up the vrs sp if it was in the mask */ - if (instruction & (1 << (13 - 4))) - ucb->vrs[13] = vsp; - } - else if ((instruction & 0xF0) == 0x90 // ARM_EXIDX_CMD_REG_TO_SP - && instruction != 0x9D - && instruction != 0x9F - ) { - /* vsp = r[nnnn] */ - ucb->vrs[13] = ucb->vrs[instruction & 0x0F]; - } - else if ((instruction & 0xF0) == 0xA0) { // ARM_EXIDX_CMD_REG_POP - /* pop r4-r[4+nnn] or pop r4-r[4+nnn], r14*/ - vsp = ucb->vrs[13]; - - for (reg = 4; reg <= uint32_t((instruction & 0x07) + 4); ++reg) { - uint32_t v; - if (!cb->readW(vsp,&v)) - return UNWIND_DREAD_W_FAIL; - - ucb->vrs[reg] = v; - vsp += 4; - } - - if (instruction & 0x08) { // ARM_EXIDX_CMD_REG_POP - uint32_t v; - if (!cb->readW(vsp,&v)) - return UNWIND_DREAD_W_FAIL; - ucb->vrs[14] = v; - vsp += 4; - } - - ucb->vrs[13] = vsp; - - } - else if (instruction == 0xB0) { // ARM_EXIDX_CMD_FINISH - /* finished */ - if (ucb->vrs[15] == 0) - ucb->vrs[15] = ucb->vrs[14]; - - /* All done unwinding */ - return UNWIND_SUCCESS; - - } - else if (instruction == 0xB1) { // ARM_EXIDX_CMD_REG_POP - /* pop register under mask {r3,r2,r1,r0} */ - vsp = ucb->vrs[13]; - mask = UnwTabGetNextInstruction(cb, ucb); - - reg = 0; - while (mask) { - if ((mask & 1) != 0) { - uint32_t v; - if (!cb->readW(vsp,&v)) - return UNWIND_DREAD_W_FAIL; - - ucb->vrs[reg] = v; - vsp += 4; - } - mask >>= 1; - ++reg; - } - ucb->vrs[13] = (uint32_t)vsp; - - } - else if (instruction == 0xB2) { // ARM_EXIDX_CMD_DATA_POP - /* vps = vsp + 0x204 + (uleb128 << 2) */ - ucb->vrs[13] += 0x204 + (UnwTabGetNextInstruction(cb, ucb) << 2); - } - else if (instruction == 0xB3 // ARM_EXIDX_CMD_VFP_POP - || instruction == 0xC8 - || instruction == 0xC9 - ) { - /* pop VFP double-precision registers */ - vsp = ucb->vrs[13]; - - /* D[ssss]-D[ssss+cccc] */ - uint32_t v; - if (!cb->readW(vsp,&v)) - return UNWIND_DREAD_W_FAIL; - - ucb->vrs[14] = v; - vsp += 4; - - if (instruction == 0xC8) { - /* D[16+sssss]-D[16+ssss+cccc] */ - ucb->vrs[14] |= 1 << 16; - } - - if (instruction != 0xB3) { - /* D[sssss]-D[ssss+cccc] */ - ucb->vrs[14] |= 1 << 17; - } - - ucb->vrs[13] = vsp; - } - else if ((instruction & 0xF8) == 0xB8 || (instruction & 0xF8) == 0xD0) { - /* Pop VFP double precision registers D[8]-D[8+nnn] */ - ucb->vrs[14] = 0x80 | (instruction & 0x07); - if ((instruction & 0xF8) == 0xD0) - ucb->vrs[14] = 1 << 17; - } - else - return UNWIND_UNSUPPORTED_DWARF_INSTR; - } - return UNWIND_SUCCESS; -} - -static inline __attribute__((always_inline)) uint32_t read_psp() { - /* Read the current PSP and return its value as a pointer */ - uint32_t psp; - - __asm__ volatile ( - " mrs %0, psp \n" - : "=r" (psp) : : - ); - - return psp; -} - -/* - * Unwind the specified frame and goto the previous one - */ -static UnwResult UnwTabUnwindFrame(const UnwindCallbacks *cb, UnwindFrame *frame) { - - UnwResult err; - UnwTabState ucb; - const UnwTabEntry *index; - uint32_t instructions; - - /* Search the unwind index for the matching unwind table */ - index = UnwTabSearchIndex(__exidx_start, __exidx_end, frame->pc); - - /* Make sure we can unwind this frame */ - if (index->insn == 0x00000001) - return UNWIND_SUCCESS; - - /* Get the pointer to the first unwind instruction */ - if (index->insn & 0x80000000) - instructions = (uint32_t)&index->insn; - else - instructions = prel31_to_addr(&index->insn); - - /* Initialize the unwind control block */ - if ((err = UnwTabStateInit(cb, &ucb, instructions, frame)) < 0) - return err; - - /* Execute the unwind instructions */ - err = UnwTabExecuteInstructions(cb, &ucb); - if (err < 0) - return err; - - /* Set the virtual pc to the virtual lr if this is the first unwind */ - if (ucb.vrs[15] == 0) - ucb.vrs[15] = ucb.vrs[14]; - - /* Check for exception return */ - /* TODO Test with other ARM processors to verify this method. */ - if ((ucb.vrs[15] & 0xF0000000) == 0xF0000000) { - /* According to the Cortex Programming Manual (p.44), the stack address is always 8-byte aligned (Cortex-M7). - Depending on where the exception came from (MSP or PSP), we need the right SP value to work with. - - ucb.vrs[7] contains the right value, so take it and align it by 8 bytes, store it as the current - SP to work with (ucb.vrs[13]) which is then saved as the current (virtual) frame's SP. - */ - uint32_t stack; - ucb.vrs[13] = (ucb.vrs[7] & ~7); - - /* If we need to start from the MSP, we need to go down X words to find the PC, where: - X=2 if it was a non-floating-point exception - X=20 if it was a floating-point (VFP) exception - - If we need to start from the PSP, we need to go up exactly 6 words to find the PC. - See the ARMv7-M Architecture Reference Manual p.594 and Cortex-M7 Processor Programming Manual p.44/p.45 for details. - */ - if ((ucb.vrs[15] & 0xC) == 0) { - /* Return to Handler Mode: MSP (0xFFFFFF-1) */ - stack = ucb.vrs[13]; - - /* The PC is always 2 words down from the MSP, if it was a non-floating-point exception */ - stack -= 2*4; - - /* If there was a VFP exception (0xFFFFFFE1), the PC is located another 18 words down */ - if ((ucb.vrs[15] & 0xF0) == 0xE0) { - stack -= 18*4; - } - } - else { - /* Return to Thread Mode: PSP (0xFFFFFF-d) */ - stack = read_psp(); - - /* The PC is always 6 words up from the PSP */ - stack += 6*4; - } - - /* Store the PC */ - uint32_t v; - if (!cb->readW(stack,&v)) - return UNWIND_DREAD_W_FAIL; - ucb.vrs[15] = v; - stack -= 4; - - /* Store the LR */ - if (!cb->readW(stack,&v)) - return UNWIND_DREAD_W_FAIL; - ucb.vrs[14] = v; - stack -= 4; - } - - /* We are done if current frame pc is equal to the virtual pc, prevent infinite loop */ - if (frame->pc == ucb.vrs[15]) - return UNWIND_SUCCESS; - - /* Update the frame */ - frame->fp = ucb.vrs[7]; - frame->sp = ucb.vrs[13]; - frame->lr = ucb.vrs[14]; - frame->pc = ucb.vrs[15]; - - /* All good - Continue unwinding */ - return UNWIND_MORE_AVAILABLE; -} - -UnwResult UnwindByTableStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) { - - UnwResult err = UNWIND_SUCCESS; - UnwReport entry; - - /* Use DWARF unwind information to unwind frames */ - do { - if (frame->pc == 0) { - /* Reached __exidx_end. */ - break; - } - - if (frame->pc == 0x00000001) { - /* Reached .cantunwind instruction. */ - break; - } - - /* Find the unwind index of the current frame pc */ - const UnwTabEntry *index = UnwTabSearchIndex(__exidx_start, __exidx_end, frame->pc); - - /* Clear last bit (Thumb indicator) */ - frame->pc &= 0xFFFFFFFEU; - - /* Generate the backtrace information */ - entry.address = frame->pc; - entry.function = prel31_to_addr(&index->addr_offset); - entry.name = UnwTabGetFunctionName(cb, entry.function); - if (!cb->report(data,&entry)) - break; - - /* Unwind frame and repeat */ - } while ((err = UnwTabUnwindFrame(cb, frame)) == UNWIND_MORE_AVAILABLE); - - /* All done */ - return err; -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwarmbytab.h b/src/HAL/shared/backtrace/unwarmbytab.h deleted file mode 100644 index 53aeca2..0000000 --- a/src/HAL/shared/backtrace/unwarmbytab.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Interface to the memory tracking sub-system. - **************************************************************************/ - -#pragma once - -#include "unwarm.h" - -typedef struct { - uint32_t vrs[16]; - uint32_t current; /* Address of current byte */ - int remaining; - int byte; -} UnwTabState; - -typedef struct { - uint32_t addr_offset; - uint32_t insn; -} UnwTabEntry; - -UnwResult UnwindByTableStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data); diff --git a/src/HAL/shared/backtrace/unwarmmem.cpp b/src/HAL/shared/backtrace/unwarmmem.cpp deleted file mode 100644 index 2402320..0000000 --- a/src/HAL/shared/backtrace/unwarmmem.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Implementation of the memory tracking sub-system. - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) -#define MODULE_NAME "UNWARMMEM" - -#include -#include "unwarmmem.h" -#include "unwarm.h" - -#define M_IsIdxUsed(a, v) !!((a)[v >> 3] & (1 << (v & 0x7))) -#define M_SetIdxUsed(a, v) ((a)[v >> 3] |= (1 << (v & 0x7))) -#define M_ClrIdxUsed(a, v) ((a)[v >> 3] &= ~(1 << (v & 0x7))) - -/** Search the memory hash to see if an entry is stored in the hash already. - * This will search the hash and either return the index where the item is - * stored, or -1 if the item was not found. - */ -static int16_t memHashIndex(MemData * const memData, const uint32_t addr) { - - const uint16_t v = addr % MEM_HASH_SIZE; - uint16_t s = v; - - do { - /* Check if the element is occupied */ - if (M_IsIdxUsed(memData->used, s)) { - /* Check if it is occupied with the sought data */ - if (memData->a[s] == addr) return s; - } - else { - /* Item is free, this is where the item should be stored */ - return s; - } - - /* Search the next entry */ - s++; - if (s > MEM_HASH_SIZE) s = 0; - } while (s != v); - - /* Search failed, hash is full and the address not stored */ - return -1; -} - -bool UnwMemHashRead(MemData * const memData, uint32_t addr,uint32_t * const data, bool * const tracked) { - - const int16_t i = memHashIndex(memData, addr); - - if (i >= 0 && M_IsIdxUsed(memData->used, i) && memData->a[i] == addr) { - *data = memData->v[i]; - *tracked = M_IsIdxUsed(memData->tracked, i); - return true; - } - else { - /* Address not found in the hash */ - return false; - } -} - -bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid) { - const int16_t i = memHashIndex(memData, addr); - if (i < 0) return false; /* Hash full */ - - /* Store the item */ - memData->a[i] = addr; - M_SetIdxUsed(memData->used, i); - - if (valValid) { - memData->v[i] = val; - M_SetIdxUsed(memData->tracked, i); - } - else { - #ifdef UNW_DEBUG - memData->v[i] = 0xDEADBEEF; - #endif - M_ClrIdxUsed(memData->tracked, i); - } - - return true; -} - -void UnwMemHashGC(UnwState * const state) { - - const uint32_t minValidAddr = state->regData[13].v; - MemData * const memData = &state->memData; - uint16_t t; - - for (t = 0; t < MEM_HASH_SIZE; t++) { - if (M_IsIdxUsed(memData->used, t) && (memData->a[t] < minValidAddr)) { - UnwPrintd3("MemHashGC: Free elem %d, addr 0x%08x\n", t, memData->a[t]); - M_ClrIdxUsed(memData->used, t); - } - } -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwarmmem.h b/src/HAL/shared/backtrace/unwarmmem.h deleted file mode 100644 index eb4579a..0000000 --- a/src/HAL/shared/backtrace/unwarmmem.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Interface to the memory tracking sub-system. - **************************************************************************/ - -#pragma once - -#include "unwarm.h" - -bool UnwMemHashRead(MemData * const memData, uint32_t addr, uint32_t * const data, bool * const tracked); -bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid); -void UnwMemHashGC(UnwState * const state); diff --git a/src/HAL/shared/backtrace/unwinder.cpp b/src/HAL/shared/backtrace/unwinder.cpp deleted file mode 100644 index aedfa24..0000000 --- a/src/HAL/shared/backtrace/unwinder.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Implementation of the interface into the ARM unwinder. - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - -#define MODULE_NAME "UNWINDER" - -#include -#include -#include "unwinder.h" -#include "unwarm.h" -#include "unwarmbytab.h" - -/* These symbols point to the unwind index and should be provide by the linker script */ -extern "C" const UnwTabEntry __exidx_start[]; -extern "C" const UnwTabEntry __exidx_end[]; - -// Detect if unwind information is present or not -static int HasUnwindTableInfo() { - // > 16 because there are default entries we can't suppress - return ((char*)(&__exidx_end) - (char*)(&__exidx_start)) > 16 ? 1 : 0; -} - -UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data) { - if (HasUnwindTableInfo()) { - /* We have unwind information tables */ - return UnwindByTableStart(frame, cb, data); - } - else { - - /* We don't have unwind information tables */ - UnwState state; - - /* Initialize the unwinding state */ - UnwInitState(&state, cb, data, frame->pc, frame->sp); - - /* Check the Thumb bit */ - return (frame->pc & 0x1) ? UnwStartThumb(&state) : UnwStartArm(&state); - } -} -#endif diff --git a/src/HAL/shared/backtrace/unwinder.h b/src/HAL/shared/backtrace/unwinder.h deleted file mode 100644 index 9280e2f..0000000 --- a/src/HAL/shared/backtrace/unwinder.h +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - **************************************************************************/ -/** \file - * Interface to the ARM stack unwinding module. - **************************************************************************/ - -#pragma once - -#include - -/** \def UNW_DEBUG - * If this define is set, additional information will be produced while - * unwinding the stack to allow debug of the unwind module itself. - */ -/* #define UNW_DEBUG 1 */ - -/*************************************************************************** - * Type Definitions - **************************************************************************/ - -/** Possible results for UnwindStart to return. - */ -typedef enum { - /** Unwinding was successful and complete. */ - UNWIND_SUCCESS = 0, - - /** Not an error: More frames are available. */ - UNWIND_MORE_AVAILABLE = 1, - - /** Unsupported DWARF unwind personality. */ - UNWIND_UNSUPPORTED_DWARF_PERSONALITY = -1, - - /** Refused to perform unwind. */ - UNWIND_REFUSED = -2, - - /** Reached an invalid SP. */ - UNWIND_INVALID_SP = -3, - - /** Reached an invalid PC */ - UNWIND_INVALID_PC = -4, - - /** Unsupported DWARF instruction */ - UNWIND_UNSUPPORTED_DWARF_INSTR = -5, - - /** More than UNW_MAX_INSTR_COUNT instructions were interpreted. */ - UNWIND_EXHAUSTED = -6, - - /** Unwinding stopped because the reporting func returned false. */ - UNWIND_TRUNCATED = -7, - - /** Read data was found to be inconsistent. */ - UNWIND_INCONSISTENT = -8, - - /** Unsupported instruction or data found. */ - UNWIND_UNSUPPORTED = -9, - - /** General failure. */ - UNWIND_FAILURE = -10, - - /** Illegal instruction. */ - UNWIND_ILLEGAL_INSTR = -11, - - /** Unwinding hit the reset vector. */ - UNWIND_RESET = -12, - - /** Failed read for an instruction word. */ - UNWIND_IREAD_W_FAIL = -13, - - /** Failed read for an instruction half-word. */ - UNWIND_IREAD_H_FAIL = -14, - - /** Failed read for an instruction byte. */ - UNWIND_IREAD_B_FAIL = -15, - - /** Failed read for a data word. */ - UNWIND_DREAD_W_FAIL = -16, - - /** Failed read for a data half-word. */ - UNWIND_DREAD_H_FAIL = -17, - - /** Failed read for a data byte. */ - UNWIND_DREAD_B_FAIL = -18, - - /** Failed write for a data word. */ - UNWIND_DWRITE_W_FAIL = -19 - -} UnwResult; - -/** A backtrace report */ -typedef struct { - uint32_t function; /** Starts address of function */ - const char *name; /** Function name, or null if not available */ - uint32_t address; /** PC on that function */ -} UnwReport; - -/** Type for function pointer for result callback. - * The function is passed two parameters, the first is a void * pointer, - * and the second is the return address of the function. The bottom bit - * of the passed address indicates the execution mode; if it is set, - * the execution mode at the return address is Thumb, otherwise it is - * ARM. - * - * The return value of this function determines whether unwinding should - * continue or not. If true is returned, unwinding will continue and the - * report function maybe called again in future. If false is returned, - * unwinding will stop with UnwindStart() returning UNWIND_TRUNCATED. - */ -typedef bool (*UnwindReportFunc)(void *data, const UnwReport *bte); - -/** Structure that holds memory callback function pointers. - */ -typedef struct { - - /** Report an unwind result. */ - UnwindReportFunc report; - - /** Read a 32 bit word from memory. - * The memory address to be read is passed as \a address, and - * \a *val is expected to be populated with the read value. - * If the address cannot or should not be read, false can be - * returned to indicate that unwinding should stop. If true - * is returned, \a *val is assumed to be valid and unwinding - * will continue. - */ - bool (*readW)(const uint32_t address, uint32_t *val); - - /** Read a 16 bit half-word from memory. - * This function has the same usage as for readW, but is expected - * to read only a 16 bit value. - */ - bool (*readH)(const uint32_t address, uint16_t *val); - - /** Read a byte from memory. - * This function has the same usage as for readW, but is expected - * to read only an 8 bit value. - */ - bool (*readB)(const uint32_t address, uint8_t *val); - - #ifdef UNW_DEBUG - /** Print a formatted line for debug. */ - void (*printf)(const char *format, ...); - #endif -} UnwindCallbacks; - -/* A frame */ -typedef struct { - uint32_t fp; - uint32_t sp; - uint32_t lr; - uint32_t pc; -} UnwindFrame; - -/** Start unwinding the current stack. - * This will unwind the stack starting at the PC value supplied to in the - * link register (i.e. not a normal register) and the stack pointer value - * supplied. - * - * -If the program was compiled with -funwind-tables it will use them to - * perform the traceback. Otherwise, brute force will be employed - * -If the program was compiled with -mpoke-function-name, then you will - * get function names in the traceback. Otherwise, you will not. - */ -UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data); diff --git a/src/HAL/shared/backtrace/unwmemaccess.cpp b/src/HAL/shared/backtrace/unwmemaccess.cpp deleted file mode 100644 index a4151b3..0000000 --- a/src/HAL/shared/backtrace/unwmemaccess.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Utility functions to access memory - **************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - -#include "unwmemaccess.h" -#include "../../../inc/MarlinConfig.h" - -/* Validate address */ - -#ifdef ARDUINO_ARCH_SAM - - // For DUE, valid address ranges are - // SRAM (0x20070000 - 0x20088000) (96kb) - // FLASH (0x00080000 - 0x00100000) (512kb) - // - #define START_SRAM_ADDR 0x20070000 - #define END_SRAM_ADDR 0x20088000 - #define START_FLASH_ADDR 0x00080000 - #define END_FLASH_ADDR 0x00100000 - -#elif defined(TARGET_LPC1768) - - // For LPC1769: - // SRAM (0x10000000 - 0x10008000) (32kb) - // FLASH (0x00000000 - 0x00080000) (512kb) - // - #define START_SRAM_ADDR 0x10000000 - #define END_SRAM_ADDR 0x10008000 - #define START_FLASH_ADDR 0x00000000 - #define END_FLASH_ADDR 0x00080000 - -#elif defined(__STM32F1__) || defined(STM32F1xx) || defined(STM32F0xx) || defined(STM32G0xx) - - // For STM32F103ZET6/STM32F103VET6/STM32F0xx - // SRAM (0x20000000 - 0x20010000) (64kb) - // FLASH (0x08000000 - 0x08080000) (512kb) - // - #define START_SRAM_ADDR 0x20000000 - #define END_SRAM_ADDR 0x20010000 - #define START_FLASH_ADDR 0x08000000 - #define END_FLASH_ADDR 0x08080000 - -#elif defined(STM32F4) || defined(STM32F4xx) - - // For STM32F407VET - // SRAM (0x20000000 - 0x20030000) (192kb) - // FLASH (0x08000000 - 0x08080000) (512kb) - // - #define START_SRAM_ADDR 0x20000000 - #define END_SRAM_ADDR 0x20030000 - #define START_FLASH_ADDR 0x08000000 - #define END_FLASH_ADDR 0x08080000 - -#elif MB(REMRAM_V1, NUCLEO_F767ZI) - - // For STM32F765VI in RemRam v1 - // SRAM (0x20000000 - 0x20080000) (512kb) - // FLASH (0x08000000 - 0x08200000) (2048kb) - // - #define START_SRAM_ADDR 0x20000000 - #define END_SRAM_ADDR 0x20080000 - #define START_FLASH_ADDR 0x08000000 - #define END_FLASH_ADDR 0x08200000 - -#elif defined(__MK20DX256__) - - // For MK20DX256 in TEENSY 3.1 or TEENSY 3.2 - // SRAM (0x1FFF8000 - 0x20008000) (64kb) - // FLASH (0x00000000 - 0x00040000) (256kb) - // - #define START_SRAM_ADDR 0x1FFF8000 - #define END_SRAM_ADDR 0x20008000 - #define START_FLASH_ADDR 0x00000000 - #define END_FLASH_ADDR 0x00040000 - -#elif defined(__MK64FX512__) - - // For MK64FX512 in TEENSY 3.5 - // SRAM (0x1FFF0000 - 0x20020000) (192kb) - // FLASH (0x00000000 - 0x00080000) (512kb) - // - #define START_SRAM_ADDR 0x1FFF0000 - #define END_SRAM_ADDR 0x20020000 - #define START_FLASH_ADDR 0x00000000 - #define END_FLASH_ADDR 0x00080000 - -#elif defined(__MK66FX1M0__) - - // For MK66FX1M0 in TEENSY 3.6 - // SRAM (0x1FFF0000 - 0x20030000) (256kb) - // FLASH (0x00000000 - 0x00140000) (1.25Mb) - // - #define START_SRAM_ADDR 0x1FFF0000 - #define END_SRAM_ADDR 0x20030000 - #define START_FLASH_ADDR 0x00000000 - #define END_FLASH_ADDR 0x00140000 - -#elif defined(__IMXRT1062__) - - // For IMXRT1062 in TEENSY 4.0/4/1 - // ITCM (rwx): ORIGIN = 0x00000000, LENGTH = 512K - // DTCM (rwx): ORIGIN = 0x20000000, LENGTH = 512K - // RAM (rwx): ORIGIN = 0x20200000, LENGTH = 512K - // FLASH (rwx): ORIGIN = 0x60000000, LENGTH = 1984K - // - #define START_SRAM_ADDR 0x00000000 - #define END_SRAM_ADDR 0x20280000 - #define START_FLASH_ADDR 0x60000000 - #define END_FLASH_ADDR 0x601F0000 - -#elif defined(__SAMD51P20A__) - - // For SAMD51x20, valid address ranges are - // SRAM (0x20000000 - 0x20040000) (256kb) - // FLASH (0x00000000 - 0x00100000) (1024kb) - // - #define START_SRAM_ADDR 0x20000000 - #define END_SRAM_ADDR 0x20040000 - #define START_FLASH_ADDR 0x00000000 - #define END_FLASH_ADDR 0x00100000 - -#else - // Generic ARM code, that's testing if an access to the given address would cause a fault or not - // It can't guarantee an address is in RAM or Flash only, but we usually don't care - - #define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status Reg. - #define NVIC_CFG_CTRL 0xE000ED14 // Configuration Control Register - #define NVIC_FAULT_STAT_BFARV 0x00008000 // BFAR is valid - #define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore bus fault in NMI/fault - #define HW_REG(X) (*((volatile unsigned long *)(X))) - - static bool validate_addr(uint32_t read_address) { - bool works = true; - uint32_t intDisabled = 0; - // Read current interrupt state - __asm__ __volatile__ ("MRS %[result], PRIMASK\n\t" : [result]"=r"(intDisabled) :: ); // 0 is int enabled, 1 for disabled - - // Clear bus fault indicator first (write 1 to clear) - HW_REG(NVIC_FAULT_STAT) |= NVIC_FAULT_STAT_BFARV; - // Ignore bus fault interrupt - HW_REG(NVIC_CFG_CTRL) |= NVIC_CFG_CTRL_BFHFNMIGN; - // Disable interrupts if not disabled previously - if (!intDisabled) __asm__ __volatile__ ("CPSID f"); - // Probe address - *(volatile uint32_t*)read_address; - // Check if a fault happened - if ((HW_REG(NVIC_FAULT_STAT) & NVIC_FAULT_STAT_BFARV) != 0) - works = false; - // Enable interrupts again if previously disabled - if (!intDisabled) __asm__ __volatile__ ("CPSIE f"); - // Enable fault interrupt flag - HW_REG(NVIC_CFG_CTRL) &= ~NVIC_CFG_CTRL_BFHFNMIGN; - - return works; - } - -#endif - -#ifdef START_SRAM_ADDR - static bool validate_addr(uint32_t addr) { - - // Address must be in SRAM range - if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR) - return true; - - // Or in FLASH range - if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR) - return true; - - return false; - } -#endif - -bool UnwReadW(const uint32_t a, uint32_t *v) { - if (!validate_addr(a)) - return false; - - *v = *(uint32_t *)a; - return true; -} - -bool UnwReadH(const uint32_t a, uint16_t *v) { - if (!validate_addr(a)) - return false; - - *v = *(uint16_t *)a; - return true; -} - -bool UnwReadB(const uint32_t a, uint8_t *v) { - if (!validate_addr(a)) - return false; - - *v = *(uint8_t *)a; - return true; -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/backtrace/unwmemaccess.h b/src/HAL/shared/backtrace/unwmemaccess.h deleted file mode 100644 index b911e34..0000000 --- a/src/HAL/shared/backtrace/unwmemaccess.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************** - * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk - * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle - * - * This program is PUBLIC DOMAIN. - * This means that there is no copyright and anyone is able to take a copy - * for free and use it as they wish, with or without modifications, and in - * any context, commercially or otherwise. The only limitation is that I - * don't guarantee that the software is fit for any purpose or accept any - * liability for its use or misuse - this software is without warranty. - *************************************************************************** - * File Description: Utility functions to access memory - **************************************************************************/ - -#pragma once - -#include "unwarm.h" -#include - -bool UnwReadW(const uint32_t a, uint32_t *v); -bool UnwReadH(const uint32_t a, uint16_t *v); -bool UnwReadB(const uint32_t a, uint8_t *v); diff --git a/src/HAL/shared/cpu_exception/exception_arm.cpp b/src/HAL/shared/cpu_exception/exception_arm.cpp deleted file mode 100644 index e54661c..0000000 --- a/src/HAL/shared/cpu_exception/exception_arm.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * Copyright (c) 2020 Cyril Russo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/*************************************************************************** - * ARM CPU Exception handler - ***************************************************************************/ - -#if defined(__arm__) || defined(__thumb__) - - -/* - On ARM CPUs exception handling is quite powerful. - - By default, upon a crash, the CPU enters the handlers that have a higher priority than any other interrupts, - so, in effect, no (real) interrupt can "interrupt" the handler (it's acting like if interrupts were disabled). - - If the handler is not called as re-entrant (that is, if the crash is not happening inside an interrupt or an handler), - then it'll patch the return address to a dumping function (resume_from_fault) and save the crash state. - The CPU will exit the handler and, as such, re-allow the other interrupts, and jump to the dumping function. - In this function, the usual serial port (USB / HW) will be used to dump the crash (no special configuration required). - - The only case where it requires hardware UART is when it's crashing in an interrupt or a crash handler. - In that case, instead of returning to the resume_from_fault function (and thus, re-enabling interrupts), - it jumps to this function directly (so with interrupts disabled), after changing the behavior of the serial output - wrapper to use the HW uart (and in effect, calling MinSerial::init which triggers a warning if you are using - a USB serial port). - - In the case you have a USB serial port, this part will be disabled, and only that part (so that's the reason for - the warning). - This means that you can't have a crash report if the crash happens in an interrupt or an handler if you are using - a USB serial port since it's physically impossible. - You will get a crash report in all other cases. -*/ - -#include "exception_hook.h" -#include "../backtrace/backtrace.h" -#include "../MinSerial.h" - -#define HW_REG(X) (*((volatile unsigned long *)(X))) - -// Default function use the CPU VTOR register to get the vector table. -// Accessing the CPU VTOR register is done in assembly since it's the only way that's common to all current tool -unsigned long get_vtor() { return HW_REG(0xE000ED08); } // Even if it looks like an error, it is not an error -void * hook_get_hardfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x03); } -void * hook_get_memfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x04); } -void * hook_get_busfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x05); } -void * hook_get_usagefault_vector_address(unsigned vtor) { return (void*)(vtor + 0x06); } -void * hook_get_reserved_vector_address(unsigned vtor) { return (void*)(vtor + 0x07); } - -// Common exception frame for ARM, should work for all ARM CPU -// Described here (modified for convenience): https://interrupt.memfault.com/blog/cortex-m-fault-debug -struct __attribute__((packed)) ContextStateFrame { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t xpsr; -}; - -struct __attribute__((packed)) ContextSavedFrame { - uint32_t R0; - uint32_t R1; - uint32_t R2; - uint32_t R3; - uint32_t R12; - uint32_t LR; - uint32_t PC; - uint32_t XPSR; - - uint32_t CFSR; - uint32_t HFSR; - uint32_t DFSR; - uint32_t AFSR; - uint32_t MMAR; - uint32_t BFAR; - - uint32_t ESP; - uint32_t ELR; -}; - -#if NONE(STM32F0xx, STM32G0xx) - extern "C" - __attribute__((naked)) void CommonHandler_ASM() { - __asm__ __volatile__ ( - // Bit 2 of LR tells which stack pointer to use (either main or process, only main should be used anyway) - "tst lr, #4\n" - "ite eq\n" - "mrseq r0, msp\n" - "mrsne r0, psp\n" - // Save the LR in use when being interrupted - "mov r1, lr\n" - // Get the exception number from the ICSR register - "ldr r2, =0xE000ED00\n" - "ldr r2, [r2, #4]\n" - "b CommonHandler_C\n" - ); - } -#else // Cortex M0 does not support conditional mov and testing with a constant, so let's have a specific handler for it - extern "C" - __attribute__((naked)) void CommonHandler_ASM() { - __asm__ __volatile__ ( - ".syntax unified\n" - // Save the LR in use when being interrupted - "mov r1, lr\n" - // Get the exception number from the ICSR register - "ldr r2, =0xE000ED00\n" - "ldr r2, [r2, #4]\n" - "movs r0, #4\n" - "tst r1, r0\n" - "beq _MSP\n" - "mrs r0, psp\n" - "b CommonHandler_C\n" - "_MSP:\n" - "mrs r0, msp\n" - "b CommonHandler_C\n" - ); - } - - #if DISABLED(DYNAMIC_VECTORTABLE) // Cortex M0 requires the handler's address to be within 32kB to the actual function to be able to branch to it - extern "C" { - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_hardfault(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_busfault(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_usagefault(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_memmanage(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_nmi(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception7(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception8(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception9(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception10(); - void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception13(); - } - //TODO When going off from libmaple, you'll need to replace those by the one from STM32/HAL_MinSerial.cpp - #endif -#endif - -// Must be a macro to avoid creating a function frame -#define HALT_IF_DEBUGGING() \ - do { \ - if (HW_REG(0xE000EDF0) & _BV(0)) { \ - __asm("bkpt 1"); \ - } \ -} while (0) - -// Resume from a fault (if possible) so we can still use interrupt based code for serial output -// In that case, we will not jump back to the faulty code, but instead to a dumping code and then a -// basic loop with watchdog calling or manual resetting -static ContextSavedFrame savedFrame; -static uint8_t lastCause; -bool resume_from_fault() { - static const char* causestr[] = { "Thread", "Rsvd", "NMI", "Hard", "Mem", "Bus", "Usage", "7", "8", "9", "10", "SVC", "Dbg", "13", "PendSV", "SysTk", "IRQ" }; - // Reinit the serial link (might only work if implemented in each of your boards) - MinSerial::init(); - - MinSerial::TX("\n\n## Software Fault detected ##\n"); - MinSerial::TX("Cause: "); MinSerial::TX(causestr[min(lastCause, (uint8_t)16)]); MinSerial::TX('\n'); - - MinSerial::TX("R0 : "); MinSerial::TXHex(savedFrame.R0); MinSerial::TX('\n'); - MinSerial::TX("R1 : "); MinSerial::TXHex(savedFrame.R1); MinSerial::TX('\n'); - MinSerial::TX("R2 : "); MinSerial::TXHex(savedFrame.R2); MinSerial::TX('\n'); - MinSerial::TX("R3 : "); MinSerial::TXHex(savedFrame.R3); MinSerial::TX('\n'); - MinSerial::TX("R12 : "); MinSerial::TXHex(savedFrame.R12); MinSerial::TX('\n'); - MinSerial::TX("LR : "); MinSerial::TXHex(savedFrame.LR); MinSerial::TX('\n'); - MinSerial::TX("PC : "); MinSerial::TXHex(savedFrame.PC); MinSerial::TX('\n'); - MinSerial::TX("PSR : "); MinSerial::TXHex(savedFrame.XPSR); MinSerial::TX('\n'); - - // Configurable Fault Status Register - // Consists of MMSR, BFSR and UFSR - MinSerial::TX("CFSR : "); MinSerial::TXHex(savedFrame.CFSR); MinSerial::TX('\n'); - - // Hard Fault Status Register - MinSerial::TX("HFSR : "); MinSerial::TXHex(savedFrame.HFSR); MinSerial::TX('\n'); - - // Debug Fault Status Register - MinSerial::TX("DFSR : "); MinSerial::TXHex(savedFrame.DFSR); MinSerial::TX('\n'); - - // Auxiliary Fault Status Register - MinSerial::TX("AFSR : "); MinSerial::TXHex(savedFrame.AFSR); MinSerial::TX('\n'); - - // Read the Fault Address Registers. These may not contain valid values. - // Check BFARVALID/MMARVALID to see if they are valid values - // MemManage Fault Address Register - MinSerial::TX("MMAR : "); MinSerial::TXHex(savedFrame.MMAR); MinSerial::TX('\n'); - - // Bus Fault Address Register - MinSerial::TX("BFAR : "); MinSerial::TXHex(savedFrame.BFAR); MinSerial::TX('\n'); - - MinSerial::TX("ExcLR: "); MinSerial::TXHex(savedFrame.ELR); MinSerial::TX('\n'); - MinSerial::TX("ExcSP: "); MinSerial::TXHex(savedFrame.ESP); MinSerial::TX('\n'); - - // The stack pointer is pushed by 8 words upon entering an exception, so we need to revert this - backtrace_ex(savedFrame.ESP + 8*4, savedFrame.LR, savedFrame.PC); - - // Call the last resort function here - hook_last_resort_func(); - - const uint32_t start = millis(), end = start + 100; // 100ms should be enough - // We need to wait for the serial buffers to be output but we don't know for how long - // So we'll just need to refresh the watchdog for a while and then stop for the system to reboot - uint32_t last = start; - while (PENDING(last, end)) { - hal.watchdog_refresh(); - while (millis() == last) { /* nada */ } - last = millis(); - MinSerial::TX('.'); - } - - // Reset now by reinstantiating the bootloader's vector table - HW_REG(0xE000ED08) = 0; - // Restart watchdog - #if DISABLED(USE_WATCHDOG) - // No watchdog, let's perform ARMv7 reset instead by writing to AIRCR register with VECTKEY set to SYSRESETREQ - HW_REG(0xE000ED0C) = (HW_REG(0xE000ED0C) & 0x0000FFFF) | 0x05FA0004; - #endif - - while(1) {} // Bad luck, nothing worked -} - -// Make sure the compiler does not optimize the frame argument away -extern "C" -__attribute__((optimize("O0"))) -void CommonHandler_C(ContextStateFrame * frame, unsigned long lr, unsigned long cause) { - - // If you are using it'll stop here - HALT_IF_DEBUGGING(); - - // Save the state to backtrace later on (don't call memcpy here since the stack can be corrupted) - savedFrame.R0 = frame->r0; - savedFrame.R1 = frame->r1; - savedFrame.R2 = frame->r2; - savedFrame.R3 = frame->r3; - savedFrame.R12 = frame->r12; - savedFrame.LR = frame->lr; - savedFrame.PC = frame->pc; - savedFrame.XPSR= frame->xpsr; - lastCause = cause & 0x1FF; - - volatile uint32_t &CFSR = HW_REG(0xE000ED28); - savedFrame.CFSR = CFSR; - savedFrame.HFSR = HW_REG(0xE000ED2C); - savedFrame.DFSR = HW_REG(0xE000ED30); - savedFrame.AFSR = HW_REG(0xE000ED3C); - savedFrame.MMAR = HW_REG(0xE000ED34); - savedFrame.BFAR = HW_REG(0xE000ED38); - savedFrame.ESP = (unsigned long)frame; // Even on return, this should not be overwritten by the CPU - savedFrame.ELR = lr; - - // First check if we can resume from this exception to our own handler safely - // If we can, then we don't need to disable interrupts and the usual serial code - // can be used - - //const uint32_t non_usage_fault_mask = 0x0000FFFF; - //const bool non_usage_fault_occurred = (CFSR & non_usage_fault_mask) != 0; - // the bottom 8 bits of the xpsr hold the exception number of the - // executing exception or 0 if the processor is in Thread mode - const bool faulted_from_exception = ((frame->xpsr & 0xFF) != 0); - if (!faulted_from_exception) { // Not sure about the non_usage_fault, we want to try anyway, don't we ? && !non_usage_fault_occurred) - // Try to resume to our handler here - CFSR |= CFSR; // The ARM programmer manual says you must write to 1 all fault bits to clear them so this instruction is correct - // The frame will not be valid when returning anymore, let's clean it - savedFrame.CFSR = 0; - - frame->pc = (uint32_t)resume_from_fault; // Patch where to return to - frame->lr = 0xDEADBEEF; // If our handler returns (it shouldn't), let's make it trigger an exception immediately - frame->xpsr = _BV(24); // Need to clean the PSR register to thumb II only - MinSerial::force_using_default_output = true; - return; // The CPU will resume in our handler hopefully, and we'll try to use default serial output - } - - // Sorry, we need to emergency code here since the fault is too dangerous to recover from - MinSerial::force_using_default_output = false; - resume_from_fault(); -} - -void hook_cpu_exceptions() { - #if ENABLED(DYNAMIC_VECTORTABLE) - // On ARM 32bits CPU, the vector table is like this: - // 0x0C => Hardfault - // 0x10 => MemFault - // 0x14 => BusFault - // 0x18 => UsageFault - - // Unfortunately, it's usually run from flash, and we can't write to flash here directly to hook our instruction - // We could set an hardware breakpoint, and hook on the fly when it's being called, but this - // is hard to get right and would probably break debugger when attached - - // So instead, we'll allocate a new vector table filled with the previous value except - // for the fault we are interested in. - // Now, comes the issue to figure out what is the current vector table size - // There is nothing telling us what is the vector table as it's per-cpu vendor specific. - // BUT: we are being called at the end of the setup, so we assume the setup is done - // Thus, we can read the current vector table until we find an address that's not in flash, and it would mark the - // end of the vector table (skipping the fist entry obviously) - // The position of the program in flash is expected to be at 0x08xxx xxxx on all known platform for ARM and the - // flash size is available via register 0x1FFFF7E0 on STM32 family, but it's not the case for all ARM boards - // (accessing this register might trigger a fault if it's not implemented). - - // So we'll simply mask the top 8 bits of the first handler as an hint of being in the flash or not -that's poor and will - // probably break if the flash happens to be more than 128MB, but in this case, we are not magician, we need help from outside. - - unsigned long *vecAddr = (unsigned long*)get_vtor(); - SERIAL_ECHOPGM("Vector table addr: "); - SERIAL_PRINTLN(get_vtor(), PrintBase::Hex); - - #ifdef VECTOR_TABLE_SIZE - uint32_t vec_size = VECTOR_TABLE_SIZE; - alignas(128) static unsigned long vectable[VECTOR_TABLE_SIZE] ; - #else - #ifndef IS_IN_FLASH - #define IS_IN_FLASH(X) (((unsigned long)X & 0xFF000000) == 0x08000000) - #endif - - // When searching for the end of the vector table, this acts as a limit not to overcome - #ifndef VECTOR_TABLE_SENTINEL - #define VECTOR_TABLE_SENTINEL 80 - #endif - - // Find the vector table size - uint32_t vec_size = 1; - while (IS_IN_FLASH(vecAddr[vec_size]) && vec_size < VECTOR_TABLE_SENTINEL) - vec_size++; - - // We failed to find a valid vector table size, let's abort hooking up - if (vec_size == VECTOR_TABLE_SENTINEL) return; - // Poor method that's wasting RAM here, but allocating with malloc and alignment would be worst - // 128 bytes alignment is required for writing the VTOR register - alignas(128) static unsigned long vectable[VECTOR_TABLE_SENTINEL]; - - SERIAL_ECHOPGM("Detected vector table size: "); - SERIAL_PRINTLN(vec_size, PrintBase::Hex); - #endif - - uint32_t defaultFaultHandler = vecAddr[(unsigned)7]; - // Copy the current vector table into the new table - for (uint32_t i = 0; i < vec_size; i++) { - vectable[i] = vecAddr[i]; - // Replace all default handler by our own handler - if (vectable[i] == defaultFaultHandler) - vectable[i] = (unsigned long)&CommonHandler_ASM; - } - - // Let's hook now with our functions - vectable[(unsigned long)hook_get_hardfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM; - vectable[(unsigned long)hook_get_memfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM; - vectable[(unsigned long)hook_get_busfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM; - vectable[(unsigned long)hook_get_usagefault_vector_address(0)] = (unsigned long)&CommonHandler_ASM; - - // Finally swap with our own vector table - // This is supposed to be atomic, but let's do that with interrupt disabled - - HW_REG(0xE000ED08) = (unsigned long)vectable | _BV32(29); // 29th bit is for telling the CPU the table is now in SRAM (should be present already) - - SERIAL_ECHOLNPGM("Installed fault handlers"); - #endif -} - -#endif // __arm__ || __thumb__ diff --git a/src/HAL/shared/cpu_exception/exception_hook.cpp b/src/HAL/shared/cpu_exception/exception_hook.cpp deleted file mode 100644 index 93e80f3..0000000 --- a/src/HAL/shared/cpu_exception/exception_hook.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General 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 "exception_hook.h" - -void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned) { return 0; } -void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned) { return 0; } -void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned) { return 0; } -void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned) { return 0; } -void __attribute__((weak)) hook_last_resort_func() {} diff --git a/src/HAL/shared/cpu_exception/exception_hook.h b/src/HAL/shared/cpu_exception/exception_hook.h deleted file mode 100644 index 70d9434..0000000 --- a/src/HAL/shared/cpu_exception/exception_hook.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/* Here is the expected behavior of a system producing a CPU exception with this hook installed: - 1. Before the system is crashed - 1.1 Upon validation (not done yet in this code, but we could be using DEBUG flags here to allow/disallow hooking) - 1.2 Install the hook by overwriting the vector table exception handler with the hooked function - 2. Upon system crash (for example, by a dereference of a NULL pointer or anything else) - 2.1 The CPU triggers its exception and jump into the vector table for the exception type - 2.2 Instead of finding the default handler, it finds the updated pointer to our hook - 2.3 The CPU jumps into our hook function (likely a naked function to keep all information about crash point intact) - 2.4 The hook (naked) function saves the important registers (stack pointer, program counter, current mode) and jumps to a common exception handler (in C) - 2.5 The common exception handler dumps the registers on the serial link and perform a backtrace around the crashing point - 2.6 Once the backtrace is performed the last resort function is called (platform specific). - On some platform with a LCD screen, this might display the crash information as a QR code or as text for the - user to capture by taking a picture - 2.7 The CPU is reset and/or halted by triggering a debug breakpoint if a debugger is attached */ - -// Hook into CPU exception interrupt table to call the backtracing code upon an exception -// Most platform will simply do nothing here, but those who can will install/overwrite the default exception handler -// with a more performant exception handler -void hook_cpu_exceptions(); - -// Some platform might deal without a hard fault handler, in that case, return 0 in your platform here or skip implementing it -void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned base_address); -// Some platform might deal without a memory management fault handler, in that case, return 0 in your platform here or skip implementing it -void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned base_address); -// Some platform might deal without a bus fault handler, in that case, return 0 in your platform here or skip implementing it -void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned base_address); -// Some platform might deal without a usage fault handler, in that case, return 0 in your platform here or skip implementing it -void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned base_address); - -// Last resort function that can be called after the exception handler was called. -void __attribute__((weak)) hook_last_resort_func(); diff --git a/src/HAL/shared/eeprom_api.cpp b/src/HAL/shared/eeprom_api.cpp deleted file mode 100644 index 47cfa5a..0000000 --- a/src/HAL/shared/eeprom_api.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../../inc/MarlinConfigPre.h" - -#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE) - - #include "eeprom_api.h" - PersistentStore persistentStore; - -#endif diff --git a/src/HAL/shared/eeprom_api.h b/src/HAL/shared/eeprom_api.h deleted file mode 100644 index cd744f8..0000000 --- a/src/HAL/shared/eeprom_api.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -#include "../../libs/crc16.h" - -class PersistentStore { -public: - - // Total available persistent storage space (in bytes) - static size_t capacity(); - - // Prepare to read or write - static bool access_start(); - - // Housecleaning after read or write - static bool access_finish(); - - // Write one or more bytes of data and update the CRC - // Return 'true' on write error - static bool write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc); - - // Read one or more bytes of data and update the CRC - // Return 'true' on read error - static bool read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing=true); - - // Write one or more bytes of data - // Return 'true' on write error - static bool write_data(const int pos, const uint8_t *value, const size_t size=sizeof(uint8_t)) { - int data_pos = pos; - uint16_t crc = 0; - return write_data(data_pos, value, size, &crc); - } - - // Write a single byte of data - // Return 'true' on write error - static bool write_data(const int pos, const uint8_t value) { return write_data(pos, &value); } - - // Read one or more bytes of data - // Return 'true' on read error - static bool read_data(const int pos, uint8_t *value, const size_t size=1) { - int data_pos = pos; - uint16_t crc = 0; - return read_data(data_pos, value, size, &crc); - } -}; - -extern PersistentStore persistentStore; diff --git a/src/HAL/shared/eeprom_if.h b/src/HAL/shared/eeprom_if.h deleted file mode 100644 index e496de2..0000000 --- a/src/HAL/shared/eeprom_if.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com - * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// -// EEPROM -// -void eeprom_init(); -void eeprom_write_byte(uint8_t *pos, uint8_t value); -uint8_t eeprom_read_byte(uint8_t *pos); diff --git a/src/HAL/shared/eeprom_if_i2c.cpp b/src/HAL/shared/eeprom_if_i2c.cpp deleted file mode 100644 index 6b559e2..0000000 --- a/src/HAL/shared/eeprom_if_i2c.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Platform-independent Arduino functions for I2C EEPROM. - * Enable USE_SHARED_EEPROM if not supplied by the framework. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(I2C_EEPROM) - -#include "eeprom_if.h" - -#if ENABLED(SOFT_I2C_EEPROM) - #include - SlowSoftWire Wire = SlowSoftWire(I2C_SDA_PIN, I2C_SCL_PIN, true); -#else - #include -#endif - -void eeprom_init() { - Wire.begin( - #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM) - uint8_t(I2C_SDA_PIN), uint8_t(I2C_SCL_PIN) - #endif - ); -} - -#if ENABLED(USE_SHARED_EEPROM) - -#ifndef EEPROM_WRITE_DELAY - #define EEPROM_WRITE_DELAY 5 -#endif -#ifndef EEPROM_DEVICE_ADDRESS - #define EEPROM_DEVICE_ADDRESS 0x50 -#endif - -static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRESS); - -// ------------------------ -// Public functions -// ------------------------ - -#define SMALL_EEPROM (MARLIN_EEPROM_SIZE <= 2048) - -// Combine Address high bits into the device address on <=16Kbit (2K) and >512Kbit (64K) EEPROMs. -// Note: MARLIN_EEPROM_SIZE is specified in bytes, whereas EEPROM model numbers refer to bits. -// e.g., The "16" in BL24C16 indicates a 16Kbit (2KB) size. -static uint8_t _eeprom_calc_device_address(uint8_t * const pos) { - const unsigned eeprom_address = (unsigned)pos; - return (SMALL_EEPROM || MARLIN_EEPROM_SIZE > 65536) - ? uint8_t(eeprom_device_address | ((eeprom_address >> (SMALL_EEPROM ? 8 : 16)) & 0x07)) - : eeprom_device_address; -} - -static void _eeprom_begin(uint8_t * const pos) { - const unsigned eeprom_address = (unsigned)pos; - Wire.beginTransmission(_eeprom_calc_device_address(pos)); - if (!SMALL_EEPROM) - Wire.write(uint8_t((eeprom_address >> 8) & 0xFF)); // Address High, if needed - Wire.write(uint8_t(eeprom_address & 0xFF)); // Address Low -} - -void eeprom_write_byte(uint8_t *pos, uint8_t value) { - _eeprom_begin(pos); - Wire.write(value); - Wire.endTransmission(); - - // wait for write cycle to complete - // this could be done more efficiently with "acknowledge polling" - delay(EEPROM_WRITE_DELAY); -} - -uint8_t eeprom_read_byte(uint8_t *pos) { - _eeprom_begin(pos); - Wire.endTransmission(); - Wire.requestFrom(_eeprom_calc_device_address(pos), (byte)1); - return Wire.available() ? Wire.read() : 0xFF; -} - -#endif // USE_SHARED_EEPROM -#endif // I2C_EEPROM diff --git a/src/HAL/shared/eeprom_if_spi.cpp b/src/HAL/shared/eeprom_if_spi.cpp deleted file mode 100644 index 72c35ad..0000000 --- a/src/HAL/shared/eeprom_if_spi.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Platform-independent Arduino functions for SPI EEPROM. - * Enable USE_SHARED_EEPROM if not supplied by the framework. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SPI_EEPROM) - -#include "eeprom_if.h" - -void eeprom_init() {} - -#if ENABLED(USE_SHARED_EEPROM) - -#define CMD_WREN 6 // WREN -#define CMD_READ 2 // WRITE -#define CMD_WRITE 2 // WRITE - -#ifndef EEPROM_WRITE_DELAY - #define EEPROM_WRITE_DELAY 7 -#endif - -static void _eeprom_begin(uint8_t * const pos, const uint8_t cmd) { - const uint8_t eeprom_temp[3] = { - cmd, - (unsigned(pos) >> 8) & 0xFF, // Address High - unsigned(pos) & 0xFF // Address Low - }; - WRITE(SPI_EEPROM1_CS_PIN, HIGH); // Usually free already - WRITE(SPI_EEPROM1_CS_PIN, LOW); // Activate the Bus - spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3); - // Leave the Bus in-use -} - -uint8_t eeprom_read_byte(uint8_t *pos) { - _eeprom_begin(pos, CMD_READ); // Set read location and begin transmission - - const uint8_t v = spiRec(SPI_CHAN_EEPROM1); // After READ a value sits on the Bus - - WRITE(SPI_EEPROM1_CS_PIN, HIGH); // Done with device - - return v; -} - -void eeprom_write_byte(uint8_t *pos, uint8_t value) { - const uint8_t eeprom_temp = CMD_WREN; - WRITE(SPI_EEPROM1_CS_PIN, LOW); - spiSend(SPI_CHAN_EEPROM1, &eeprom_temp, 1); // Write Enable - - WRITE(SPI_EEPROM1_CS_PIN, HIGH); // Done with the Bus - delay(1); // For a small amount of time - - _eeprom_begin(pos, CMD_WRITE); // Set write address and begin transmission - - spiSend(SPI_CHAN_EEPROM1, value); // Send the value to be written - WRITE(SPI_EEPROM1_CS_PIN, HIGH); // Done with the Bus - delay(EEPROM_WRITE_DELAY); // Give page write time to complete -} - -#endif // USE_SHARED_EEPROM -#endif // I2C_EEPROM diff --git a/src/HAL/shared/esp_wifi.cpp b/src/HAL/shared/esp_wifi.cpp deleted file mode 100644 index a55f5ca..0000000 --- a/src/HAL/shared/esp_wifi.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" -#include "Delay.h" - -void esp_wifi_init(void) { // init ESP01 WIFI module pins - #if PIN_EXISTS(ESP_WIFI_MODULE_GPIO0) - OUT_WRITE(ESP_WIFI_MODULE_GPIO0_PIN, HIGH); - #endif - #if PIN_EXISTS(ESP_WIFI_MODULE_GPIO2) - OUT_WRITE(ESP_WIFI_MODULE_GPIO2_PIN, HIGH); - #endif - #if PIN_EXISTS(ESP_WIFI_MODULE_RESET) - delay(1); // power up delay (0.1mS minimum) - OUT_WRITE(ESP_WIFI_MODULE_RESET_PIN, LOW); - delay(1); - OUT_WRITE(ESP_WIFI_MODULE_RESET_PIN, HIGH); - #endif - #if PIN_EXISTS(ESP_WIFI_MODULE_ENABLE) - delay(1); // delay after reset released (0.1mS minimum) - OUT_WRITE(ESP_WIFI_MODULE_ENABLE_PIN, HIGH); - #endif -} diff --git a/src/HAL/shared/esp_wifi.h b/src/HAL/shared/esp_wifi.h deleted file mode 100644 index 84a50a9..0000000 --- a/src/HAL/shared/esp_wifi.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void esp_wifi_init(); diff --git a/src/HAL/shared/math_32bit.h b/src/HAL/shared/math_32bit.h deleted file mode 100644 index 1fb233e..0000000 --- a/src/HAL/shared/math_32bit.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../core/macros.h" - -/** - * Math helper functions for 32 bit CPUs - */ -FORCE_INLINE static uint32_t MultiU32X24toH32(uint32_t longIn1, uint32_t longIn2) { - return ((uint64_t)longIn1 * longIn2 + 0x00800000) >> 24; -} diff --git a/src/HAL/shared/progmem.h b/src/HAL/shared/progmem.h deleted file mode 100644 index 4cd7663..0000000 --- a/src/HAL/shared/progmem.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifndef __AVR__ -#ifndef __PGMSPACE_H_ -// This define should prevent reading the system pgmspace.h if included elsewhere -// This is not normally needed. -#define __PGMSPACE_H_ 1 -#endif - -#ifndef PROGMEM -#define PROGMEM -#endif -#ifndef PGM_P -#define PGM_P const char * -#endif -#ifndef PSTR -#define PSTR(str) (str) -#endif -#ifndef F -class __FlashStringHelper; -#define F(str) (reinterpret_cast(PSTR(str))) -#endif -#ifndef _SFR_BYTE -#define _SFR_BYTE(n) (n) -#endif -#ifndef memchr_P -#define memchr_P(str, c, len) memchr((str), (c), (len)) -#endif -#ifndef memcmp_P -#define memcmp_P(a, b, n) memcmp((a), (b), (n)) -#endif -#ifndef memcpy_P -#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) -#endif -#ifndef memmem_P -#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen)) -#endif -#ifndef memrchr_P -#define memrchr_P(str, val, len) memrchr((str), (val), (len)) -#endif -#ifndef strcat_P -#define strcat_P(dest, src) strcat((dest), (src)) -#endif -#ifndef strchr_P -#define strchr_P(str, c) strchr((str), (c)) -#endif -#ifndef strchrnul_P -#define strchrnul_P(str, c) strchrnul((str), (c)) -#endif -#ifndef strcmp_P -#define strcmp_P(a, b) strcmp((a), (b)) -#endif -#ifndef strcpy_P -#define strcpy_P(dest, src) strcpy((dest), (src)) -#endif -#ifndef strcasecmp_P -#define strcasecmp_P(a, b) strcasecmp((a), (b)) -#endif -#ifndef strcasestr_P -#define strcasestr_P(a, b) strcasestr((a), (b)) -#endif -#ifndef strlcat_P -#define strlcat_P(dest, src, len) strlcat((dest), (src), (len)) -#endif -#ifndef strlcpy_P -#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len)) -#endif -#ifndef strlen_P -#define strlen_P(s) strlen((const char *)(s)) -#endif -#ifndef strnlen_P -#define strnlen_P(str, len) strnlen((str), (len)) -#endif -#ifndef strncmp_P -#define strncmp_P(a, b, n) strncmp((a), (b), (n)) -#endif -#ifndef strncasecmp_P -#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n)) -#endif -#ifndef strncat_P -#define strncat_P(a, b, n) strncat((a), (b), (n)) -#endif -#ifndef strncpy_P -#define strncpy_P(a, b, n) strncpy((a), (b), (n)) -#endif -#ifndef strpbrk_P -#define strpbrk_P(str, chrs) strpbrk((str), (chrs)) -#endif -#ifndef strrchr_P -#define strrchr_P(str, c) strrchr((str), (c)) -#endif -#ifndef strsep_P -#define strsep_P(pstr, delim) strsep((pstr), (delim)) -#endif -#ifndef strspn_P -#define strspn_P(str, chrs) strspn((str), (chrs)) -#endif -#ifndef strstr_P -#define strstr_P(a, b) strstr((a), (b)) -#endif -#ifndef sprintf_P -#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__) -#endif -#ifndef vfprintf_P -#define vfprintf_P(s, ...) vfprintf((s), __VA_ARGS__) -#endif -#ifndef printf_P -#define printf_P(...) printf(__VA_ARGS__) -#endif -#ifndef snprintf_P -#define snprintf_P(s, n, ...) snprintf((s), (n), __VA_ARGS__) -#endif -#ifndef vsprintf_P -#define vsprintf_P(s, ...) vsprintf((s),__VA_ARGS__) -#endif -#ifndef vsnprintf_P -#define vsnprintf_P(s, n, ...) vsnprintf((s), (n),__VA_ARGS__) -#endif -#ifndef fprintf_P -#define fprintf_P(s, ...) fprintf((s), __VA_ARGS__) -#endif - -#ifndef pgm_read_byte -#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#endif -#ifndef pgm_read_word -#define pgm_read_word(addr) (*(const unsigned short *)(addr)) -#endif -#ifndef pgm_read_dword -#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#endif -#ifndef pgm_read_float -#define pgm_read_float(addr) (*(const float *)(addr)) -#endif - -#ifndef pgm_read_byte_near -#define pgm_read_byte_near(addr) pgm_read_byte(addr) -#endif -#ifndef pgm_read_word_near -#define pgm_read_word_near(addr) pgm_read_word(addr) -#endif -#ifndef pgm_read_dword_near -#define pgm_read_dword_near(addr) pgm_read_dword(addr) -#endif -#ifndef pgm_read_float_near -#define pgm_read_float_near(addr) pgm_read_float(addr) -#endif -#ifndef pgm_read_byte_far -#define pgm_read_byte_far(addr) pgm_read_byte(addr) -#endif -#ifndef pgm_read_word_far -#define pgm_read_word_far(addr) pgm_read_word(addr) -#endif -#ifndef pgm_read_dword_far -#define pgm_read_dword_far(addr) pgm_read_dword(addr) -#endif -#ifndef pgm_read_float_far -#define pgm_read_float_far(addr) pgm_read_float(addr) -#endif - -#ifndef pgm_read_pointer -#define pgm_read_pointer -#endif - -// Fix bug in pgm_read_ptr -#undef pgm_read_ptr -#define pgm_read_ptr(addr) (*((void**)(addr))) - -#endif // __AVR__ diff --git a/src/HAL/shared/servo.cpp b/src/HAL/shared/servo.cpp deleted file mode 100644 index b838800..0000000 --- a/src/HAL/shared/servo.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * 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), safe_delay(servo_delay[servoIndex]). - * With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after servo_delay[servoIndex]. - * 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 "../../inc/MarlinConfig.h" - -#if SHARED_SERVOS - -#include "servo.h" -#include "servo_private.h" - -ServoInfo_t servo_info[MAX_SERVOS]; // static array of servo info structures -uint8_t ServoCount = 0; // the total number of attached servos - -#define SERVO_MIN(v) (MIN_PULSE_WIDTH - (v) * 4) // minimum value in uS for this servo -#define SERVO_MAX(v) (MAX_PULSE_WIDTH - (v) * 4) // maximum value in uS for this servo - -/************ static functions common to all instances ***********************/ - -static bool anyTimerChannelActive(const timer16_Sequence_t timer) { - // returns true if any servo is active on this timer - LOOP_L_N(channel, SERVOS_PER_TIMER) { - if (SERVO(timer, channel).Pin.isActive) - return true; - } - return false; -} - -/****************** end of static functions ******************************/ - -Servo::Servo() { - if (ServoCount < MAX_SERVOS) { - servoIndex = ServoCount++; // assign a servo index to this instance - servo_info[servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 - } - else - servoIndex = INVALID_SERVO; // too many servos -} - -int8_t Servo::attach(const int inPin) { - return attach(inPin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); -} - -int8_t Servo::attach(const int inPin, const int inMin, const int inMax) { - - if (servoIndex >= MAX_SERVOS) return -1; - - if (inPin > 0) servo_info[servoIndex].Pin.nbr = inPin; - pinMode(servo_info[servoIndex].Pin.nbr, OUTPUT); // set servo pin to output - - // TODO: min/max check: ABS(min - MIN_PULSE_WIDTH) / 4 < 128 - min = (MIN_PULSE_WIDTH - inMin) / 4; //resolution of min/max is 4 uS - max = (MAX_PULSE_WIDTH - inMax) / 4; - - // initialize the timer if it has not already been initialized - const timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); - if (!anyTimerChannelActive(timer)) initISR(timer); - servo_info[servoIndex].Pin.isActive = true; // this must be set after the check for anyTimerChannelActive - - return servoIndex; -} - -void Servo::detach() { - servo_info[servoIndex].Pin.isActive = false; - const timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); - if (!anyTimerChannelActive(timer)) finISR(timer); - //pinMode(servo_info[servoIndex].Pin.nbr, INPUT); // set servo pin to input -} - -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(min), SERVO_MAX(max)); - writeMicroseconds(value); -} - -void Servo::writeMicroseconds(int value) { - // calculate and store the values for the given channel - byte channel = servoIndex; - if (channel < MAX_SERVOS) { // ensure channel is valid - // ensure pulse width is valid - value = constrain(value, SERVO_MIN(min), SERVO_MAX(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(readMicroseconds() + 1, SERVO_MIN(min), SERVO_MAX(max), 0, 180); } - -int Servo::readMicroseconds() { - return (servoIndex == INVALID_SERVO) ? 0 : ticksToUs(servo_info[servoIndex].ticks) + (TRIM_DURATION); -} - -bool Servo::attached() { return servo_info[servoIndex].Pin.isActive; } - -void Servo::move(const int value) { - constexpr uint16_t servo_delay[] = SERVO_DELAY; - static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); - if (attach(0) >= 0) { - write(value); - safe_delay(servo_delay[servoIndex]); - TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); - } -} - -#endif // SHARED_SERVOS diff --git a/src/HAL/shared/servo.h b/src/HAL/shared/servo.h deleted file mode 100644 index c2560a8..0000000 --- a/src/HAL/shared/servo.h +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * 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. - */ - -#if IS_TEENSY32 - #include "../TEENSY31_32/Servo.h" -#elif IS_TEENSY35 || IS_TEENSY36 - #include "../TEENSY35_36/Servo.h" -#elif IS_TEENSY40 || IS_TEENSY41 - #include "../TEENSY40_41/Servo.h" -#elif defined(TARGET_LPC1768) - #include "../LPC1768/Servo.h" -#elif defined(__STM32F1__) || defined(TARGET_STM32F1) - #include "../STM32F1/Servo.h" -#elif defined(ARDUINO_ARCH_STM32) - #include "../STM32/Servo.h" -#elif defined(ARDUINO_ARCH_ESP32) - #include "../ESP32/Servo.h" -#else - #include - - #if defined(__AVR__) || defined(ARDUINO_ARCH_SAM) || defined(__SAMD51__) - // we're good to go - #else - #error "This library only supports boards with an AVR, SAM3X or SAMD51 processor." - #endif - - #define Servo_VERSION 2 // software version of this library - - class Servo { - public: - Servo(); - int8_t attach(const int pin); // attach the given pin to the next free channel, set pinMode, return channel number (-1 on fail) - int8_t attach(const int pin, const int min, const 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(const 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/src/HAL/shared/servo_private.h b/src/HAL/shared/servo_private.h deleted file mode 100644 index 10cc5a1..0000000 --- a/src/HAL/shared/servo_private.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * servo_private.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 - */ - -#include - -// Architecture specific include -#ifdef __AVR__ - #include "../AVR/ServoTimers.h" -#elif defined(ARDUINO_ARCH_SAM) - #include "../DUE/ServoTimers.h" -#elif defined(__SAMD51__) - #include "../SAMD51/ServoTimers.h" -#else - #error "This library only supports boards with an AVR, SAM3X or SAMD51 processor." -#endif - -// Macros - -#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 - -// Convert microseconds to ticks and back (PRESCALER depends on architecture) -#define usToTicks(_us) (clockCyclesPerMicrosecond() * (_us) / (SERVO_TIMER_PRESCALER)) -#define ticksToUs(_ticks) (unsigned(_ticks) * (SERVO_TIMER_PRESCALER) / clockCyclesPerMicrosecond()) - -// convenience macros -#define SERVO_INDEX_TO_TIMER(_servo_nbr) timer16_Sequence_t(_servo_nbr / (SERVOS_PER_TIMER)) // the timer controlling this servo -#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // the index of the servo on this timer -#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // servo index by timer and channel -#define SERVO(_timer,_channel) servo_info[SERVO_INDEX(_timer,_channel)] // servo class by timer and channel - -// Types - -typedef struct { - uint8_t nbr : 7 ; // a pin number from 0 to 127 - 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; - -// Global variables - -extern uint8_t ServoCount; -extern ServoInfo_t servo_info[MAX_SERVOS]; - -// Public functions - -void initISR(const timer16_Sequence_t timer_index); -void finISR(const timer16_Sequence_t timer_index); diff --git a/src/MarlinCore.cpp b/src/MarlinCore.cpp deleted file mode 100644 index e059c2e..0000000 --- a/src/MarlinCore.cpp +++ /dev/null @@ -1,1668 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * About Marlin - * - * This firmware is a mashup between Sprinter and grbl. - * - https://github.com/kliment/Sprinter - * - https://github.com/grbl/grbl - */ - -#include "MarlinCore.h" - -#include "HAL/shared/Delay.h" -#include "HAL/shared/esp_wifi.h" -#include "HAL/shared/cpu_exception/exception_hook.h" - -#ifdef ARDUINO - #include -#endif -#include - -#include "core/utility.h" - -#include "module/motion.h" -#include "module/planner.h" -#include "module/endstops.h" -#include "module/temperature.h" -#include "module/settings.h" -#include "module/printcounter.h" // PrintCounter or Stopwatch - -#include "module/stepper.h" -#include "module/stepper/indirection.h" - -#include "gcode/gcode.h" -#include "gcode/parser.h" -#include "gcode/queue.h" - -#include "feature/pause.h" -#include "sd/cardreader.h" - -#include "lcd/marlinui.h" -#if HAS_TOUCH_BUTTONS - #include "lcd/touch/touch_buttons.h" -#endif - -#if HAS_TFT_LVGL_UI - #include "lcd/extui/mks_ui/tft_lvgl_configuration.h" - #include "lcd/extui/mks_ui/draw_ui.h" - #include "lcd/extui/mks_ui/mks_hardware.h" - #include -#endif - -#if HAS_DWIN_E3V2 - #include "lcd/e3v2/common/encoder.h" - #if ENABLED(DWIN_CREALITY_LCD) - #include "lcd/e3v2/creality/dwin.h" - #elif ENABLED(DWIN_LCD_PROUI) - #include "lcd/e3v2/proui/dwin.h" - #elif ENABLED(DWIN_CREALITY_LCD_JYERSUI) - #include "lcd/e3v2/jyersui/dwin.h" - #endif -#endif - -#if HAS_ETHERNET - #include "feature/ethernet.h" -#endif - -#if ENABLED(IIC_BL24CXX_EEPROM) - #include "libs/BL24CXX.h" -#endif - -#if ENABLED(DIRECT_STEPPING) - #include "feature/direct_stepping.h" -#endif - -#if ENABLED(HOST_ACTION_COMMANDS) - #include "feature/host_actions.h" -#endif - -#if HAS_BEEPER - #include "libs/buzzer.h" -#endif - -#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - #include "feature/closedloop.h" -#endif - -#if HAS_MOTOR_CURRENT_I2C - #include "feature/digipot/digipot.h" -#endif - -#if ENABLED(MIXING_EXTRUDER) - #include "feature/mixing.h" -#endif - -#if ENABLED(MAX7219_DEBUG) - #include "feature/max7219.h" -#endif - -#if HAS_COLOR_LEDS - #include "feature/leds/leds.h" -#endif - -#if ENABLED(BLTOUCH) - #include "feature/bltouch.h" -#endif - -#if ENABLED(POLL_JOG) - #include "feature/joystick.h" -#endif - -#if HAS_SERVOS - #include "module/servo.h" -#endif - -#if HAS_MOTOR_CURRENT_DAC - #include "feature/dac/stepper_dac.h" -#endif - -#if ENABLED(EXPERIMENTAL_I2CBUS) - #include "feature/twibus.h" -#endif - -#if ENABLED(I2C_POSITION_ENCODERS) - #include "feature/encoder_i2c.h" -#endif - -#if (HAS_TRINAMIC_CONFIG || HAS_TMC_SPI) && DISABLED(PSU_DEFAULT_OFF) - #include "feature/tmc_util.h" -#endif - -#if HAS_CUTTER - #include "feature/spindle_laser.h" -#endif - -#if ENABLED(SDSUPPORT) - CardReader card; -#endif - -#if ENABLED(G38_PROBE_TARGET) - uint8_t G38_move; // = 0 - bool G38_did_trigger; // = false -#endif - -#if ENABLED(DELTA) - #include "module/delta.h" -#elif ENABLED(POLARGRAPH) - #include "module/polargraph.h" -#elif IS_SCARA - #include "module/scara.h" -#endif - -#if HAS_LEVELING - #include "feature/bedlevel/bedlevel.h" -#endif - -#if ENABLED(GCODE_REPEAT_MARKERS) - #include "feature/repeat.h" -#endif - -#if ENABLED(POWER_LOSS_RECOVERY) - #include "feature/powerloss.h" -#endif - -#if ENABLED(CANCEL_OBJECTS) - #include "feature/cancel_object.h" -#endif - -#if HAS_FILAMENT_SENSOR - #include "feature/runout.h" -#endif - -#if EITHER(PROBE_TARE, HAS_Z_SERVO_PROBE) - #include "module/probe.h" -#endif - -#if ENABLED(HOTEND_IDLE_TIMEOUT) - #include "feature/hotend_idle.h" -#endif - -#if ENABLED(TEMP_STAT_LEDS) - #include "feature/leds/tempstat.h" -#endif - -#if ENABLED(CASE_LIGHT_ENABLE) - #include "feature/caselight.h" -#endif - -#if HAS_FANMUX - #include "feature/fanmux.h" -#endif - -#include "module/tool_change.h" - -#if HAS_FANCHECK - #include "feature/fancheck.h" -#endif - -#if ENABLED(USE_CONTROLLER_FAN) - #include "feature/controllerfan.h" -#endif - -#if HAS_PRUSA_MMU1 - #include "feature/mmu/mmu.h" -#endif - -#if HAS_PRUSA_MMU2 - #include "feature/mmu/mmu2.h" -#endif - -#if HAS_L64XX - #include "libs/L64XX/L64XX_Marlin.h" -#endif - -#if ENABLED(PASSWORD_FEATURE) - #include "feature/password/password.h" -#endif - -#if ENABLED(DGUS_LCD_UI_MKS) - #include "lcd/extui/dgus/DGUSScreenHandler.h" -#endif - -#if HAS_DRIVER_SAFE_POWER_PROTECT - #include "feature/stepper_driver_safety.h" -#endif - -#if ENABLED(PSU_CONTROL) - #include "feature/power.h" -#endif - -#if ENABLED(EASYTHREED_UI) - #include "feature/easythreed_ui.h" -#endif - -PGMSTR(M112_KILL_STR, "M112 Shutdown"); - -MarlinState marlin_state = MF_INITIALIZING; - -// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop -bool wait_for_heatup = true; - -// For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop -#if HAS_RESUME_CONTINUE - bool wait_for_user; // = false; - - void wait_for_user_response(millis_t ms/*=0*/, const bool no_sleep/*=false*/) { - UNUSED(no_sleep); - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; - if (ms) ms += millis(); // expire time - while (wait_for_user && !(ms && ELAPSED(millis(), ms))) - idle(TERN_(ADVANCED_PAUSE_FEATURE, no_sleep)); - wait_for_user = false; - while (ui.button_pressed()) safe_delay(50); - } - -#endif - -/** - * *************************************************************************** - * ******************************** FUNCTIONS ******************************** - * *************************************************************************** - */ - -/** - * Stepper Reset (RigidBoard, et.al.) - */ -#if HAS_STEPPER_RESET - void disableStepperDrivers() { OUT_WRITE(STEPPER_RESET_PIN, LOW); } // Drive down to keep motor driver chips in reset - void enableStepperDrivers() { SET_INPUT(STEPPER_RESET_PIN); } // Set to input, allowing pullups to pull the pin high -#endif - -/** - * Sensitive pin test for M42, M226 - */ - -#include "pins/sensitive_pins.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnarrowing" - -#ifndef RUNTIME_ONLY_ANALOG_TO_DIGITAL - template - constexpr pin_t OnlyPins<_SP_END, D...>::table[sizeof...(D)]; -#endif - -bool pin_is_protected(const pin_t pin) { - #ifdef RUNTIME_ONLY_ANALOG_TO_DIGITAL - static const pin_t sensitive_pins[] PROGMEM = { SENSITIVE_PINS }; - const size_t pincount = COUNT(sensitive_pins); - #else - static constexpr size_t pincount = OnlyPins::size; - static const pin_t (&sensitive_pins)[pincount] PROGMEM = OnlyPins::table; - #endif - LOOP_L_N(i, pincount) { - const pin_t * const pptr = &sensitive_pins[i]; - if (pin == (sizeof(pin_t) == 2 ? (pin_t)pgm_read_word(pptr) : (pin_t)pgm_read_byte(pptr))) return true; - } - return false; -} - -#pragma GCC diagnostic pop - -bool printer_busy() { - return planner.movesplanned() || printingIsActive(); -} - -/** - * A Print Job exists when the timer is running or SD is printing - */ -bool printJobOngoing() { return print_job_timer.isRunning() || IS_SD_PRINTING(); } - -/** - * Printing is active when a job is underway but not paused - */ -bool printingIsActive() { return !did_pause_print && printJobOngoing(); } - -/** - * Printing is paused according to SD or host indicators - */ -bool printingIsPaused() { - return did_pause_print || print_job_timer.isPaused() || IS_SD_PAUSED(); -} - -void startOrResumeJob() { - if (!printingIsPaused()) { - TERN_(GCODE_REPEAT_MARKERS, repeat.reset()); - TERN_(CANCEL_OBJECTS, cancelable.reset()); - TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0); - #if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME) - ui.reset_remaining_time(); - #endif - } - print_job_timer.start(); -} - -#if ENABLED(SDSUPPORT) - - inline void abortSDPrinting() { - IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel()); - card.abortFilePrintNow(TERN_(SD_RESORT, true)); - - queue.clear(); - quickstop_stepper(); - - print_job_timer.abort(); - - IF_DISABLED(SD_ABORT_NO_COOLDOWN, thermalManager.disable_all_heaters()); - - TERN(HAS_CUTTER, cutter.kill(), thermalManager.zero_fan_speeds()); // Full cutter shutdown including ISR control - - wait_for_heatup = false; - - TERN_(POWER_LOSS_RECOVERY, recovery.purge()); - - #ifdef EVENT_GCODE_SD_ABORT - queue.inject(F(EVENT_GCODE_SD_ABORT)); - #endif - - TERN_(PASSWORD_AFTER_SD_PRINT_ABORT, password.lock_machine()); - } - - inline void finishSDPrinting() { - if (queue.enqueue_one(F("M1001"))) { // Keep trying until it gets queued - marlin_state = MF_RUNNING; // Signal to stop trying - TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine()); - TERN_(DGUS_LCD_UI_MKS, ScreenHandler.SDPrintingFinished()); - } - } - -#endif // SDSUPPORT - -/** - * Minimal management of Marlin's core activities: - * - Keep the command buffer full - * - Check for maximum inactive time between commands - * - Check for maximum inactive time between stepper commands - * - Check if CHDK_PIN needs to go LOW - * - Check for KILL button held down - * - Check for HOME button held down - * - Check for CUSTOM USER 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) - * - Pulse FET_SAFETY_PIN if it exists - */ -inline void manage_inactivity(const bool no_stepper_sleep=false) { - - queue.get_available_commands(); - - const millis_t ms = millis(); - - // Prevent steppers timing-out - const bool do_reset_timeout = no_stepper_sleep - || TERN0(PAUSE_PARK_NO_STEPPER_TIMEOUT, did_pause_print); - - // Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout - if (do_reset_timeout) gcode.reset_stepper_timeout(ms); - - if (gcode.stepper_max_timed_out(ms)) { - SERIAL_ERROR_START(); - SERIAL_ECHOPGM(STR_KILL_PRE); - SERIAL_ECHOLNPGM(STR_KILL_INACTIVE_TIME, parser.command_ptr); - kill(); - } - - const bool has_blocks = planner.has_blocks_queued(); // Any moves in the planner? - if (has_blocks) gcode.reset_stepper_timeout(ms); // Reset timeout for M18/M84, M85 max 'kill', and laser. - - // M18 / M84 : Handle steppers inactive time timeout - #if HAS_DISABLE_INACTIVE_AXIS - if (gcode.stepper_inactive_time) { - - static bool already_shutdown_steppers; // = false - - if (!has_blocks && !do_reset_timeout && gcode.stepper_inactive_timeout()) { - if (!already_shutdown_steppers) { - already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this - - // Individual axes will be disabled if configured - TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS)); - TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS)); - TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS)); - TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS)); - TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS)); - TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS)); - TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers()); - - TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled()); - } - } - else - already_shutdown_steppers = false; - } - #endif - - #if ENABLED(PHOTO_GCODE) && PIN_EXISTS(CHDK) - // Check if CHDK should be set to LOW (after M240 set it HIGH) - extern millis_t chdk_timeout; - if (chdk_timeout && ELAPSED(ms, chdk_timeout)) { - chdk_timeout = 0; - WRITE(CHDK_PIN, 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 (kill_state()) - 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_ECHOPGM(STR_KILL_PRE); - SERIAL_ECHOLNPGM(STR_KILL_BUTTON); - kill(); - } - #endif - - #if HAS_FREEZE_PIN - stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE; - #endif - - #if HAS_HOME - // Handle a standalone HOME button - constexpr millis_t HOME_DEBOUNCE_DELAY = 1000UL; - static millis_t next_home_key_ms; // = 0 - if (!IS_SD_PRINTING() && !READ(HOME_PIN)) { // HOME_PIN goes LOW when pressed - if (ELAPSED(ms, next_home_key_ms)) { - next_home_key_ms = ms + HOME_DEBOUNCE_DELAY; - LCD_MESSAGE(MSG_AUTO_HOME); - queue.inject_P(G28_STR); - } - } - #endif - - #if ENABLED(CUSTOM_USER_BUTTONS) - // Handle a custom user button if defined - const bool printer_not_busy = !printingIsActive(); - #define HAS_CUSTOM_USER_BUTTON(N) (PIN_EXISTS(BUTTON##N) && defined(BUTTON##N##_HIT_STATE) && defined(BUTTON##N##_GCODE)) - #define HAS_BETTER_USER_BUTTON(N) HAS_CUSTOM_USER_BUTTON(N) && defined(BUTTON##N##_DESC) - #define _CHECK_CUSTOM_USER_BUTTON(N, CODE) do{ \ - constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \ - static millis_t next_cub_ms_##N; \ - if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \ - && (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \ - if (ELAPSED(ms, next_cub_ms_##N)) { \ - next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \ - CODE; \ - queue.inject(F(BUTTON##N##_GCODE)); \ - TERN_(HAS_MARLINUI_MENU, ui.quick_feedback()); \ - } \ - } \ - }while(0) - - #define CHECK_CUSTOM_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, NOOP) - #define CHECK_BETTER_USER_BUTTON(N) _CHECK_CUSTOM_USER_BUTTON(N, if (strlen(BUTTON##N##_DESC)) LCD_MESSAGE_F(BUTTON##N##_DESC)) - - #if HAS_BETTER_USER_BUTTON(1) - CHECK_BETTER_USER_BUTTON(1); - #elif HAS_CUSTOM_USER_BUTTON(1) - CHECK_CUSTOM_USER_BUTTON(1); - #endif - #if HAS_BETTER_USER_BUTTON(2) - CHECK_BETTER_USER_BUTTON(2); - #elif HAS_CUSTOM_USER_BUTTON(2) - CHECK_CUSTOM_USER_BUTTON(2); - #endif - #if HAS_BETTER_USER_BUTTON(3) - CHECK_BETTER_USER_BUTTON(3); - #elif HAS_CUSTOM_USER_BUTTON(3) - CHECK_CUSTOM_USER_BUTTON(3); - #endif - #if HAS_BETTER_USER_BUTTON(4) - CHECK_BETTER_USER_BUTTON(4); - #elif HAS_CUSTOM_USER_BUTTON(4) - CHECK_CUSTOM_USER_BUTTON(4); - #endif - #if HAS_BETTER_USER_BUTTON(5) - CHECK_BETTER_USER_BUTTON(5); - #elif HAS_CUSTOM_USER_BUTTON(5) - CHECK_CUSTOM_USER_BUTTON(5); - #endif - #if HAS_BETTER_USER_BUTTON(6) - CHECK_BETTER_USER_BUTTON(6); - #elif HAS_CUSTOM_USER_BUTTON(6) - CHECK_CUSTOM_USER_BUTTON(6); - #endif - #if HAS_BETTER_USER_BUTTON(7) - CHECK_BETTER_USER_BUTTON(7); - #elif HAS_CUSTOM_USER_BUTTON(7) - CHECK_CUSTOM_USER_BUTTON(7); - #endif - #if HAS_BETTER_USER_BUTTON(8) - CHECK_BETTER_USER_BUTTON(8); - #elif HAS_CUSTOM_USER_BUTTON(8) - CHECK_CUSTOM_USER_BUTTON(8); - #endif - #if HAS_BETTER_USER_BUTTON(9) - CHECK_BETTER_USER_BUTTON(9); - #elif HAS_CUSTOM_USER_BUTTON(9) - CHECK_CUSTOM_USER_BUTTON(9); - #endif - #if HAS_BETTER_USER_BUTTON(10) - CHECK_BETTER_USER_BUTTON(10); - #elif HAS_CUSTOM_USER_BUTTON(10) - CHECK_CUSTOM_USER_BUTTON(10); - #endif - #if HAS_BETTER_USER_BUTTON(11) - CHECK_BETTER_USER_BUTTON(11); - #elif HAS_CUSTOM_USER_BUTTON(11) - CHECK_CUSTOM_USER_BUTTON(11); - #endif - #if HAS_BETTER_USER_BUTTON(12) - CHECK_BETTER_USER_BUTTON(12); - #elif HAS_CUSTOM_USER_BUTTON(12) - CHECK_CUSTOM_USER_BUTTON(12); - #endif - #if HAS_BETTER_USER_BUTTON(13) - CHECK_BETTER_USER_BUTTON(13); - #elif HAS_CUSTOM_USER_BUTTON(13) - CHECK_CUSTOM_USER_BUTTON(13); - #endif - #if HAS_BETTER_USER_BUTTON(14) - CHECK_BETTER_USER_BUTTON(14); - #elif HAS_CUSTOM_USER_BUTTON(14) - CHECK_CUSTOM_USER_BUTTON(14); - #endif - #if HAS_BETTER_USER_BUTTON(15) - CHECK_BETTER_USER_BUTTON(15); - #elif HAS_CUSTOM_USER_BUTTON(15) - CHECK_CUSTOM_USER_BUTTON(15); - #endif - #if HAS_BETTER_USER_BUTTON(16) - CHECK_BETTER_USER_BUTTON(16); - #elif HAS_CUSTOM_USER_BUTTON(16) - CHECK_CUSTOM_USER_BUTTON(16); - #endif - #if HAS_BETTER_USER_BUTTON(17) - CHECK_BETTER_USER_BUTTON(17); - #elif HAS_CUSTOM_USER_BUTTON(17) - CHECK_CUSTOM_USER_BUTTON(17); - #endif - #if HAS_BETTER_USER_BUTTON(18) - CHECK_BETTER_USER_BUTTON(18); - #elif HAS_CUSTOM_USER_BUTTON(18) - CHECK_CUSTOM_USER_BUTTON(18); - #endif - #if HAS_BETTER_USER_BUTTON(19) - CHECK_BETTER_USER_BUTTON(19); - #elif HAS_CUSTOM_USER_BUTTON(19) - CHECK_CUSTOM_USER_BUTTON(19); - #endif - #if HAS_BETTER_USER_BUTTON(20) - CHECK_BETTER_USER_BUTTON(20); - #elif HAS_CUSTOM_USER_BUTTON(20) - CHECK_CUSTOM_USER_BUTTON(20); - #endif - #if HAS_BETTER_USER_BUTTON(21) - CHECK_BETTER_USER_BUTTON(21); - #elif HAS_CUSTOM_USER_BUTTON(21) - CHECK_CUSTOM_USER_BUTTON(21); - #endif - #if HAS_BETTER_USER_BUTTON(22) - CHECK_BETTER_USER_BUTTON(22); - #elif HAS_CUSTOM_USER_BUTTON(22) - CHECK_CUSTOM_USER_BUTTON(22); - #endif - #if HAS_BETTER_USER_BUTTON(23) - CHECK_BETTER_USER_BUTTON(23); - #elif HAS_CUSTOM_USER_BUTTON(23) - CHECK_CUSTOM_USER_BUTTON(23); - #endif - #if HAS_BETTER_USER_BUTTON(24) - CHECK_BETTER_USER_BUTTON(24); - #elif HAS_CUSTOM_USER_BUTTON(24) - CHECK_CUSTOM_USER_BUTTON(24); - #endif - #if HAS_BETTER_USER_BUTTON(25) - CHECK_BETTER_USER_BUTTON(25); - #elif HAS_CUSTOM_USER_BUTTON(25) - CHECK_CUSTOM_USER_BUTTON(25); - #endif - #endif - - TERN_(EASYTHREED_UI, easythreed_ui.run()); - - TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down - - TERN_(AUTO_POWER_CONTROL, powerManager.check(!ui.on_status_screen() || printJobOngoing() || printingIsPaused())); - - TERN_(HOTEND_IDLE_TIMEOUT, hotend_idle.check()); - - #if ENABLED(EXTRUDER_RUNOUT_PREVENT) - if (thermalManager.degHotend(active_extruder) > (EXTRUDER_RUNOUT_MINTEMP) - && ELAPSED(ms, gcode.previous_move_ms + SEC_TO_MS(EXTRUDER_RUNOUT_SECONDS)) - && !planner.has_blocks_queued() - ) { - #if ENABLED(SWITCHING_EXTRUDER) - bool oldstatus; - switch (active_extruder) { - default: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 0); stepper.ENABLE_EXTRUDER(0); break; - #if E_STEPPERS > 1 - case 2: case 3: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 1); stepper.ENABLE_EXTRUDER(1); break; - #if E_STEPPERS > 2 - case 4: case 5: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 2); stepper.ENABLE_EXTRUDER(2); break; - #if E_STEPPERS > 3 - case 6: case 7: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, 3); stepper.ENABLE_EXTRUDER(3); break; - #endif // E_STEPPERS > 3 - #endif // E_STEPPERS > 2 - #endif // E_STEPPERS > 1 - } - #else // !SWITCHING_EXTRUDER - bool oldstatus; - switch (active_extruder) { - default: - #define _CASE_EN(N) case N: oldstatus = stepper.AXIS_IS_ENABLED(E_AXIS, N); stepper.ENABLE_EXTRUDER(N); break; - REPEAT(E_STEPPERS, _CASE_EN); - } - #endif - - const float olde = current_position.e; - current_position.e += EXTRUDER_RUNOUT_EXTRUDE; - line_to_current_position(MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED)); - current_position.e = olde; - planner.set_e_position_mm(olde); - planner.synchronize(); - - #if ENABLED(SWITCHING_EXTRUDER) - switch (active_extruder) { - default: if (oldstatus) stepper.ENABLE_EXTRUDER(0); else stepper.DISABLE_EXTRUDER(0); break; - #if E_STEPPERS > 1 - case 2: case 3: if (oldstatus) stepper.ENABLE_EXTRUDER(1); else stepper.DISABLE_EXTRUDER(1); break; - #if E_STEPPERS > 2 - case 4: case 5: if (oldstatus) stepper.ENABLE_EXTRUDER(2); else stepper.DISABLE_EXTRUDER(2); break; - #endif // E_STEPPERS > 2 - #endif // E_STEPPERS > 1 - } - #else // !SWITCHING_EXTRUDER - switch (active_extruder) { - #define _CASE_RESTORE(N) case N: if (oldstatus) stepper.ENABLE_EXTRUDER(N); else stepper.DISABLE_EXTRUDER(N); break; - REPEAT(E_STEPPERS, _CASE_RESTORE); - } - #endif // !SWITCHING_EXTRUDER - - gcode.reset_stepper_timeout(ms); - } - #endif // EXTRUDER_RUNOUT_PREVENT - - #if ENABLED(DUAL_X_CARRIAGE) - // handle delayed move timeout - if (delayed_move_time && ELAPSED(ms, delayed_move_time) && IsRunning()) { - // travel moves have been received so enact them - delayed_move_time = 0xFFFFFFFFUL; // force moves to be done - destination = current_position; - prepare_line_to_destination(); - planner.synchronize(); - } - #endif - - TERN_(TEMP_STAT_LEDS, handle_status_leds()); - - TERN_(MONITOR_DRIVER_STATUS, monitor_tmc_drivers()); - - TERN_(MONITOR_L6470_DRIVER_STATUS, L64xxManager.monitor_driver()); - - // Limit check_axes_activity frequency to 10Hz - static millis_t next_check_axes_ms = 0; - if (ELAPSED(ms, next_check_axes_ms)) { - planner.check_axes_activity(); - next_check_axes_ms = ms + 100UL; - } - - #if PIN_EXISTS(FET_SAFETY) - static millis_t FET_next; - if (ELAPSED(ms, FET_next)) { - FET_next = ms + FET_SAFETY_DELAY; // 2µs pulse every FET_SAFETY_DELAY mS - OUT_WRITE(FET_SAFETY_PIN, !FET_SAFETY_INVERTED); - DELAY_US(2); - WRITE(FET_SAFETY_PIN, FET_SAFETY_INVERTED); - } - #endif -} - -/** - * Standard idle routine keeps the machine alive: - * - Core Marlin activities - * - Manage heaters (and Watchdog) - * - Max7219 heartbeat, animation, etc. - * - * Only after setup() is complete: - * - Handle filament runout sensors - * - Run HAL idle tasks - * - Handle Power-Loss Recovery - * - Run StallGuard endstop checks - * - Handle SD Card insert / remove - * - Handle USB Flash Drive insert / remove - * - Announce Host Keepalive state (if any) - * - Update the Print Job Timer state - * - Update the Beeper queue - * - Read Buttons and Update the LCD - * - Run i2c Position Encoders - * - Auto-report Temperatures / SD Status - * - Update the Průša MMU2 - * - Handle Joystick jogging - */ -void idle(bool no_stepper_sleep/*=false*/) { - #if ENABLED(MARLIN_DEV_MODE) - static uint16_t idle_depth = 0; - if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth); - #endif - - // Core Marlin activities - manage_inactivity(no_stepper_sleep); - - // Manage Heaters (and Watchdog) - thermalManager.task(); - - // Max7219 heartbeat, animation, etc - TERN_(MAX7219_DEBUG, max7219.idle_tasks()); - - // Return if setup() isn't completed - if (marlin_state == MF_INITIALIZING) goto IDLE_DONE; - - // TODO: Still causing errors - (void)check_tool_sensor_stats(active_extruder, true); - - // Handle filament runout sensors - #if HAS_FILAMENT_SENSOR - if (TERN1(HAS_PRUSA_MMU2, !mmu2.enabled())) - runout.run(); - #endif - - // Run HAL idle tasks - hal.idletask(); - - // Check network connection - TERN_(HAS_ETHERNET, ethernet.check()); - - // Handle Power-Loss Recovery - #if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS) - if (IS_SD_PRINTING()) recovery.outage(); - #endif - - // Run StallGuard endstop checks - #if ENABLED(SPI_ENDSTOPS) - if (endstops.tmc_spi_homing.any && TERN1(IMPROVE_HOMING_RELIABILITY, ELAPSED(millis(), sg_guard_period))) - LOOP_L_N(i, 4) if (endstops.tmc_spi_homing_check()) break; // Read SGT 4 times per idle loop - #endif - - // Handle SD Card insert / remove - TERN_(SDSUPPORT, card.manage_media()); - - // Handle USB Flash Drive insert / remove - TERN_(USB_FLASH_DRIVE_SUPPORT, card.diskIODriver()->idle()); - - // Announce Host Keepalive state (if any) - TERN_(HOST_KEEPALIVE_FEATURE, gcode.host_keepalive()); - - // Update the Print Job Timer state - TERN_(PRINTCOUNTER, print_job_timer.tick()); - - // Update the Beeper queue - TERN_(HAS_BEEPER, buzzer.tick()); - - // Handle UI input / draw events - TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update()); - - // Run i2c Position Encoders - #if ENABLED(I2C_POSITION_ENCODERS) - { - static millis_t i2cpem_next_update_ms; - if (planner.has_blocks_queued()) { - const millis_t ms = millis(); - if (ELAPSED(ms, i2cpem_next_update_ms)) { - I2CPEM.update(); - i2cpem_next_update_ms = ms + I2CPE_MIN_UPD_TIME_MS; - } - } - } - #endif - - // Auto-report Temperatures / SD Status - #if HAS_AUTO_REPORTING - if (!gcode.autoreport_paused) { - TERN_(AUTO_REPORT_TEMPERATURES, thermalManager.auto_reporter.tick()); - TERN_(AUTO_REPORT_FANS, fan_check.auto_reporter.tick()); - TERN_(AUTO_REPORT_SD_STATUS, card.auto_reporter.tick()); - TERN_(AUTO_REPORT_POSITION, position_auto_reporter.tick()); - TERN_(BUFFER_MONITORING, queue.auto_report_buffer_statistics()); - } - #endif - - // Update the Průša MMU2 - TERN_(HAS_PRUSA_MMU2, mmu2.mmu_loop()); - - // Handle Joystick jogging - TERN_(POLL_JOG, joystick.inject_jog_moves()); - - // Direct Stepping - TERN_(DIRECT_STEPPING, page_manager.write_responses()); - - // Update the LVGL interface - TERN_(HAS_TFT_LVGL_UI, LV_TASK_HANDLER()); - - IDLE_DONE: - TERN_(MARLIN_DEV_MODE, idle_depth--); - return; -} - -/** - * Kill all activity and lock the machine. - * After this the machine will need to be reset. - */ -void kill(FSTR_P const lcd_error/*=nullptr*/, FSTR_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) { - thermalManager.disable_all_heaters(); - - TERN_(HAS_CUTTER, cutter.kill()); // Full cutter shutdown including ISR control - - // Echo the LCD message to serial for extra context - if (lcd_error) { SERIAL_ECHO_START(); SERIAL_ECHOLNF(lcd_error); } - - #if HAS_DISPLAY - ui.kill_screen(lcd_error ?: GET_TEXT_F(MSG_KILLED), lcd_component ?: FPSTR(NUL_STR)); - #else - UNUSED(lcd_error); UNUSED(lcd_component); - #endif - - TERN_(HAS_TFT_LVGL_UI, lv_draw_error_message(lcd_error)); - - // "Error:Printer halted. kill() called!" - SERIAL_ERROR_MSG(STR_ERR_KILLED); - - #ifdef ACTION_ON_KILL - hostui.kill(); - #endif - - minkill(steppers_off); -} - -void minkill(const bool steppers_off/*=false*/) { - - // Wait a short time (allows messages to get out before shutting down. - for (int i = 1000; i--;) DELAY_US(600); - - cli(); // Stop interrupts - - // Wait to ensure all interrupts stopped - for (int i = 1000; i--;) DELAY_US(250); - - // Reiterate heaters off - thermalManager.disable_all_heaters(); - - TERN_(HAS_CUTTER, cutter.kill()); // Reiterate cutter shutdown - - // Power off all steppers (for M112) or just the E steppers - steppers_off ? stepper.disable_all_steppers() : stepper.disable_e_steppers(); - - TERN_(PSU_CONTROL, powerManager.power_off()); - - TERN_(HAS_SUICIDE, suicide()); - - #if EITHER(HAS_KILL, SOFT_RESET_ON_KILL) - - // Wait for both KILL and ENC to be released - while (TERN0(HAS_KILL, kill_state()) || TERN0(SOFT_RESET_ON_KILL, ui.button_pressed())) - hal.watchdog_refresh(); - - // Wait for either KILL or ENC to be pressed again - while (TERN1(HAS_KILL, !kill_state()) && TERN1(SOFT_RESET_ON_KILL, !ui.button_pressed())) - hal.watchdog_refresh(); - - // Reboot the board - hal.reboot(); - - #else - - for (;;) hal.watchdog_refresh(); // Wait for RESET button or power-cycle - - #endif -} - -/** - * 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 - - print_job_timer.stop(); - - #if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE) - thermalManager.set_fans_paused(false); // Un-pause fans for safety - #endif - - if (!IsStopped()) { - SERIAL_ERROR_MSG(STR_ERR_STOPPED); - LCD_MESSAGE(MSG_STOPPED); - safe_delay(350); // allow enough time for messages to get out before stopping - marlin_state = MF_STOPPED; - } -} - -inline void tmc_standby_setup() { - #if PIN_EXISTS(X_STDBY) - SET_INPUT_PULLDOWN(X_STDBY_PIN); - #endif - #if PIN_EXISTS(X2_STDBY) - SET_INPUT_PULLDOWN(X2_STDBY_PIN); - #endif - #if PIN_EXISTS(Y_STDBY) - SET_INPUT_PULLDOWN(Y_STDBY_PIN); - #endif - #if PIN_EXISTS(Y2_STDBY) - SET_INPUT_PULLDOWN(Y2_STDBY_PIN); - #endif - #if PIN_EXISTS(Z_STDBY) - SET_INPUT_PULLDOWN(Z_STDBY_PIN); - #endif - #if PIN_EXISTS(Z2_STDBY) - SET_INPUT_PULLDOWN(Z2_STDBY_PIN); - #endif - #if PIN_EXISTS(Z3_STDBY) - SET_INPUT_PULLDOWN(Z3_STDBY_PIN); - #endif - #if PIN_EXISTS(Z4_STDBY) - SET_INPUT_PULLDOWN(Z4_STDBY_PIN); - #endif - #if PIN_EXISTS(I_STDBY) - SET_INPUT_PULLDOWN(I_STDBY_PIN); - #endif - #if PIN_EXISTS(J_STDBY) - SET_INPUT_PULLDOWN(J_STDBY_PIN); - #endif - #if PIN_EXISTS(K_STDBY) - SET_INPUT_PULLDOWN(K_STDBY_PIN); - #endif - #if PIN_EXISTS(E0_STDBY) - SET_INPUT_PULLDOWN(E0_STDBY_PIN); - #endif - #if PIN_EXISTS(E1_STDBY) - SET_INPUT_PULLDOWN(E1_STDBY_PIN); - #endif - #if PIN_EXISTS(E2_STDBY) - SET_INPUT_PULLDOWN(E2_STDBY_PIN); - #endif - #if PIN_EXISTS(E3_STDBY) - SET_INPUT_PULLDOWN(E3_STDBY_PIN); - #endif - #if PIN_EXISTS(E4_STDBY) - SET_INPUT_PULLDOWN(E4_STDBY_PIN); - #endif - #if PIN_EXISTS(E5_STDBY) - SET_INPUT_PULLDOWN(E5_STDBY_PIN); - #endif - #if PIN_EXISTS(E6_STDBY) - SET_INPUT_PULLDOWN(E6_STDBY_PIN); - #endif - #if PIN_EXISTS(E7_STDBY) - SET_INPUT_PULLDOWN(E7_STDBY_PIN); - #endif -} - -/** - * Marlin Firmware entry-point. Abandon Hope All Ye Who Enter Here. - * Setup before the program loop: - * - * - Call any special pre-init set for the board - * - Put TMC drivers into Low Power Standby mode - * - Init the serial ports (so setup can be debugged) - * - Set up the kill and suicide pins - * - Prepare (disable) board JTAG and Debug ports - * - Init serial for a connected MKS TFT with WiFi - * - Install Marlin custom Exception Handlers, if set. - * - Init Marlin's HAL interfaces (for SPI, i2c, etc.) - * - Init some optional hardware and features: - * • MAX Thermocouple pins - * • Duet Smart Effector - * • Filament Runout Sensor - * • TMC220x Stepper Drivers (Serial) - * • PSU control - * • Power-loss Recovery - * • L64XX Stepper Drivers (SPI) - * • Stepper Driver Reset: DISABLE - * • TMC Stepper Drivers (SPI) - * • Run hal.init_board() for additional pins setup - * • ESP WiFi - * - Get the Reset Reason and report it - * - Print startup messages and diagnostics - * - Calibrate the HAL DELAY for precise timing - * - Init the buzzer, possibly a custom timer - * - Init more optional hardware: - * • Color LED illumination - * • Neopixel illumination - * • Controller Fan - * • Creality DWIN LCD (show boot image) - * • Tare the Probe if possible - * - Mount the (most likely external) SD Card - * - Load settings from EEPROM (or use defaults) - * - Init the Ethernet Port - * - Init Touch Buttons (for emulated DOGLCD) - * - Adjust the (certainly wrong) current position by the home offset - * - Init the Planner::position (steps) based on current (native) position - * - Initialize more managers and peripherals: - * • Temperatures - * • Print Job Timer - * • Endstops and Endstop Interrupts - * • Stepper ISR - Kind of Important! - * • Servos - * • Servo-based Probe - * • Photograph Pin - * • Laser/Spindle tool Power / PWM - * • Coolant Control - * • Bed Probe - * • Stepper Driver Reset: ENABLE - * • Digipot I2C - Stepper driver current control - * • Stepper DAC - Stepper driver current control - * • Solenoid (probe, or for other use) - * • Home Pin - * • Custom User Buttons - * • Red/Blue Status LEDs - * • Case Light - * • Prusa MMU filament changer - * • Fan Multiplexer - * • Mixing Extruder - * • BLTouch Probe - * • I2C Position Encoders - * • Custom I2C Bus handlers - * • Enhanced tools or extruders: - * • Switching Extruder - * • Switching Nozzle - * • Parking Extruder - * • Magnetic Parking Extruder - * • Switching Toolhead - * • Electromagnetic Switching Toolhead - * • Watchdog Timer - Also Kind of Important! - * • Closed Loop Controller - * - Run Startup Commands, if defined - * - Tell host to close Host Prompts - * - Test Trinamic driver connections - * - Init Prusa MMU2 filament changer - * - Init and test BL24Cxx EEPROM - * - Init Creality DWIN encoder, show faux progress bar - * - Reset Status Message / Show Service Messages - * - Init MAX7219 LED Matrix - * - Init Direct Stepping (Klipper-style motion control) - * - Init TFT LVGL UI (with 3D Graphics) - * - Apply Password Lock - Hold for Authentication - * - Open Touch Screen Calibration screen, if not calibrated - * - Set Marlin to RUNNING State - */ -void setup() { - #ifdef FASTIO_INIT - FASTIO_INIT(); - #endif - - #ifdef BOARD_PREINIT - BOARD_PREINIT(); // Low-level init (before serial init) - #endif - - tmc_standby_setup(); // TMC Low Power Standby pins must be set early or they're not usable - - // Check startup - does nothing if bootloader sets MCUSR to 0 - const byte mcu = hal.get_reset_source(); - hal.clear_reset_source(); - - #if ENABLED(MARLIN_DEV_MODE) - auto log_current_ms = [&](PGM_P const msg) { - SERIAL_ECHO_START(); - SERIAL_CHAR('['); SERIAL_ECHO(millis()); SERIAL_ECHOPGM("] "); - SERIAL_ECHOLNPGM_P(msg); - }; - #define SETUP_LOG(M) log_current_ms(PSTR(M)) - #else - #define SETUP_LOG(...) NOOP - #endif - #define SETUP_RUN(C) do{ SETUP_LOG(STRINGIFY(C)); C; }while(0) - - MYSERIAL1.begin(BAUDRATE); - millis_t serial_connect_timeout = millis() + 1000UL; - while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } - - #if HAS_MULTI_SERIAL && !HAS_ETHERNET - #ifndef BAUDRATE_2 - #define BAUDRATE_2 BAUDRATE - #endif - MYSERIAL2.begin(BAUDRATE_2); - serial_connect_timeout = millis() + 1000UL; - while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } - #ifdef SERIAL_PORT_3 - #ifndef BAUDRATE_3 - #define BAUDRATE_3 BAUDRATE - #endif - MYSERIAL3.begin(BAUDRATE_3); - serial_connect_timeout = millis() + 1000UL; - while (!MYSERIAL3.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ } - #endif - #endif - SERIAL_ECHOLNPGM("start"); - - // Set up these pins early to prevent suicide - #if HAS_KILL - SETUP_LOG("KILL_PIN"); - #if KILL_PIN_STATE - SET_INPUT_PULLDOWN(KILL_PIN); - #else - SET_INPUT_PULLUP(KILL_PIN); - #endif - #endif - - #if ENABLED(FREEZE_FEATURE) - SETUP_LOG("FREEZE_PIN"); - #if FREEZE_STATE - SET_INPUT_PULLDOWN(FREEZE_PIN); - #else - SET_INPUT_PULLUP(FREEZE_PIN); - #endif - #endif - - #if HAS_SUICIDE - SETUP_LOG("SUICIDE_PIN"); - OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_STATE); - #endif - - #ifdef JTAGSWD_RESET - SETUP_LOG("JTAGSWD_RESET"); - JTAGSWD_RESET(); - #endif - - // Disable any hardware debug to free up pins for IO - #if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE) - delay(10); - SETUP_LOG("JTAGSWD_DISABLE"); - JTAGSWD_DISABLE(); - #elif ENABLED(DISABLE_JTAG) && defined(JTAG_DISABLE) - delay(10); - SETUP_LOG("JTAG_DISABLE"); - JTAG_DISABLE(); - #endif - - TERN_(DYNAMIC_VECTORTABLE, hook_cpu_exceptions()); // If supported, install Marlin exception handlers at runtime - - SETUP_RUN(hal.init()); - - // Init and disable SPI thermocouples; this is still needed - #if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0)) - OUT_WRITE(TEMP_0_CS_PIN, HIGH); // Disable - #endif - #if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1)) - OUT_WRITE(TEMP_1_CS_PIN, HIGH); - #endif - - #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) - OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode - #endif - - #if HAS_FILAMENT_SENSOR - SETUP_RUN(runout.setup()); - #endif - - #if HAS_TMC220x - SETUP_RUN(tmc_serial_begin()); - #endif - - #if HAS_TMC_SPI - #if DISABLED(TMC_USE_SW_SPI) - SETUP_RUN(SPI.begin()); - #endif - SETUP_RUN(tmc_init_cs_pins()); - #endif - - #if HAS_L64XX - SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers - #endif - - #if ENABLED(PSU_CONTROL) - SETUP_LOG("PSU_CONTROL"); - powerManager.init(); - #endif - - #if ENABLED(POWER_LOSS_RECOVERY) - SETUP_RUN(recovery.setup()); - #endif - - #if HAS_STEPPER_RESET - SETUP_RUN(disableStepperDrivers()); - #endif - - SETUP_RUN(hal.init_board()); - - SETUP_RUN(esp_wifi_init()); - - // Report Reset Reason - if (mcu & RST_POWER_ON) SERIAL_ECHOLNPGM(STR_POWERUP); - if (mcu & RST_EXTERNAL) SERIAL_ECHOLNPGM(STR_EXTERNAL_RESET); - if (mcu & RST_BROWN_OUT) SERIAL_ECHOLNPGM(STR_BROWNOUT_RESET); - if (mcu & RST_WATCHDOG) SERIAL_ECHOLNPGM(STR_WATCHDOG_RESET); - if (mcu & RST_SOFTWARE) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET); - - // Identify myself as Marlin x.x.x - SERIAL_ECHOLNPGM("Marlin " SHORT_BUILD_VERSION); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) - SERIAL_ECHO_MSG( - " Last Updated: " STRING_DISTRIBUTION_DATE - " | Author: " STRING_CONFIG_H_AUTHOR - ); - #endif - SERIAL_ECHO_MSG(" Compiled: " __DATE__); - SERIAL_ECHO_MSG(STR_FREE_MEMORY, hal.freeMemory(), STR_PLANNER_BUFFER_BYTES, sizeof(block_t) * (BLOCK_BUFFER_SIZE)); - - // Some HAL need precise delay adjustment - calibrate_delay_loop(); - - // Init buzzer pin(s) - #if HAS_BEEPER - SETUP_RUN(buzzer.init()); - #endif - - // Set up LEDs early - #if HAS_COLOR_LEDS - SETUP_RUN(leds.setup()); - #endif - - #if ENABLED(NEOPIXEL2_SEPARATE) - SETUP_RUN(leds2.setup()); - #endif - - #if ENABLED(USE_CONTROLLER_FAN) // Set up fan controller to initialize also the default configurations. - SETUP_RUN(controllerFan.setup()); - #endif - - TERN_(HAS_FANCHECK, fan_check.init()); - - // UI must be initialized before EEPROM - // (because EEPROM code calls the UI). - - SETUP_RUN(ui.init()); - - #if PIN_EXISTS(SAFE_POWER) - #if HAS_DRIVER_SAFE_POWER_PROTECT - SETUP_RUN(stepper_driver_backward_check()); - #else - SETUP_LOG("SAFE_POWER"); - OUT_WRITE(SAFE_POWER_PIN, HIGH); - #endif - #endif - - #if BOTH(SDSUPPORT, SDCARD_EEPROM_EMULATION) - SETUP_RUN(card.mount()); // Mount media with settings before first_load - #endif - - SETUP_RUN(settings.first_load()); // Load data from EEPROM if available (or use defaults) - // This also updates variables in the planner, elsewhere - - #if BOTH(HAS_WIRED_LCD, SHOW_BOOTSCREEN) - SETUP_RUN(ui.show_bootscreen()); - const millis_t bootscreen_ms = millis(); - #endif - - #if ENABLED(PROBE_TARE) - SETUP_RUN(probe.tare_init()); - #endif - - #if HAS_ETHERNET - SETUP_RUN(ethernet.init()); - #endif - - #if HAS_TOUCH_BUTTONS - SETUP_RUN(touchBt.init()); - #endif - - TERN_(HAS_M206_COMMAND, current_position += home_offset); // Init current position based on home_offset - - sync_plan_position(); // Vital to init stepper/planner equivalent for current_position - - SETUP_RUN(thermalManager.init()); // Initialize temperature loop - - SETUP_RUN(print_job_timer.init()); // Initial setup of print job timer - - SETUP_RUN(endstops.init()); // Init endstops and pullups - - #if ENABLED(DELTA) && !HAS_SOFTWARE_ENDSTOPS - SETUP_RUN(refresh_delta_clip_start_height()); // Init safe delta height without soft endstops - #endif - - SETUP_RUN(stepper.init()); // Init stepper. This enables interrupts! - - #if HAS_SERVOS - SETUP_RUN(servo_init()); - #endif - - #if HAS_Z_SERVO_PROBE - SETUP_RUN(probe.servo_probe_init()); - #endif - - #if HAS_PHOTOGRAPH - OUT_WRITE(PHOTOGRAPH_PIN, LOW); - #endif - - #if HAS_CUTTER - SETUP_RUN(cutter.init()); - #endif - - #if ENABLED(COOLANT_MIST) - OUT_WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Init Mist Coolant OFF - #endif - #if ENABLED(COOLANT_FLOOD) - OUT_WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Init Flood Coolant OFF - #endif - - #if HAS_BED_PROBE - #if PIN_EXISTS(PROBE_ENABLE) - OUT_WRITE(PROBE_ENABLE_PIN, LOW); // Disable - #endif - SETUP_RUN(endstops.enable_z_probe(false)); - #endif - - #if HAS_STEPPER_RESET - SETUP_RUN(enableStepperDrivers()); - #endif - - #if HAS_MOTOR_CURRENT_I2C - SETUP_RUN(digipot_i2c.init()); - #endif - - #if HAS_MOTOR_CURRENT_DAC - SETUP_RUN(stepper_dac.init()); - #endif - - #if EITHER(Z_PROBE_SLED, SOLENOID_PROBE) && HAS_SOLENOID_1 - OUT_WRITE(SOL1_PIN, LOW); // OFF - #endif - - #if HAS_HOME - SET_INPUT_PULLUP(HOME_PIN); - #endif - - #if ENABLED(CUSTOM_USER_BUTTONS) - #define INIT_CUSTOM_USER_BUTTON_PIN(N) do{ SET_INPUT(BUTTON##N##_PIN); WRITE(BUTTON##N##_PIN, !BUTTON##N##_HIT_STATE); }while(0) - - #if HAS_CUSTOM_USER_BUTTON(1) - INIT_CUSTOM_USER_BUTTON_PIN(1); - #endif - #if HAS_CUSTOM_USER_BUTTON(2) - INIT_CUSTOM_USER_BUTTON_PIN(2); - #endif - #if HAS_CUSTOM_USER_BUTTON(3) - INIT_CUSTOM_USER_BUTTON_PIN(3); - #endif - #if HAS_CUSTOM_USER_BUTTON(4) - INIT_CUSTOM_USER_BUTTON_PIN(4); - #endif - #if HAS_CUSTOM_USER_BUTTON(5) - INIT_CUSTOM_USER_BUTTON_PIN(5); - #endif - #if HAS_CUSTOM_USER_BUTTON(6) - INIT_CUSTOM_USER_BUTTON_PIN(6); - #endif - #if HAS_CUSTOM_USER_BUTTON(7) - INIT_CUSTOM_USER_BUTTON_PIN(7); - #endif - #if HAS_CUSTOM_USER_BUTTON(8) - INIT_CUSTOM_USER_BUTTON_PIN(8); - #endif - #if HAS_CUSTOM_USER_BUTTON(9) - INIT_CUSTOM_USER_BUTTON_PIN(9); - #endif - #if HAS_CUSTOM_USER_BUTTON(10) - INIT_CUSTOM_USER_BUTTON_PIN(10); - #endif - #if HAS_CUSTOM_USER_BUTTON(11) - INIT_CUSTOM_USER_BUTTON_PIN(11); - #endif - #if HAS_CUSTOM_USER_BUTTON(12) - INIT_CUSTOM_USER_BUTTON_PIN(12); - #endif - #if HAS_CUSTOM_USER_BUTTON(13) - INIT_CUSTOM_USER_BUTTON_PIN(13); - #endif - #if HAS_CUSTOM_USER_BUTTON(14) - INIT_CUSTOM_USER_BUTTON_PIN(14); - #endif - #if HAS_CUSTOM_USER_BUTTON(15) - INIT_CUSTOM_USER_BUTTON_PIN(15); - #endif - #if HAS_CUSTOM_USER_BUTTON(16) - INIT_CUSTOM_USER_BUTTON_PIN(16); - #endif - #if HAS_CUSTOM_USER_BUTTON(17) - INIT_CUSTOM_USER_BUTTON_PIN(17); - #endif - #if HAS_CUSTOM_USER_BUTTON(18) - INIT_CUSTOM_USER_BUTTON_PIN(18); - #endif - #if HAS_CUSTOM_USER_BUTTON(19) - INIT_CUSTOM_USER_BUTTON_PIN(19); - #endif - #if HAS_CUSTOM_USER_BUTTON(20) - INIT_CUSTOM_USER_BUTTON_PIN(20); - #endif - #if HAS_CUSTOM_USER_BUTTON(21) - INIT_CUSTOM_USER_BUTTON_PIN(21); - #endif - #if HAS_CUSTOM_USER_BUTTON(22) - INIT_CUSTOM_USER_BUTTON_PIN(22); - #endif - #if HAS_CUSTOM_USER_BUTTON(23) - INIT_CUSTOM_USER_BUTTON_PIN(23); - #endif - #if HAS_CUSTOM_USER_BUTTON(24) - INIT_CUSTOM_USER_BUTTON_PIN(24); - #endif - #if HAS_CUSTOM_USER_BUTTON(25) - INIT_CUSTOM_USER_BUTTON_PIN(25); - #endif - #endif - - #if PIN_EXISTS(STAT_LED_RED) - OUT_WRITE(STAT_LED_RED_PIN, LOW); // OFF - #endif - #if PIN_EXISTS(STAT_LED_BLUE) - OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF - #endif - - #if ENABLED(CASE_LIGHT_ENABLE) - SETUP_RUN(caselight.init()); - #endif - - #if HAS_PRUSA_MMU1 - SETUP_RUN(mmu_init()); - #endif - - #if HAS_FANMUX - SETUP_RUN(fanmux_init()); - #endif - - #if ENABLED(MIXING_EXTRUDER) - SETUP_RUN(mixer.init()); - #endif - - #if ENABLED(BLTOUCH) - SETUP_RUN(bltouch.init(/*set_voltage=*/true)); - #endif - - #if ENABLED(MAGLEV4) - OUT_WRITE(MAGLEV_TRIGGER_PIN, LOW); - #endif - - #if ENABLED(I2C_POSITION_ENCODERS) - SETUP_RUN(I2CPEM.init()); - #endif - - #if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0 - SETUP_LOG("i2c..."); - i2c.onReceive(i2c_on_receive); - i2c.onRequest(i2c_on_request); - #endif - - #if DO_SWITCH_EXTRUDER - SETUP_RUN(move_extruder_servo(0)); // Initialize extruder servo - #endif - - #if ENABLED(SWITCHING_NOZZLE) - SETUP_LOG("SWITCHING_NOZZLE"); - // Initialize nozzle servo(s) - #if SWITCHING_NOZZLE_TWO_SERVOS - lower_nozzle(0); - raise_nozzle(1); - #else - move_nozzle_servo(0); - #endif - #endif - - #if ENABLED(PARKING_EXTRUDER) - SETUP_RUN(pe_solenoid_init()); - #elif ENABLED(MAGNETIC_PARKING_EXTRUDER) - SETUP_RUN(mpe_settings_init()); - #elif ENABLED(SWITCHING_TOOLHEAD) - SETUP_RUN(swt_init()); - #elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD) - SETUP_RUN(est_init()); - #endif - - #if ENABLED(USE_WATCHDOG) - SETUP_RUN(hal.watchdog_init()); // Reinit watchdog after hal.get_reset_source call - #endif - - #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - SETUP_RUN(closedloop.init()); - #endif - - #ifdef STARTUP_COMMANDS - SETUP_LOG("STARTUP_COMMANDS"); - queue.inject(F(STARTUP_COMMANDS)); - #endif - - #if ENABLED(HOST_PROMPT_SUPPORT) - SETUP_RUN(hostui.prompt_end()); - #endif - - #if HAS_DRIVER_SAFE_POWER_PROTECT - SETUP_RUN(stepper_driver_backward_report()); - #endif - - #if HAS_PRUSA_MMU2 - SETUP_RUN(mmu2.init()); - #endif - - #if ENABLED(IIC_BL24CXX_EEPROM) - BL24CXX::init(); - const uint8_t err = BL24CXX::check(); - SERIAL_ECHO_TERNARY(err, "BL24CXX Check ", "failed", "succeeded", "!\n"); - #endif - - #if HAS_DWIN_E3V2_BASIC - SETUP_RUN(DWIN_InitScreen()); - #endif - - #if HAS_SERVICE_INTERVALS && !HAS_DWIN_E3V2_BASIC - SETUP_RUN(ui.reset_status(true)); // Show service messages or keep current status - #endif - - #if ENABLED(MAX7219_DEBUG) - SETUP_RUN(max7219.init()); - #endif - - #if ENABLED(DIRECT_STEPPING) - SETUP_RUN(page_manager.init()); - #endif - - #if HAS_TFT_LVGL_UI - #if ENABLED(SDSUPPORT) - if (!card.isMounted()) SETUP_RUN(card.mount()); // Mount SD to load graphics and fonts - #endif - SETUP_RUN(tft_lvgl_init()); - #endif - - #if BOTH(HAS_WIRED_LCD, SHOW_BOOTSCREEN) - const millis_t elapsed = millis() - bootscreen_ms; - #if ENABLED(MARLIN_DEV_MODE) - SERIAL_ECHOLNPGM("elapsed=", elapsed); - #endif - SETUP_RUN(ui.bootscreen_completion(elapsed)); - #endif - - #if ENABLED(PASSWORD_ON_STARTUP) - SETUP_RUN(password.lock_machine()); // Will not proceed until correct password provided - #endif - - #if BOTH(HAS_MARLINUI_MENU, TOUCH_SCREEN_CALIBRATION) && EITHER(TFT_CLASSIC_UI, TFT_COLOR_UI) - SETUP_RUN(ui.check_touch_calibration()); - #endif - - #if ENABLED(EASYTHREED_UI) - SETUP_RUN(easythreed_ui.init()); - #endif - - #if HAS_TRINAMIC_CONFIG && DISABLED(PSU_DEFAULT_OFF) - SETUP_RUN(test_tmc_connection()); - #endif - - marlin_state = MF_RUNNING; - - SETUP_LOG("setup() completed."); -} - -/** - * The main Marlin program loop - * - * - Call idle() to handle all tasks between G-code commands - * Note that no G-codes from the queue can be executed during idle() - * but many G-codes can be called directly anytime like macros. - * - Check whether SD card auto-start is needed now. - * - Check whether SD print finishing is needed now. - * - Run one G-code command from the immediate or main command queue - * and open up one space. Commands in the main queue may come from sd - * card, host, or by direct injection. The queue will continue to fill - * as long as idle() or manage_inactivity() are being called. - */ -void loop() { - do { - idle(); - - #if ENABLED(SDSUPPORT) - if (card.flag.abort_sd_printing) abortSDPrinting(); - if (marlin_state == MF_SD_COMPLETE) finishSDPrinting(); - #endif - - queue.advance(); - - #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN) - powerManager.checkAutoPowerOff(); - #endif - - endstops.event_handler(); - - TERN_(HAS_TFT_LVGL_UI, printer_state_polling()); - - } while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards -} diff --git a/src/MarlinCore.h b/src/MarlinCore.h deleted file mode 100644 index f80405a..0000000 --- a/src/MarlinCore.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "inc/MarlinConfig.h" - -#include -#include -#include - -void stop(); - -// Pass true to keep steppers from timing out -void idle(bool no_stepper_sleep=false); -inline void idle_no_sleep() { idle(true); } - -#if ENABLED(G38_PROBE_TARGET) - extern uint8_t G38_move; // Flag to tell the ISR that G38 is in progress, and the type - extern bool G38_did_trigger; // Flag from the ISR to indicate the endstop changed -#endif - -void kill(FSTR_P const lcd_error=nullptr, FSTR_P const lcd_component=nullptr, const bool steppers_off=false); -void minkill(const bool steppers_off=false); - -// Global State of the firmware -enum MarlinState : uint8_t { - MF_INITIALIZING = 0, - MF_STOPPED, - MF_KILLED, - MF_RUNNING, - MF_SD_COMPLETE, - MF_PAUSED, - MF_WAITING, -}; - -extern MarlinState marlin_state; -inline bool IsRunning() { return marlin_state >= MF_RUNNING; } -inline bool IsStopped() { return marlin_state == MF_STOPPED; } - -bool printingIsActive(); -bool printJobOngoing(); -bool printingIsPaused(); -void startOrResumeJob(); - -bool printer_busy(); - -extern bool wait_for_heatup; - -#if HAS_RESUME_CONTINUE - extern bool wait_for_user; - void wait_for_user_response(millis_t ms=0, const bool no_sleep=false); -#endif - -bool pin_is_protected(const pin_t pin); - -#if HAS_SUICIDE - inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_STATE); } -#endif - -#if HAS_KILL - #ifndef KILL_PIN_STATE - #define KILL_PIN_STATE LOW - #endif - inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; } -#endif - -extern const char M112_KILL_STR[]; diff --git a/src/core/boards.h b/src/core/boards.h deleted file mode 100644 index 55cab84..0000000 --- a/src/core/boards.h +++ /dev/null @@ -1,475 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "macros.h" - -#define BOARD_UNKNOWN -1 - -// -// RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560 -// - -#define BOARD_RAMPS_OLD 1000 // MEGA/RAMPS up to 1.2 - -#define BOARD_RAMPS_13_EFB 1010 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_13_EEB 1011 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_13_EFF 1012 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_13_EEF 1013 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_13_SF 1014 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan) - -#define BOARD_RAMPS_14_EFB 1020 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_14_EEB 1021 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_14_EFF 1022 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_14_EEF 1023 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_14_SF 1024 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan) - -#define BOARD_RAMPS_PLUS_EFB 1030 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_PLUS_EEB 1031 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_PLUS_EFF 1032 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_PLUS_EEF 1033 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_PLUS_SF 1034 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan) - -// -// RAMPS Derivatives - ATmega1280, ATmega2560 -// - -#define BOARD_3DRAG 1100 // 3Drag Controller -#define BOARD_K8200 1101 // Velleman K8200 Controller (derived from 3Drag Controller) -#define BOARD_K8400 1102 // Velleman K8400 Controller (derived from 3Drag Controller) -#define BOARD_K8600 1103 // Velleman K8600 Controller (Vertex Nano) -#define BOARD_K8800 1104 // Velleman K8800 Controller (Vertex Delta) -#define BOARD_BAM_DICE 1105 // 2PrintBeta BAM&DICE with STK drivers -#define BOARD_BAM_DICE_DUE 1106 // 2PrintBeta BAM&DICE Due with STK drivers -#define BOARD_MKS_BASE 1107 // MKS BASE v1.0 -#define BOARD_MKS_BASE_14 1108 // MKS BASE v1.4 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_15 1109 // MKS BASE v1.5 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_16 1110 // MKS BASE v1.6 with Allegro A4982 stepper drivers -#define BOARD_MKS_BASE_HEROIC 1111 // MKS BASE 1.0 with Heroic HR4982 stepper drivers -#define BOARD_MKS_GEN_13 1112 // MKS GEN v1.3 or 1.4 -#define BOARD_MKS_GEN_L 1113 // MKS GEN L -#define BOARD_KFB_2 1114 // BigTreeTech or BIQU KFB2.0 -#define BOARD_ZRIB_V20 1115 // zrib V2.0 (Chinese RAMPS replica) -#define BOARD_ZRIB_V52 1116 // zrib V5.2 (Chinese RAMPS replica) -#define BOARD_FELIX2 1117 // Felix 2.0+ Electronics Board (RAMPS like) -#define BOARD_RIGIDBOARD 1118 // Invent-A-Part RigidBoard -#define BOARD_RIGIDBOARD_V2 1119 // Invent-A-Part RigidBoard V2 -#define BOARD_SAINSMART_2IN1 1120 // Sainsmart 2-in-1 board -#define BOARD_ULTIMAKER 1121 // Ultimaker -#define BOARD_ULTIMAKER_OLD 1122 // Ultimaker (Older electronics. Pre 1.5.4. This is rare) -#define BOARD_AZTEEG_X3 1123 // Azteeg X3 -#define BOARD_AZTEEG_X3_PRO 1124 // Azteeg X3 Pro -#define BOARD_ULTIMAIN_2 1125 // Ultimainboard 2.x (Uses TEMP_SENSOR 20) -#define BOARD_RUMBA 1126 // Rumba -#define BOARD_RUMBA_RAISE3D 1127 // Raise3D N series Rumba derivative -#define BOARD_RL200 1128 // Rapide Lite 200 (v1, low-cost RUMBA clone with drv) -#define BOARD_FORMBOT_TREX2PLUS 1129 // Formbot T-Rex 2 Plus -#define BOARD_FORMBOT_TREX3 1130 // Formbot T-Rex 3 -#define BOARD_FORMBOT_RAPTOR 1131 // Formbot Raptor -#define BOARD_FORMBOT_RAPTOR2 1132 // Formbot Raptor 2 -#define BOARD_BQ_ZUM_MEGA_3D 1133 // bq ZUM Mega 3D -#define BOARD_MAKEBOARD_MINI 1134 // MakeBoard Mini v2.1.2 by MicroMake -#define BOARD_TRIGORILLA_13 1135 // TriGorilla Anycubic version 1.3-based on RAMPS EFB -#define BOARD_TRIGORILLA_14 1136 // ... Ver 1.4 -#define BOARD_TRIGORILLA_14_11 1137 // ... Rev 1.1 (new servo pin order) -#define BOARD_RAMPS_ENDER_4 1138 // Creality: Ender-4, CR-8 -#define BOARD_RAMPS_CREALITY 1139 // Creality: CR10S, CR20, CR-X -#define BOARD_DAGOMA_F5 1140 // Dagoma F5 -#define BOARD_FYSETC_F6_13 1141 // FYSETC F6 1.3 -#define BOARD_FYSETC_F6_14 1142 // FYSETC F6 1.4 -#define BOARD_DUPLICATOR_I3_PLUS 1143 // Wanhao Duplicator i3 Plus -#define BOARD_VORON 1144 // VORON Design -#define BOARD_TRONXY_V3_1_0 1145 // Tronxy TRONXY-V3-1.0 -#define BOARD_Z_BOLT_X_SERIES 1146 // Z-Bolt X Series -#define BOARD_TT_OSCAR 1147 // TT OSCAR -#define BOARD_OVERLORD 1148 // Overlord/Overlord Pro -#define BOARD_HJC2560C_REV1 1149 // ADIMLab Gantry v1 -#define BOARD_HJC2560C_REV2 1150 // ADIMLab Gantry v2 -#define BOARD_TANGO 1151 // BIQU Tango V1 -#define BOARD_MKS_GEN_L_V2 1152 // MKS GEN L V2 -#define BOARD_MKS_GEN_L_V21 1153 // MKS GEN L V2.1 -#define BOARD_COPYMASTER_3D 1154 // Copymaster 3D -#define BOARD_ORTUR_4 1155 // Ortur 4 -#define BOARD_TENLOG_D3_HERO 1156 // Tenlog D3 Hero IDEX printer -#define BOARD_RAMPS_S_12_EEFB 1157 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed) -#define BOARD_RAMPS_S_12_EEEB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed) -#define BOARD_RAMPS_S_12_EFFB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed) -#define BOARD_LONGER3D_LK1_PRO 1160 // Longer LK1 PRO / Alfawise U20 Pro (PRO version) -#define BOARD_LONGER3D_LKx_PRO 1161 // Longer LKx PRO / Alfawise Uxx Pro (PRO version) -#define BOARD_ZRIB_V53 1162 // Zonestar zrib V5.3 (Chinese RAMPS replica) -#define BOARD_PXMALION_CORE_I3 1163 // Pxmalion Core I3 - -// -// RAMBo and derivatives -// - -#define BOARD_RAMBO 1200 // Rambo -#define BOARD_MINIRAMBO 1201 // Mini-Rambo -#define BOARD_MINIRAMBO_10A 1202 // Mini-Rambo 1.0a -#define BOARD_EINSY_RAMBO 1203 // Einsy Rambo -#define BOARD_EINSY_RETRO 1204 // Einsy Retro -#define BOARD_SCOOVO_X9H 1205 // abee Scoovo X9H -#define BOARD_RAMBO_THINKERV2 1206 // ThinkerV2 - -// -// Other ATmega1280, ATmega2560 -// - -#define BOARD_CNCONTROLS_11 1300 // Cartesio CN Controls V11 -#define BOARD_CNCONTROLS_12 1301 // Cartesio CN Controls V12 -#define BOARD_CNCONTROLS_15 1302 // Cartesio CN Controls V15 -#define BOARD_CHEAPTRONIC 1303 // Cheaptronic v1.0 -#define BOARD_CHEAPTRONIC_V2 1304 // Cheaptronic v2.0 -#define BOARD_MIGHTYBOARD_REVE 1305 // Makerbot Mightyboard Revision E -#define BOARD_MEGATRONICS 1306 // Megatronics -#define BOARD_MEGATRONICS_2 1307 // Megatronics v2.0 -#define BOARD_MEGATRONICS_3 1308 // Megatronics v3.0 -#define BOARD_MEGATRONICS_31 1309 // Megatronics v3.1 -#define BOARD_MEGATRONICS_32 1310 // Megatronics v3.2 -#define BOARD_ELEFU_3 1311 // Elefu Ra Board (v3) -#define BOARD_LEAPFROG 1312 // Leapfrog -#define BOARD_MEGACONTROLLER 1313 // Mega controller -#define BOARD_GT2560_REV_A 1314 // Geeetech GT2560 Rev A -#define BOARD_GT2560_REV_A_PLUS 1315 // Geeetech GT2560 Rev A+ (with auto level probe) -#define BOARD_GT2560_REV_B 1316 // Geeetech GT2560 Rev B -#define BOARD_GT2560_V3 1317 // Geeetech GT2560 Rev B for A10(M/T/D) -#define BOARD_GT2560_V4 1318 // Geeetech GT2560 Rev B for A10(M/T/D) -#define BOARD_GT2560_V3_MC2 1319 // Geeetech GT2560 Rev B for Mecreator2 -#define BOARD_GT2560_V3_A20 1320 // Geeetech GT2560 Rev B for A20(M/T/D) -#define BOARD_EINSTART_S 1321 // Einstart retrofit -#define BOARD_WANHAO_ONEPLUS 1322 // Wanhao 0ne+ i3 Mini -#define BOARD_LEAPFROG_XEED2015 1323 // Leapfrog Xeed 2015 -#define BOARD_PICA_REVB 1324 // PICA Shield (original version) -#define BOARD_PICA 1325 // PICA Shield (rev C or later) -#define BOARD_INTAMSYS40 1326 // Intamsys 4.0 (Funmat HT) -#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only) -#define BOARD_GT2560_V4_A20 1328 // Geeetech GT2560 Rev B for A20(M/T/D) -#define BOARD_PROTONEER_CNC_SHIELD_V3 1329 // Mega controller & Protoneer CNC Shield V3.00 -#define BOARD_WEEDO_62A 1330 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.) - -// -// ATmega1281, ATmega2561 -// - -#define BOARD_MINITRONICS 1400 // Minitronics v1.0/1.1 -#define BOARD_SILVER_GATE 1401 // Silvergate v1.0 - -// -// Sanguinololu and Derivatives - ATmega644P, ATmega1284P -// - -#define BOARD_SANGUINOLOLU_11 1500 // Sanguinololu < 1.2 -#define BOARD_SANGUINOLOLU_12 1501 // Sanguinololu 1.2 and above -#define BOARD_MELZI 1502 // Melzi -#define BOARD_MELZI_V2 1503 // Melzi V2 -#define BOARD_MELZI_MAKR3D 1504 // Melzi with ATmega1284 (MaKr3d version) -#define BOARD_MELZI_CREALITY 1505 // Melzi Creality3D (for CR-10 etc) -#define BOARD_MELZI_MALYAN 1506 // Melzi Malyan M150 -#define BOARD_MELZI_TRONXY 1507 // Tronxy X5S -#define BOARD_STB_11 1508 // STB V1.1 -#define BOARD_AZTEEG_X1 1509 // Azteeg X1 -#define BOARD_ANET_10 1510 // Anet 1.0 (Melzi clone) -#define BOARD_ZMIB_V2 1511 // ZoneStar ZMIB V2 - -// -// Other ATmega644P, ATmega644, ATmega1284P -// - -#define BOARD_GEN3_MONOLITHIC 1600 // Gen3 Monolithic Electronics -#define BOARD_GEN3_PLUS 1601 // Gen3+ -#define BOARD_GEN6 1602 // Gen6 -#define BOARD_GEN6_DELUXE 1603 // Gen6 deluxe -#define BOARD_GEN7_CUSTOM 1604 // Gen7 custom (Alfons3 Version) https://github.com/Alfons3/Generation_7_Electronics -#define BOARD_GEN7_12 1605 // Gen7 v1.1, v1.2 -#define BOARD_GEN7_13 1606 // Gen7 v1.3 -#define BOARD_GEN7_14 1607 // Gen7 v1.4 -#define BOARD_OMCA_A 1608 // Alpha OMCA -#define BOARD_OMCA 1609 // Final OMCA -#define BOARD_SETHI 1610 // Sethi 3D_1 - -// -// Teensyduino - AT90USB1286, AT90USB1286P -// - -#define BOARD_TEENSYLU 1700 // Teensylu -#define BOARD_PRINTRBOARD 1701 // Printrboard (AT90USB1286) -#define BOARD_PRINTRBOARD_REVF 1702 // Printrboard Revision F (AT90USB1286) -#define BOARD_BRAINWAVE 1703 // Brainwave (AT90USB646) -#define BOARD_BRAINWAVE_PRO 1704 // Brainwave Pro (AT90USB1286) -#define BOARD_SAV_MKI 1705 // SAV Mk-I (AT90USB1286) -#define BOARD_TEENSY2 1706 // Teensy++2.0 (AT90USB1286) -#define BOARD_5DPRINT 1707 // 5DPrint D8 Driver Board - -// -// LPC1768 ARM Cortex M3 -// - -#define BOARD_RAMPS_14_RE_ARM_EFB 2000 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_14_RE_ARM_EEB 2001 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_14_RE_ARM_EFF 2002 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_14_RE_ARM_EEF 2003 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_14_RE_ARM_SF 2004 // Re-ARM with RAMPS 1.4 (Power outputs: Spindle, Controller Fan) -#define BOARD_MKS_SBASE 2005 // MKS-Sbase -#define BOARD_AZSMZ_MINI 2006 // AZSMZ Mini -#define BOARD_BIQU_BQ111_A4 2007 // BIQU BQ111-A4 -#define BOARD_SELENA_COMPACT 2008 // Selena Compact -#define BOARD_BIQU_B300_V1_0 2009 // BIQU B300_V1.0 -#define BOARD_MKS_SGEN_L 2010 // MKS-SGen-L -#define BOARD_GMARSH_X6_REV1 2011 // GMARSH X6, revision 1 prototype -#define BOARD_BTT_SKR_V1_1 2012 // BigTreeTech SKR v1.1 -#define BOARD_BTT_SKR_V1_3 2013 // BigTreeTech SKR v1.3 -#define BOARD_BTT_SKR_V1_4 2014 // BigTreeTech SKR v1.4 -#define BOARD_EMOTRONIC 2015 // eMotion-Tech eMotronic - -// -// LPC1769 ARM Cortex M3 -// - -#define BOARD_MKS_SGEN 2500 // MKS-SGen -#define BOARD_AZTEEG_X5_GT 2501 // Azteeg X5 GT -#define BOARD_AZTEEG_X5_MINI 2502 // Azteeg X5 Mini -#define BOARD_AZTEEG_X5_MINI_WIFI 2503 // Azteeg X5 Mini Wifi -#define BOARD_COHESION3D_REMIX 2504 // Cohesion3D ReMix -#define BOARD_COHESION3D_MINI 2505 // Cohesion3D Mini -#define BOARD_SMOOTHIEBOARD 2506 // Smoothieboard -#define BOARD_TH3D_EZBOARD 2507 // TH3D EZBoard v1.0 -#define BOARD_BTT_SKR_V1_4_TURBO 2508 // BigTreeTech SKR v1.4 TURBO -#define BOARD_MKS_SGEN_L_V2 2509 // MKS SGEN_L V2 -#define BOARD_BTT_SKR_E3_TURBO 2510 // BigTreeTech SKR E3 Turbo -#define BOARD_FLY_CDY 2511 // FLYmaker FLY CDY - -// -// SAM3X8E ARM Cortex M3 -// - -#define BOARD_DUE3DOM 3000 // DUE3DOM for Arduino DUE -#define BOARD_DUE3DOM_MINI 3001 // DUE3DOM MINI for Arduino DUE -#define BOARD_RADDS 3002 // RADDS -#define BOARD_RAMPS_FD_V1 3003 // RAMPS-FD v1 -#define BOARD_RAMPS_FD_V2 3004 // RAMPS-FD v2 -#define BOARD_RAMPS_SMART_EFB 3005 // RAMPS-SMART (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_SMART_EEB 3006 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_SMART_EFF 3007 // RAMPS-SMART (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_SMART_EEF 3008 // RAMPS-SMART (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_SMART_SF 3009 // RAMPS-SMART (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS_DUO_EFB 3010 // RAMPS Duo (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS_DUO_EEB 3011 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS_DUO_EFF 3012 // RAMPS Duo (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS_DUO_EEF 3013 // RAMPS Duo (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS_DUO_SF 3014 // RAMPS Duo (Power outputs: Spindle, Controller Fan) -#define BOARD_RAMPS4DUE_EFB 3015 // RAMPS4DUE (Power outputs: Hotend, Fan, Bed) -#define BOARD_RAMPS4DUE_EEB 3016 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Bed) -#define BOARD_RAMPS4DUE_EFF 3017 // RAMPS4DUE (Power outputs: Hotend, Fan0, Fan1) -#define BOARD_RAMPS4DUE_EEF 3018 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Fan) -#define BOARD_RAMPS4DUE_SF 3019 // RAMPS4DUE (Power outputs: Spindle, Controller Fan) -#define BOARD_RURAMPS4D_11 3020 // RuRAMPS4Duo v1.1 -#define BOARD_RURAMPS4D_13 3021 // RuRAMPS4Duo v1.3 -#define BOARD_ULTRATRONICS_PRO 3022 // ReprapWorld Ultratronics Pro V1.0 -#define BOARD_ARCHIM1 3023 // UltiMachine Archim1 (with DRV8825 drivers) -#define BOARD_ARCHIM2 3024 // UltiMachine Archim2 (with TMC2130 drivers) -#define BOARD_ALLIGATOR 3025 // Alligator Board R2 -#define BOARD_CNCONTROLS_15D 3026 // Cartesio CN Controls V15 on DUE -#define BOARD_KRATOS32 3027 // K.3D Kratos32 (Arduino Due Shield) - -// -// SAM3X8C ARM Cortex M3 -// - -#define BOARD_PRINTRBOARD_G2 3100 // Printrboard G2 -#define BOARD_ADSK 3101 // Arduino DUE Shield Kit (ADSK) - -// -// STM32 ARM Cortex-M3 -// - -#define BOARD_MALYAN_M200_V2 4000 // STM32F070CB controller -#define BOARD_MALYAN_M300 4001 // STM32F070-based delta -#define BOARD_STM32F103RE 4002 // STM32F103RE Libmaple-based STM32F1 controller -#define BOARD_MALYAN_M200 4003 // STM32C8 Libmaple-based STM32F1 controller -#define BOARD_STM3R_MINI 4004 // STM32F103RE Libmaple-based STM32F1 controller -#define BOARD_GTM32_PRO_VB 4005 // STM32F103VE controller -#define BOARD_GTM32_MINI 4006 // STM32F103VE controller -#define BOARD_GTM32_MINI_A30 4007 // STM32F103VE controller -#define BOARD_GTM32_REV_B 4008 // STM32F103VE controller -#define BOARD_MORPHEUS 4009 // STM32F103C8 / STM32F103CB Libmaple-based STM32F1 controller -#define BOARD_CHITU3D 4010 // Chitu3D (STM32F103RE) -#define BOARD_MKS_ROBIN 4011 // MKS Robin (STM32F103ZE) -#define BOARD_MKS_ROBIN_MINI 4012 // MKS Robin Mini (STM32F103VE) -#define BOARD_MKS_ROBIN_NANO 4013 // MKS Robin Nano (STM32F103VE) -#define BOARD_MKS_ROBIN_NANO_V2 4014 // MKS Robin Nano V2 (STM32F103VE) -#define BOARD_MKS_ROBIN_LITE 4015 // MKS Robin Lite/Lite2 (STM32F103RC) -#define BOARD_MKS_ROBIN_LITE3 4016 // MKS Robin Lite3 (STM32F103RC) -#define BOARD_MKS_ROBIN_PRO 4017 // MKS Robin Pro (STM32F103ZE) -#define BOARD_MKS_ROBIN_E3 4018 // MKS Robin E3 (STM32F103RC) -#define BOARD_MKS_ROBIN_E3_V1_1 4019 // MKS Robin E3 V1.1 (STM32F103RC) -#define BOARD_MKS_ROBIN_E3D 4020 // MKS Robin E3D (STM32F103RC) -#define BOARD_MKS_ROBIN_E3D_V1_1 4021 // MKS Robin E3D V1.1 (STM32F103RC) -#define BOARD_MKS_ROBIN_E3P 4022 // MKS Robin E3p (STM32F103VE) -#define BOARD_BTT_SKR_MINI_V1_1 4023 // BigTreeTech SKR Mini v1.1 (STM32F103RC) -#define BOARD_BTT_SKR_MINI_E3_V1_0 4024 // BigTreeTech SKR Mini E3 (STM32F103RC) -#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC) -#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE) -#define BOARD_BTT_SKR_MINI_E3_V3_0 4027 // BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RE) -#define BOARD_BTT_SKR_MINI_MZ_V1_0 4028 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC) -#define BOARD_BTT_SKR_E3_DIP 4029 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE) -#define BOARD_BTT_SKR_CR6 4030 // BigTreeTech SKR CR6 v1.0 (STM32F103RE) -#define BOARD_JGAURORA_A5S_A1 4031 // JGAurora A5S A1 (STM32F103ZE) -#define BOARD_FYSETC_AIO_II 4032 // FYSETC AIO_II (STM32F103RC) -#define BOARD_FYSETC_CHEETAH 4033 // FYSETC Cheetah (STM32F103RC) -#define BOARD_FYSETC_CHEETAH_V12 4034 // FYSETC Cheetah V1.2 (STM32F103RC) -#define BOARD_LONGER3D_LK 4035 // Longer3D LK1/2 - Alfawise U20/U20+/U30 (STM32F103VE) -#define BOARD_CCROBOT_MEEB_3DP 4036 // ccrobot-online.com MEEB_3DP (STM32F103RC) -#define BOARD_CHITU3D_V5 4037 // Chitu3D TronXY X5SA V5 Board (STM32F103ZE) -#define BOARD_CHITU3D_V6 4038 // Chitu3D TronXY X5SA V6 Board (STM32F103ZE) -#define BOARD_CHITU3D_V9 4039 // Chitu3D TronXY X5SA V9 Board (STM32F103ZE) -#define BOARD_CREALITY_V4 4040 // Creality v4.x (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V422 4041 // Creality v4.2.2 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V423 4042 // Creality v4.2.3 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V425 4043 // Creality v4.2.5 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V427 4044 // Creality v4.2.7 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V4210 4045 // Creality v4.2.10 (STM32F103RC / STM32F103RE) as found in the CR-30 -#define BOARD_CREALITY_V431 4046 // Creality v4.3.1 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V431_A 4047 // Creality v4.3.1a (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V431_B 4048 // Creality v4.3.1b (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V431_C 4049 // Creality v4.3.1c (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V431_D 4050 // Creality v4.3.1d (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V452 4051 // Creality v4.5.2 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V453 4052 // Creality v4.5.3 (STM32F103RC / STM32F103RE) -#define BOARD_CREALITY_V24S1 4053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7 -#define BOARD_CREALITY_V24S1_301 4054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1 -#define BOARD_CREALITY_V25S1 4055 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro -#define BOARD_TRIGORILLA_PRO 4056 // Trigorilla Pro (STM32F103ZE) -#define BOARD_FLY_MINI 4057 // FLYmaker FLY MINI (STM32F103RC) -#define BOARD_FLSUN_HISPEED 4058 // FLSUN HiSpeedV1 (STM32F103VE) -#define BOARD_BEAST 4059 // STM32F103RE Libmaple-based controller -#define BOARD_MINGDA_MPX_ARM_MINI 4060 // STM32F103ZE Mingda MD-16 -#define BOARD_GTM32_PRO_VD 4061 // STM32F103VE controller -#define BOARD_ZONESTAR_ZM3E2 4062 // Zonestar ZM3E2 (STM32F103RC) -#define BOARD_ZONESTAR_ZM3E4 4063 // Zonestar ZM3E4 V1 (STM32F103VC) -#define BOARD_ZONESTAR_ZM3E4V2 4064 // Zonestar ZM3E4 V2 (STM32F103VC) -#define BOARD_ERYONE_ERY32_MINI 4065 // Eryone Ery32 mini (STM32F103VE) -#define BOARD_PANDA_PI_V29 4066 // Panda Pi V2.9 - Standalone (STM32F103RC) - -// -// ARM Cortex-M4F -// - -#define BOARD_TEENSY31_32 4100 // Teensy3.1 and Teensy3.2 -#define BOARD_TEENSY35_36 4101 // Teensy3.5 and Teensy3.6 - -// -// STM32 ARM Cortex-M4F -// - -#define BOARD_ARMED 4200 // Arm'ed STM32F4-based controller -#define BOARD_RUMBA32_V1_0 4201 // RUMBA32 STM32F446VE based controller from Aus3D -#define BOARD_RUMBA32_V1_1 4202 // RUMBA32 STM32F446VE based controller from Aus3D -#define BOARD_RUMBA32_MKS 4203 // RUMBA32 STM32F446VE based controller from Makerbase -#define BOARD_RUMBA32_BTT 4204 // RUMBA32 STM32F446VE based controller from BIGTREETECH -#define BOARD_BLACK_STM32F407VE 4205 // BLACK_STM32F407VE -#define BOARD_BLACK_STM32F407ZE 4206 // BLACK_STM32F407ZE -#define BOARD_STEVAL_3DP001V1 4207 // STEVAL-3DP001V1 3D PRINTER BOARD -#define BOARD_BTT_SKR_PRO_V1_1 4208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG) -#define BOARD_BTT_SKR_PRO_V1_2 4209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG) -#define BOARD_BTT_BTT002_V1_0 4210 // BigTreeTech BTT002 v1.0 (STM32F407VG) -#define BOARD_BTT_E3_RRF 4211 // BigTreeTech E3 RRF (STM32F407VG) -#define BOARD_BTT_SKR_V2_0_REV_A 4212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG) -#define BOARD_BTT_SKR_V2_0_REV_B 4213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG) -#define BOARD_BTT_GTR_V1_0 4214 // BigTreeTech GTR v1.0 (STM32F407IGT) -#define BOARD_BTT_OCTOPUS_V1_0 4215 // BigTreeTech Octopus v1.0 (STM32F446ZE) -#define BOARD_BTT_OCTOPUS_V1_1 4216 // BigTreeTech Octopus v1.1 (STM32F446ZE) -#define BOARD_BTT_OCTOPUS_PRO_V1_0 4217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG) -#define BOARD_LERDGE_K 4218 // Lerdge K (STM32F407ZG) -#define BOARD_LERDGE_S 4219 // Lerdge S (STM32F407VE) -#define BOARD_LERDGE_X 4220 // Lerdge X (STM32F407VE) -#define BOARD_VAKE403D 4221 // VAkE 403D (STM32F446VE) -#define BOARD_FYSETC_S6 4222 // FYSETC S6 (STM32F446VE) -#define BOARD_FYSETC_S6_V2_0 4223 // FYSETC S6 v2.0 (STM32F446VE) -#define BOARD_FYSETC_SPIDER 4224 // FYSETC Spider (STM32F446VE) -#define BOARD_FLYF407ZG 4225 // FLYmaker FLYF407ZG (STM32F407ZG) -#define BOARD_MKS_ROBIN2 4226 // MKS_ROBIN2 (STM32F407ZE) -#define BOARD_MKS_ROBIN_PRO_V2 4227 // MKS Robin Pro V2 (STM32F407VE) -#define BOARD_MKS_ROBIN_NANO_V3 4228 // MKS Robin Nano V3 (STM32F407VG) -#define BOARD_MKS_ROBIN_NANO_V3_1 4229 // MKS Robin Nano V3.1 (STM32F407VE) -#define BOARD_MKS_MONSTER8_V1 4230 // MKS Monster8 V1 (STM32F407VE) -#define BOARD_MKS_MONSTER8_V2 4231 // MKS Monster8 V2 (STM32F407VE) -#define BOARD_ANET_ET4 4232 // ANET ET4 V1.x (STM32F407VG) -#define BOARD_ANET_ET4P 4233 // ANET ET4P V1.x (STM32F407VG) -#define BOARD_FYSETC_CHEETAH_V20 4234 // FYSETC Cheetah V2.0 (STM32F401RC) -#define BOARD_TH3D_EZBOARD_V2 4235 // TH3D EZBoard v2.0 (STM32F405RG) -#define BOARD_OPULO_LUMEN_REV3 4236 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG) -#define BOARD_MKS_ROBIN_NANO_V1_3_F4 4237 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE) -#define BOARD_MKS_EAGLE 4238 // MKS Eagle (STM32F407VE) -#define BOARD_ARTILLERY_RUBY 4239 // Artillery Ruby (STM32F401RC) -#define BOARD_FYSETC_SPIDER_V2_2 4240 // FYSETC Spider V2.2 (STM32F446VE) -#define BOARD_CREALITY_V24S1_301F4 4241 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4 - -// -// ARM Cortex M7 -// - -#define BOARD_REMRAM_V1 5000 // RemRam v1 -#define BOARD_TEENSY41 5001 // Teensy 4.1 -#define BOARD_T41U5XBB 5002 // T41U5XBB Teensy 4.1 breakout board -#define BOARD_NUCLEO_F767ZI 5003 // ST NUCLEO-F767ZI Dev Board -#define BOARD_BTT_SKR_SE_BX_V2 5004 // BigTreeTech SKR SE BX V2.0 (STM32H743II) -#define BOARD_BTT_SKR_SE_BX_V3 5005 // BigTreeTech SKR SE BX V3.0 (STM32H743II) -#define BOARD_BTT_SKR_V3_0 5006 // BigTreeTech SKR V3.0 (STM32H743VG) -#define BOARD_BTT_SKR_V3_0_EZ 5007 // BigTreeTech SKR V3.0 EZ (STM32H743VG) - -// -// Espressif ESP32 WiFi -// - -#define BOARD_ESPRESSIF_ESP32 6000 // Generic ESP32 -#define BOARD_MRR_ESPA 6001 // MRR ESPA based on ESP32 (native pins only) -#define BOARD_MRR_ESPE 6002 // MRR ESPE based on ESP32 (with I2S stepper stream) -#define BOARD_E4D_BOX 6003 // E4d@BOX -#define BOARD_RESP32_CUSTOM 6004 // Rutilea ESP32 custom board -#define BOARD_FYSETC_E4 6005 // FYSETC E4 -#define BOARD_PANDA_ZHU 6006 // Panda_ZHU -#define BOARD_PANDA_M4 6007 // Panda_M4 -#define BOARD_MKS_TINYBEE 6008 // MKS TinyBee based on ESP32 (with I2S stepper stream) -#define BOARD_ENWI_ESPNP 6009 // enwi ESPNP based on ESP32 (with I2S stepper stream) - -// -// SAMD51 ARM Cortex M4 -// - -#define BOARD_AGCM4_RAMPS_144 6100 // RAMPS 1.4.4 -#define BOARD_BRICOLEMON_V1_0 6101 // Bricolemon -#define BOARD_BRICOLEMON_LITE_V1_0 6102 // Bricolemon Lite - -// -// Custom board -// - -#define BOARD_CUSTOM 9998 // Custom pins definition for development and/or rare boards - -// -// Simulations -// - -#define BOARD_LINUX_RAMPS 9999 - -#define _MB_1(B) (defined(BOARD_##B) && MOTHERBOARD==BOARD_##B) -#define MB(V...) DO(MB,||,V) diff --git a/src/core/bug_on.h b/src/core/bug_on.h deleted file mode 100644 index 7f1243e..0000000 --- a/src/core/bug_on.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Copyright (c) 2021 X-Ryl669 [https://blog.cyril.by] - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// We need SERIAL_ECHOPGM and macros.h -#include "serial.h" - -#if ENABLED(POSTMORTEM_DEBUGGING) - // Useful macro for stopping the CPU on an unexpected condition - // This is used like SERIAL_ECHOPGM, that is: a key-value call of the local variables you want - // to dump to the serial port before stopping the CPU. - // \/ Don't replace by SERIAL_ECHOPGM since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building - #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": "); SERIAL_ECHOLNPGM(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0) -#elif ENABLED(MARLIN_DEV_MODE) - // Don't stop the CPU here, but at least dump the bug on the serial port - // \/ Don't replace by SERIAL_ECHOPGM since ONLY_FILENAME cannot be transformed to a PGM string on Arduino and it breaks building - #define BUG_ON(V...) do { SERIAL_ECHO(ONLY_FILENAME); SERIAL_ECHO(__LINE__); SERIAL_ECHOLNPGM(": BUG!"); SERIAL_ECHOLNPGM(V); SERIAL_FLUSHTX(); } while(0) -#else - // Release mode, let's ignore the bug - #define BUG_ON(V...) NOOP -#endif diff --git a/src/core/debug_out.h b/src/core/debug_out.h deleted file mode 100644 index eb1c91e..0000000 --- a/src/core/debug_out.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// -// Serial aliases for debugging. -// Include this header after defining DEBUG_OUT -// (or not) in a given .cpp file -// - -#undef DEBUG_SECTION -#undef DEBUG_ECHO_START -#undef DEBUG_ERROR_START -#undef DEBUG_CHAR -#undef DEBUG_ECHO -#undef DEBUG_DECIMAL -#undef DEBUG_ECHO_F -#undef DEBUG_ECHOLN -#undef DEBUG_ECHOPGM -#undef DEBUG_ECHOLNPGM -#undef DEBUG_ECHOF -#undef DEBUG_ECHOLNF -#undef DEBUG_ECHOPGM_P -#undef DEBUG_ECHOLNPGM_P -#undef DEBUG_ECHOPAIR_F -#undef DEBUG_ECHOPAIR_F_P -#undef DEBUG_ECHOLNPAIR_F -#undef DEBUG_ECHOLNPAIR_F_P -#undef DEBUG_ECHO_MSG -#undef DEBUG_ERROR_MSG -#undef DEBUG_EOL -#undef DEBUG_FLUSH -#undef DEBUG_POS -#undef DEBUG_XYZ -#undef DEBUG_DELAY -#undef DEBUG_SYNCHRONIZE - -#if DEBUG_OUT - - #include "debug_section.h" - #define DEBUG_SECTION(N,S,D) SectionLog N(F(S),D) - - #define DEBUG_ECHO_START SERIAL_ECHO_START - #define DEBUG_ERROR_START SERIAL_ERROR_START - #define DEBUG_CHAR SERIAL_CHAR - #define DEBUG_ECHO SERIAL_ECHO - #define DEBUG_DECIMAL SERIAL_DECIMAL - #define DEBUG_ECHO_F SERIAL_ECHO_F - #define DEBUG_ECHOLN SERIAL_ECHOLN - #define DEBUG_ECHOPGM SERIAL_ECHOPGM - #define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM - #define DEBUG_ECHOF SERIAL_ECHOF - #define DEBUG_ECHOLNF SERIAL_ECHOLNF - #define DEBUG_ECHOPGM SERIAL_ECHOPGM - #define DEBUG_ECHOPGM_P SERIAL_ECHOPGM_P - #define DEBUG_ECHOPAIR_F SERIAL_ECHOPAIR_F - #define DEBUG_ECHOPAIR_F_P SERIAL_ECHOPAIR_F_P - #define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM - #define DEBUG_ECHOLNPGM_P SERIAL_ECHOLNPGM_P - #define DEBUG_ECHOLNPAIR_F SERIAL_ECHOLNPAIR_F - #define DEBUG_ECHOLNPAIR_F_P SERIAL_ECHOLNPAIR_F_P - #define DEBUG_ECHO_MSG SERIAL_ECHO_MSG - #define DEBUG_ERROR_MSG SERIAL_ERROR_MSG - #define DEBUG_EOL SERIAL_EOL - #define DEBUG_FLUSH SERIAL_FLUSH - #define DEBUG_POS SERIAL_POS - #define DEBUG_XYZ SERIAL_XYZ - #define DEBUG_DELAY(ms) serial_delay(ms) - #define DEBUG_SYNCHRONIZE() planner.synchronize() - -#else - - #define DEBUG_SECTION(...) NOOP - #define DEBUG_ECHO_START() NOOP - #define DEBUG_ERROR_START() NOOP - #define DEBUG_CHAR(...) NOOP - #define DEBUG_ECHO(...) NOOP - #define DEBUG_DECIMAL(...) NOOP - #define DEBUG_ECHO_F(...) NOOP - #define DEBUG_ECHOLN(...) NOOP - #define DEBUG_ECHOPGM(...) NOOP - #define DEBUG_ECHOLNPGM(...) NOOP - #define DEBUG_ECHOF(...) NOOP - #define DEBUG_ECHOLNF(...) NOOP - #define DEBUG_ECHOPGM_P(...) NOOP - #define DEBUG_ECHOLNPGM_P(...) NOOP - #define DEBUG_ECHOPAIR_F(...) NOOP - #define DEBUG_ECHOPAIR_F_P(...) NOOP - #define DEBUG_ECHOLNPAIR_F(...) NOOP - #define DEBUG_ECHOLNPAIR_F_P(...) NOOP - #define DEBUG_ECHO_MSG(...) NOOP - #define DEBUG_ERROR_MSG(...) NOOP - #define DEBUG_EOL() NOOP - #define DEBUG_FLUSH() NOOP - #define DEBUG_POS(...) NOOP - #define DEBUG_XYZ(...) NOOP - #define DEBUG_DELAY(...) NOOP - #define DEBUG_SYNCHRONIZE() NOOP - -#endif - -#undef DEBUG_OUT diff --git a/src/core/debug_section.h b/src/core/debug_section.h deleted file mode 100644 index 6e23d9e..0000000 --- a/src/core/debug_section.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "serial.h" -#include "../module/motion.h" - -class SectionLog { -public: - SectionLog(FSTR_P const fmsg=nullptr, bool inbug=true) { - the_msg = fmsg; - if ((debug = inbug)) echo_msg(F(">>>")); - } - - ~SectionLog() { if (debug) echo_msg(F("<<<")); } - -private: - FSTR_P the_msg; - bool debug; - - void echo_msg(FSTR_P const fpre) { - SERIAL_ECHOF(fpre); - if (the_msg) { - SERIAL_CHAR(' '); - SERIAL_ECHOF(the_msg); - } - SERIAL_CHAR(' '); - print_pos(current_position); - } -}; diff --git a/src/core/drivers.h b/src/core/drivers.h deleted file mode 100644 index f6a8f0f..0000000 --- a/src/core/drivers.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// -// Included by MarlinConfigPre.h ahead of Configuration_adv.h. -// Don't use #if in this file for anything not defined early! -// - -#define _A4988 0x4988 -#define _A5984 0x5984 -#define _DRV8825 0x8825 -#define _LV8729 0x8729 -#define _L6470 0x6470 -#define _L6474 0x6474 -#define _L6480 0x6480 -#define _POWERSTEP01 0xF00D -#define _TB6560 0x6560 -#define _TB6600 0x6600 -#define _TMC2100 0x2100 -#define _TMC2130 0x2130A -#define _TMC2130_STANDALONE 0x2130B -#define _TMC2160 0x2160A -#define _TMC2160_STANDALONE 0x2160B -#define _TMC2208 0x2208A -#define _TMC2208_STANDALONE 0x2208B -#define _TMC2209 0x2209A -#define _TMC2209_STANDALONE 0x2209B -#define _TMC26X 0x2600A -#define _TMC26X_STANDALONE 0x2600B -#define _TMC2660 0x2660A -#define _TMC2660_STANDALONE 0x2660B -#define _TMC5130 0x5130A -#define _TMC5130_STANDALONE 0x5130B -#define _TMC5160 0x5160A -#define _TMC5160_STANDALONE 0x5160B - -#define _DRIVER_ID(V) _CAT(_, V) -#define _AXIS_DRIVER_TYPE(A,T) (_DRIVER_ID(A##_DRIVER_TYPE) == _DRIVER_ID(T)) - -#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T) -#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T) -#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T) -#define AXIS_DRIVER_TYPE_I(T) _AXIS_DRIVER_TYPE(I,T) -#define AXIS_DRIVER_TYPE_J(T) _AXIS_DRIVER_TYPE(J,T) -#define AXIS_DRIVER_TYPE_K(T) _AXIS_DRIVER_TYPE(K,T) - -#define AXIS_DRIVER_TYPE_X2(T) (HAS_X2_STEPPER && _AXIS_DRIVER_TYPE(X2,T)) -#define AXIS_DRIVER_TYPE_Y2(T) (HAS_DUAL_Y_STEPPERS && _AXIS_DRIVER_TYPE(Y2,T)) -#define AXIS_DRIVER_TYPE_Z2(T) (NUM_Z_STEPPERS >= 2 && _AXIS_DRIVER_TYPE(Z2,T)) -#define AXIS_DRIVER_TYPE_Z3(T) (NUM_Z_STEPPERS >= 3 && _AXIS_DRIVER_TYPE(Z3,T)) -#define AXIS_DRIVER_TYPE_Z4(T) (NUM_Z_STEPPERS >= 4 && _AXIS_DRIVER_TYPE(Z4,T)) - -#define AXIS_DRIVER_TYPE_E(N,T) (E_STEPPERS > N && _AXIS_DRIVER_TYPE(E##N,T)) -#define AXIS_DRIVER_TYPE_E0(T) AXIS_DRIVER_TYPE_E(0,T) -#define AXIS_DRIVER_TYPE_E1(T) AXIS_DRIVER_TYPE_E(1,T) -#define AXIS_DRIVER_TYPE_E2(T) AXIS_DRIVER_TYPE_E(2,T) -#define AXIS_DRIVER_TYPE_E3(T) AXIS_DRIVER_TYPE_E(3,T) -#define AXIS_DRIVER_TYPE_E4(T) AXIS_DRIVER_TYPE_E(4,T) -#define AXIS_DRIVER_TYPE_E5(T) AXIS_DRIVER_TYPE_E(5,T) -#define AXIS_DRIVER_TYPE_E6(T) AXIS_DRIVER_TYPE_E(6,T) -#define AXIS_DRIVER_TYPE_E7(T) AXIS_DRIVER_TYPE_E(7,T) - -#define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T) - -#define _OR_ADTE(N,T) || AXIS_DRIVER_TYPE_E(N,T) -#define HAS_E_DRIVER(T) (0 RREPEAT2(E_STEPPERS, _OR_ADTE, T)) - -#define HAS_DRIVER(T) ( AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Z(T) \ - || AXIS_DRIVER_TYPE_I(T) || AXIS_DRIVER_TYPE_J(T) || AXIS_DRIVER_TYPE_K(T) \ - || AXIS_DRIVER_TYPE_X2(T) || AXIS_DRIVER_TYPE_Y2(T) || AXIS_DRIVER_TYPE_Z2(T) \ - || AXIS_DRIVER_TYPE_Z3(T) || AXIS_DRIVER_TYPE_Z4(T) || HAS_E_DRIVER(T) ) - -// -// Trinamic Stepper Drivers -// - -// Test for supported TMC drivers that require advanced configuration -// Does not match standalone configurations -#if ( HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) \ - || HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) \ - || HAS_DRIVER(TMC2660) \ - || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160) ) - #define HAS_TRINAMIC_CONFIG 1 -#endif - -#define HAS_TRINAMIC HAS_TRINAMIC_CONFIG - -#if ( HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE) \ - || HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) \ - || HAS_DRIVER(TMC26X_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) \ - || HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) ) - #define HAS_TRINAMIC_STANDALONE 1 -#endif - -#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5130) || HAS_DRIVER(TMC5160) - #define HAS_TMCX1X0 1 -#endif - -#if HAS_DRIVER(TMC2208) || HAS_DRIVER(TMC2209) - #define HAS_TMC220x 1 -#endif - -#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) - -// Test for a driver that uses SPI - this allows checking whether a _CS_ pin -// is considered sensitive -#define AXIS_HAS_SPI(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC26X) || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) - -#define AXIS_HAS_UART(A) ( AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) ) - -#define AXIS_HAS_RXTX AXIS_HAS_UART - -#define AXIS_HAS_HW_SERIAL(A) ( AXIS_HAS_UART(A) && defined(A##_HARDWARE_SERIAL) ) -#define AXIS_HAS_SW_SERIAL(A) ( AXIS_HAS_UART(A) && !defined(A##_HARDWARE_SERIAL) ) - -#define AXIS_HAS_STALLGUARD(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC2660) \ - || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) - -#define AXIS_HAS_STEALTHCHOP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) - -#define AXIS_HAS_SG_RESULT(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ - || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) ) - -#define AXIS_HAS_COOLSTEP(A) ( AXIS_DRIVER_TYPE(A,TMC2130) \ - || AXIS_DRIVER_TYPE(A,TMC2209) \ - || AXIS_DRIVER_TYPE(A,TMC5130) || AXIS_DRIVER_TYPE(A,TMC5160) ) - -#define _OR_EAH(N,T) || AXIS_HAS_##T(E##N) -#define E_AXIS_HAS(T) (0 _OR_EAH(0,T) _OR_EAH(1,T) _OR_EAH(2,T) _OR_EAH(3,T) _OR_EAH(4,T) _OR_EAH(5,T) _OR_EAH(6,T) _OR_EAH(7,T)) - -#define ANY_AXIS_HAS(T) ( AXIS_HAS_##T(X) || AXIS_HAS_##T(X2) \ - || AXIS_HAS_##T(Y) || AXIS_HAS_##T(Y2) \ - || AXIS_HAS_##T(Z) || AXIS_HAS_##T(Z2) || AXIS_HAS_##T(Z3) || AXIS_HAS_##T(Z4) \ - || AXIS_HAS_##T(I) || AXIS_HAS_##T(J) || AXIS_HAS_##T(K) \ - || E_AXIS_HAS(T) ) - -#if ANY_AXIS_HAS(STEALTHCHOP) - #define HAS_STEALTHCHOP 1 -#endif -#if ANY_AXIS_HAS(STALLGUARD) - #define HAS_STALLGUARD 1 -#endif -#if ANY_AXIS_HAS(SG_RESULT) - #define HAS_SG_RESULT 1 -#endif -#if ANY_AXIS_HAS(COOLSTEP) - #define HAS_COOLSTEP 1 -#endif -#if ANY_AXIS_HAS(RXTX) - #define HAS_TMC_UART 1 -#endif -#if ANY_AXIS_HAS(SPI) - #define HAS_TMC_SPI 1 -#endif - -// -// TMC26XX Stepper Drivers -// -#if HAS_DRIVER(TMC26X) - #define HAS_TMC26X 1 -#endif - -// -// L64XX Stepper Drivers -// - -#if HAS_DRIVER(L6470) || HAS_DRIVER(L6474) || HAS_DRIVER(L6480) || HAS_DRIVER(POWERSTEP01) - #define HAS_L64XX 1 -#endif -#if HAS_L64XX && !HAS_DRIVER(L6474) - #define HAS_L64XX_NOT_L6474 1 -#endif - -#define AXIS_IS_L64XX(A) (AXIS_DRIVER_TYPE_##A(L6470) || AXIS_DRIVER_TYPE_##A(L6474) || AXIS_DRIVER_TYPE_##A(L6480) || AXIS_DRIVER_TYPE_##A(POWERSTEP01)) diff --git a/src/core/language.h b/src/core/language.h deleted file mode 100644 index f225f91..0000000 --- a/src/core/language.h +++ /dev/null @@ -1,564 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#define _UxGT(a) a - -// 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" / "ULTRA_LCD" / "SDSUPPORT" #define IN "Configuration.h" -// ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS -// See also https://marlinfw.org/docs/development/lcd_language.html - -// Languages -// an Aragonese -// bg Bulgarian -// ca Catalan -// cz Czech -// da Danish -// de German -// el Greek (Greece) -// el_CY Greek (Cyprus) -// en English -// es Spanish -// eu Basque-Euskera -// fi Finnish -// fr French -// gl Galician -// hr Croatian -// hu Hungarian -// it Italian -// jp_kana Japanese -// ko_KR Korean (South Korea) -// nl Dutch -// pl Polish -// pt Portuguese -// pt_br Portuguese (Brazilian) -// ro Romanian -// ru Russian -// sk Slovak -// sv Swedish -// tr Turkish -// uk Ukrainian -// vi Vietnamese -// zh_CN Chinese (Simplified) -// zh_TW Chinese (Traditional) - -#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 -#elif defined(DEFAULT_MACHINE_NAME) - #undef MACHINE_NAME - #define MACHINE_NAME DEFAULT_MACHINE_NAME -#endif - -#ifndef MACHINE_UUID - #define MACHINE_UUID DEFAULT_MACHINE_UUID -#endif - -#define MARLIN_WEBSITE_URL "marlinfw.org" - -//#if !defined(STRING_SPLASH_LINE3) && defined(WEBSITE_URL) -// #define STRING_SPLASH_LINE3 WEBSITE_URL -//#endif - -// -// Common Serial Console Messages -// Don't change these strings because serial hosts look for them. -// - -#define STR_ENQUEUEING "enqueueing \"" -#define STR_POWERUP "PowerUp" -#define STR_POWEROFF "PowerOff" -#define STR_EXTERNAL_RESET " External Reset" -#define STR_BROWNOUT_RESET " Brown out Reset" -#define STR_WATCHDOG_RESET " Watchdog Reset" -#define STR_SOFTWARE_RESET " Software Reset" -#define STR_FREE_MEMORY " Free Memory: " -#define STR_PLANNER_BUFFER_BYTES " PlannerBufferBytes: " -#define STR_OK "ok" -#define STR_WAIT "wait" -#define STR_STATS "Stats: " -#define STR_FILE_SAVED "Done saving file." -#define STR_ERR_LINE_NO "Line Number is not Last Line Number+1, Last Line: " -#define STR_ERR_CHECKSUM_MISMATCH "checksum mismatch, Last Line: " -#define STR_ERR_NO_CHECKSUM "No Checksum with line number, Last Line: " -#define STR_FILE_PRINTED "Done printing file" -#define STR_NO_MEDIA "No media" -#define STR_BEGIN_FILE_LIST "Begin file list" -#define STR_END_FILE_LIST "End file list" -#define STR_INVALID_EXTRUDER "Invalid extruder" -#define STR_INVALID_E_STEPPER "Invalid E stepper" -#define STR_E_STEPPER_NOT_SPECIFIED "E stepper not specified" -#define STR_INVALID_SOLENOID "Invalid solenoid" -#define STR_COUNT_X " Count X:" -#define STR_COUNT_A " Count A:" -#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required." -#define STR_ERR_KILLED "Printer halted. kill() called!" -#define STR_FLOWMETER_FAULT "Coolant flow fault. Flowmeter safety is active. Attention required." -#define STR_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)" -#define STR_ERR_SERIAL_MISMATCH "Serial status mismatch" -#define STR_BUSY_PROCESSING "busy: processing" -#define STR_BUSY_PAUSED_FOR_USER "busy: paused for user" -#define STR_BUSY_PAUSED_FOR_INPUT "busy: paused for input" -#define STR_Z_MOVE_COMP "Z_move_comp" -#define STR_RESEND "Resend: " -#define STR_UNKNOWN_COMMAND "Unknown command: \"" -#define STR_ACTIVE_EXTRUDER "Active Extruder: " -#define STR_ERR_FANSPEED "Fan speed E" - -#define STR_PROBE_OFFSET "Probe Offset" -#define STR_SKEW_MIN "min_skew_factor: " -#define STR_SKEW_MAX "max_skew_factor: " -#define STR_ERR_MATERIAL_INDEX "M145 S out of range (0-1)" -#define STR_ERR_M421_PARAMETERS "M421 incorrect parameter usage" -#define STR_ERR_BAD_PLANE_MODE "G5 requires XY plane mode" -#define STR_ERR_MESH_XY "Mesh point out of range" -#define STR_ERR_ARC_ARGS "G2/G3 bad parameters" -#define STR_ERR_PROTECTED_PIN "Protected Pin" -#define STR_ERR_M420_FAILED "Failed to enable Bed Leveling" -#define STR_ERR_M428_TOO_FAR "Too far from reference point" -#define STR_ERR_M303_DISABLED "PIDTEMP disabled" -#define STR_M119_REPORT "Reporting endstop status" -#define STR_ON "ON" -#define STR_OFF "OFF" -#define STR_ENDSTOP_HIT "TRIGGERED" -#define STR_ENDSTOP_OPEN "open" -#define STR_DUPLICATION_MODE "Duplication mode: " -#define STR_SOFT_MIN " Min: " -#define STR_SOFT_MAX " Max: " - -#define STR_SAVED_POS "Position saved" -#define STR_RESTORING_POS "Restoring position" -#define STR_INVALID_POS_SLOT "Invalid slot. Total: " -#define STR_DONE "Done." - -#define STR_SD_CANT_OPEN_SUBDIR "Cannot open subdir " -#define STR_SD_INIT_FAIL "No SD card" -#define STR_SD_VOL_INIT_FAIL "volume.init failed" -#define STR_SD_OPENROOT_FAIL "openRoot failed" -#define STR_SD_CARD_OK "SD card ok" -#define STR_SD_WORKDIR_FAIL "workDir open failed" -#define STR_SD_OPEN_FILE_FAIL "open failed, File: " -#define STR_SD_FILE_OPENED "File opened: " -#define STR_SD_SIZE " Size: " -#define STR_SD_FILE_SELECTED "File selected" -#define STR_SD_WRITE_TO_FILE "Writing to file: " -#define STR_SD_PRINTING_BYTE "SD printing byte " -#define STR_SD_NOT_PRINTING "Not SD printing" -#define STR_SD_ERR_WRITE_TO_FILE "error writing to file" -#define STR_SD_ERR_READ "SD read error" -#define STR_SD_CANT_ENTER_SUBDIR "Cannot enter subdir: " - -#define STR_ENDSTOPS_HIT "endstops hit: " -#define STR_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented" -#define STR_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented" -#define STR_ERR_HOTEND_TOO_COLD "Hotend too cold" -#define STR_ERR_EEPROM_WRITE "Error writing to EEPROM!" - -#define STR_FILAMENT_CHANGE_HEAT_LCD "Press button to heat nozzle" -#define STR_FILAMENT_CHANGE_INSERT_LCD "Insert filament and press button" -#define STR_FILAMENT_CHANGE_WAIT_LCD "Press button to resume" -#define STR_FILAMENT_CHANGE_HEAT_M108 "Send M108 to heat nozzle" -#define STR_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108" -#define STR_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume" - -#define STR_STOP_PRE "!! STOP called because of " -#define STR_STOP_POST " error - restart with M999" -#define STR_STOP_BLTOUCH "BLTouch" -#define STR_STOP_UNHOMED "unhomed" -#define STR_KILL_PRE "!! KILL caused by " -#define STR_KILL_INACTIVE_TIME "too much inactive time - current command: " -#define STR_KILL_BUTTON "KILL button/pin" - -// temperature.cpp strings -#define STR_PID_AUTOTUNE "PID Autotune" -#define STR_PID_AUTOTUNE_START " start" -#define STR_PID_BAD_HEATER_ID " failed! Bad heater id" -#define STR_PID_TEMP_TOO_HIGH " failed! Temperature too high" -#define STR_PID_TIMEOUT " failed! timeout" -#define STR_BIAS " bias: " -#define STR_D_COLON " d: " -#define STR_T_MIN " min: " -#define STR_T_MAX " max: " -#define STR_KU " Ku: " -#define STR_TU " Tu: " -#define STR_CLASSIC_PID " Classic PID " -#define STR_KP " Kp: " -#define STR_KI " Ki: " -#define STR_KD " Kd: " -#define STR_PID_AUTOTUNE_FINISHED " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h" -#define STR_PID_DEBUG " PID_DEBUG " -#define STR_PID_DEBUG_INPUT ": Input " -#define STR_PID_DEBUG_OUTPUT " Output " -#define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !" -#define STR_MPC_AUTOTUNE "MPC Autotune" -#define STR_MPC_AUTOTUNE_START " start for " STR_E -#define STR_MPC_AUTOTUNE_INTERRUPTED " interrupted!" -#define STR_MPC_AUTOTUNE_FINISHED " finished! Put the constants below into Configuration.h" -#define STR_MPC_COOLING_TO_AMBIENT "Cooling to ambient" -#define STR_MPC_HEATING_PAST_200 "Heating to over 200C" -#define STR_MPC_MEASURING_AMBIENT "Measuring ambient heatloss at " -#define STR_MPC_TEMPERATURE_ERROR "Temperature error" - -#define STR_HEATER_BED "bed" -#define STR_HEATER_CHAMBER "chamber" -#define STR_COOLER "cooler" -#define STR_MOTHERBOARD "motherboard" -#define STR_PROBE "probe" -#define STR_REDUNDANT "redundant " -#define STR_LASER_TEMP "laser temperature" - -#define STR_STOPPED_HEATER ", system stopped! Heater_ID: " -#define STR_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !" -#define STR_T_HEATING_FAILED "Heating failed" -#define STR_T_THERMAL_RUNAWAY "Thermal Runaway" -#define STR_T_MALFUNCTION "Thermal Malfunction" -#define STR_T_MAXTEMP "MAXTEMP triggered" -#define STR_T_MINTEMP "MINTEMP triggered" -#define STR_ERR_PROBING_FAILED "Probing Failed" -#define STR_ZPROBE_OUT_SER "Z Probe Past Bed" - -// Debug -#define STR_DEBUG_PREFIX "DEBUG:" -#define STR_DEBUG_OFF "off" -#define STR_DEBUG_ECHO "ECHO" -#define STR_DEBUG_INFO "INFO" -#define STR_DEBUG_ERRORS "ERRORS" -#define STR_DEBUG_DRYRUN "DRYRUN" -#define STR_DEBUG_COMMUNICATION "COMMUNICATION" -#define STR_DEBUG_DETAIL "DETAIL" - -#define STR_PRINTER_LOCKED "Printer locked! (Unlock with M511 or LCD)" -#define STR_WRONG_PASSWORD "Incorrect Password" -#define STR_PASSWORD_TOO_LONG "Password too long" -#define STR_PASSWORD_REMOVED "Password removed" -#define STR_REMINDER_SAVE_SETTINGS "Remember to save!" -#define STR_PASSWORD_SET "Password is " - -// Settings Report Strings -#define STR_Z_AUTO_ALIGN "Z Auto-Align" -#define STR_BACKLASH_COMPENSATION "Backlash compensation" -#define STR_S_SEG_PER_SEC "S" -#define STR_DELTA_SETTINGS "Delta (L R H S XYZ ABC)" -#define STR_SCARA_SETTINGS "SCARA" -#define STR_POLARGRAPH_SETTINGS "Polargraph" -#define STR_SCARA_P_T_Z "P T Z" -#define STR_ENDSTOP_ADJUSTMENT "Endstop adjustment" -#define STR_SKEW_FACTOR "Skew Factor" -#define STR_FILAMENT_SETTINGS "Filament settings" -#define STR_MAX_ACCELERATION "Max Acceleration (units/s2)" -#define STR_MAX_FEEDRATES "Max feedrates (units/s)" -#define STR_ACCELERATION_P_R_T "Acceleration (units/s2) (P R T)" -#define STR_TOOL_CHANGING "Tool-changing" -#define STR_HOTEND_OFFSETS "Hotend offsets" -#define STR_SERVO_ANGLES "Servo Angles" -#define STR_HOTEND_PID "Hotend PID" -#define STR_BED_PID "Bed PID" -#define STR_CHAMBER_PID "Chamber PID" -#define STR_STEPS_PER_UNIT "Steps per unit" -#define STR_LINEAR_ADVANCE "Linear Advance" -#define STR_CONTROLLER_FAN "Controller Fan" -#define STR_STEPPER_MOTOR_CURRENTS "Stepper motor currents" -#define STR_RETRACT_S_F_Z "Retract (S F Z)" -#define STR_RECOVER_S_F "Recover (S F)" -#define STR_AUTO_RETRACT_S "Auto-Retract (S)" -#define STR_FILAMENT_LOAD_UNLOAD "Filament load/unload" -#define STR_POWER_LOSS_RECOVERY "Power-loss recovery" -#define STR_FILAMENT_RUNOUT_SENSOR "Filament runout sensor" -#define STR_DRIVER_STEPPING_MODE "Driver stepping mode" -#define STR_STEPPER_DRIVER_CURRENT "Stepper driver current" -#define STR_HYBRID_THRESHOLD "Hybrid Threshold" -#define STR_STALLGUARD_THRESHOLD "StallGuard threshold" -#define STR_HOME_OFFSET "Home offset" -#define STR_SOFT_ENDSTOPS "Soft endstops" -#define STR_MATERIAL_HEATUP "Material heatup parameters" -#define STR_LCD_CONTRAST "LCD Contrast" -#define STR_LCD_BRIGHTNESS "LCD Brightness" -#define STR_DISPLAY_SLEEP "Display Sleep" -#define STR_UI_LANGUAGE "UI Language" -#define STR_Z_PROBE_OFFSET "Z-Probe Offset" -#define STR_TEMPERATURE_UNITS "Temperature Units" -#define STR_USER_THERMISTORS "User thermistors" -#define STR_DELAYED_POWEROFF "Delayed poweroff" - -// -// Endstop Names used by Endstops::report_states -// -#define STR_X_MIN "x_min" -#define STR_X_MAX "x_max" -#define STR_X2_MIN "x2_min" -#define STR_X2_MAX "x2_max" - -#if HAS_Y_AXIS - #define STR_Y_MIN "y_min" - #define STR_Y_MAX "y_max" - #define STR_Y2_MIN "y2_min" - #define STR_Y2_MAX "y2_max" -#endif - -#if HAS_Z_AXIS - #define STR_Z_MIN "z_min" - #define STR_Z_MAX "z_max" - #define STR_Z2_MIN "z2_min" - #define STR_Z2_MAX "z2_max" - #define STR_Z3_MIN "z3_min" - #define STR_Z3_MAX "z3_max" - #define STR_Z4_MIN "z4_min" - #define STR_Z4_MAX "z4_max" -#endif - -#define STR_Z_PROBE "z_probe" -#define STR_PROBE_EN "probe_en" -#define STR_FILAMENT "filament" - -// General axis names -#define STR_X "X" -#define STR_Y "Y" -#define STR_Z "Z" -#define STR_E "E" -#if IS_KINEMATIC - #define STR_A "A" - #define STR_B "B" - #define STR_C "C" -#else - #define STR_A "X" - #define STR_B "Y" - #define STR_C "Z" -#endif -#define STR_X2 "X2" -#define STR_Y2 "Y2" -#define STR_Z2 "Z2" -#define STR_Z3 "Z3" -#define STR_Z4 "Z4" - -// Extra Axis and Endstop Names -#if HAS_I_AXIS - #if AXIS4_NAME == 'A' - #define STR_I "A" - #define STR_I_MIN "a_min" - #define STR_I_MAX "a_max" - #elif AXIS4_NAME == 'B' - #define STR_I "B" - #define STR_I_MIN "b_min" - #define STR_I_MAX "b_max" - #elif AXIS4_NAME == 'C' - #define STR_I "C" - #define STR_I_MIN "c_min" - #define STR_I_MAX "c_max" - #elif AXIS4_NAME == 'U' - #define STR_I "U" - #define STR_I_MIN "u_min" - #define STR_I_MAX "u_max" - #elif AXIS4_NAME == 'V' - #define STR_I "V" - #define STR_I_MIN "v_min" - #define STR_I_MAX "v_max" - #elif AXIS4_NAME == 'W' - #define STR_I "W" - #define STR_I_MIN "w_min" - #define STR_I_MAX "w_max" - #else - #error "AXIS4_NAME can only be one of 'A', 'B', 'C', 'U', 'V', or 'W'." - #endif -#else - #define STR_I "" -#endif - -#if HAS_J_AXIS - #if AXIS5_NAME == 'B' - #define STR_J "B" - #define STR_J_MIN "b_min" - #define STR_J_MAX "b_max" - #elif AXIS5_NAME == 'C' - #define STR_J "C" - #define STR_J_MIN "c_min" - #define STR_J_MAX "c_max" - #elif AXIS5_NAME == 'U' - #define STR_J "U" - #define STR_J_MIN "u_min" - #define STR_J_MAX "u_max" - #elif AXIS5_NAME == 'V' - #define STR_J "V" - #define STR_J_MIN "v_min" - #define STR_J_MAX "v_max" - #elif AXIS5_NAME == 'W' - #define STR_J "W" - #define STR_J_MIN "w_min" - #define STR_J_MAX "w_max" - #else - #error "AXIS5_NAME can only be one of 'B', 'C', 'U', 'V', or 'W'." - #endif -#else - #define STR_J "" -#endif - -#if HAS_K_AXIS - #if AXIS6_NAME == 'C' - #define STR_K "C" - #define STR_K_MIN "c_min" - #define STR_K_MAX "c_max" - #elif AXIS6_NAME == 'U' - #define STR_K "U" - #define STR_K_MIN "u_min" - #define STR_K_MAX "u_max" - #elif AXIS6_NAME == 'V' - #define STR_K "V" - #define STR_K_MIN "v_min" - #define STR_K_MAX "v_max" - #elif AXIS6_NAME == 'W' - #define STR_K "W" - #define STR_K_MIN "w_min" - #define STR_K_MAX "w_max" - #else - #error "AXIS6_NAME can only be one of 'C', 'U', 'V', or 'W'." - #endif -#else - #define STR_K "" -#endif - -#if EITHER(HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL) - - // Custom characters defined in the first 8 characters of the LCD - #define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string! - #define LCD_STR_DEGREE "\x01" - #define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation - #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 */ - -#else - // - // Custom characters from Marlin_symbols.fon which was merged into ISO10646-0-3.bdf - // \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" - -#endif - -/** - * Tool indexes for LCD display only - * - * By convention the LCD shows "E1" for the first extruder. - * However, internal to Marlin E0/T0 is the first tool, and - * most board silkscreens say "E0." Zero-based labels will - * make these indexes consistent but this defies expectation. - */ -#if ENABLED(NUMBER_TOOLS_FROM_0) - #define LCD_FIRST_TOOL 0 - #define STR_N0 "0" - #define STR_N1 "1" - #define STR_N2 "2" - #define STR_N3 "3" - #define STR_N4 "4" - #define STR_N5 "5" - #define STR_N6 "6" - #define STR_N7 "7" -#else - #define LCD_FIRST_TOOL 1 - #define STR_N0 "1" - #define STR_N1 "2" - #define STR_N2 "3" - #define STR_N3 "4" - #define STR_N4 "5" - #define STR_N5 "6" - #define STR_N6 "7" - #define STR_N7 "8" -#endif - -#define STR_E0 STR_E STR_N0 -#define STR_E1 STR_E STR_N1 -#define STR_E2 STR_E STR_N2 -#define STR_E3 STR_E STR_N3 -#define STR_E4 STR_E STR_N4 -#define STR_E5 STR_E STR_N5 -#define STR_E6 STR_E STR_N6 -#define STR_E7 STR_E STR_N7 - -// Include localized LCD Menu Messages - -#define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h) -#define LANGUAGE_DATA_INCL(M) LANGUAGE_DATA_INCL_(M) - -#define LANGUAGE_INCL_(M) STRINGIFY_(../lcd/language/language_##M.h) -#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M) - -// Use superscripts, if possible. Evaluated at point of use. -#define SUPERSCRIPT_TWO TERN(NOT_EXTENDED_ISO10646_1_5X7, "^2", "²") -#define SUPERSCRIPT_THREE TERN(NOT_EXTENDED_ISO10646_1_5X7, "^3", "³") - -#include "multi_language.h" // Allow multiple languages - -#include "../lcd/language/language_en.h" -#include LANGUAGE_INCL(LCD_LANGUAGE) -#include LANGUAGE_INCL(LCD_LANGUAGE_2) -#include LANGUAGE_INCL(LCD_LANGUAGE_3) -#include LANGUAGE_INCL(LCD_LANGUAGE_4) -#include LANGUAGE_INCL(LCD_LANGUAGE_5) - -#if NONE(DISPLAY_CHARSET_ISO10646_1, \ - DISPLAY_CHARSET_ISO10646_5, \ - DISPLAY_CHARSET_ISO10646_KANA, \ - DISPLAY_CHARSET_ISO10646_GREEK, \ - DISPLAY_CHARSET_ISO10646_CN, \ - DISPLAY_CHARSET_ISO10646_TR, \ - DISPLAY_CHARSET_ISO10646_PL, \ - DISPLAY_CHARSET_ISO10646_CZ, \ - DISPLAY_CHARSET_ISO10646_SK) - #define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. -#endif diff --git a/src/core/macros.h b/src/core/macros.h deleted file mode 100644 index ad06763..0000000 --- a/src/core/macros.h +++ /dev/null @@ -1,720 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#if !defined(__has_include) - #define __has_include(...) 1 -#endif - -#define ABCE 4 -#define XYZE 4 -#define ABC 3 -#define XYZ 3 -#define XY 2 - -#define _AXIS(A) (A##_AXIS) - -#define _XSTOP_ 0x01 -#define _YSTOP_ 0x02 -#define _ZSTOP_ 0x03 -#define _ISTOP_ 0x04 -#define _JSTOP_ 0x05 -#define _KSTOP_ 0x06 -#define _XMIN_ 0x11 -#define _YMIN_ 0x12 -#define _ZMIN_ 0x13 -#define _IMIN_ 0x14 -#define _JMIN_ 0x15 -#define _KMIN_ 0x16 -#define _XMAX_ 0x21 -#define _YMAX_ 0x22 -#define _ZMAX_ 0x23 -#define _IMAX_ 0x24 -#define _JMAX_ 0x25 -#define _KMAX_ 0x26 -#define _XDIAG_ 0x31 -#define _YDIAG_ 0x32 -#define _ZDIAG_ 0x33 -#define _IDIAG_ 0x34 -#define _JDIAG_ 0x35 -#define _KDIAG_ 0x36 -#define _E0DIAG_ 0xE0 -#define _E1DIAG_ 0xE1 -#define _E2DIAG_ 0xE2 -#define _E3DIAG_ 0xE3 -#define _E4DIAG_ 0xE4 -#define _E5DIAG_ 0xE5 -#define _E6DIAG_ 0xE6 -#define _E7DIAG_ 0xE7 - -#define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__ -#define FORCE_INLINE __attribute__((always_inline)) inline -#define NO_INLINE __attribute__((noinline)) -#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"))) - -#define IS_CONSTEXPR(...) __builtin_constant_p(__VA_ARGS__) // Only valid solution with C++14. Should use std::is_constant_evaluated() in C++20 instead - -#ifndef UNUSED - #define UNUSED(x) ((void)(x)) -#endif - -// Clock speed factors -#if !defined(CYCLES_PER_MICROSECOND) && !defined(__STM32F1__) - #define CYCLES_PER_MICROSECOND (F_CPU / 1000000UL) // 16 or 20 on AVR -#endif - -// Nanoseconds per cycle -#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU) - -// Macros to make a string from a macro -#define STRINGIFY_(M) #M -#define STRINGIFY(M) STRINGIFY_(M) - -#define A(CODE) " " CODE "\n\t" -#define L(CODE) CODE ":\n\t" - -// Macros for bit masks -#undef _BV -#define _BV(n) (1<<(n)) -#define TEST(n,b) (!!((n)&_BV(b))) -#define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0) -#ifndef SBI - #define SBI(A,B) (A |= _BV(B)) -#endif -#ifndef CBI - #define CBI(A,B) (A &= ~_BV(B)) -#endif -#define TBI(N,B) (N ^= _BV(B)) -#define _BV32(b) (1UL << (b)) -#define TEST32(n,b) !!((n)&_BV32(b)) -#define SBI32(n,b) (n |= _BV32(b)) -#define CBI32(n,b) (n &= ~_BV32(b)) -#define TBI32(N,B) (N ^= _BV32(B)) - -#define cu(x) ({__typeof__(x) _x = (x); (_x)*(_x)*(_x);}) -#define RADIANS(d) ((d)*float(M_PI)/180.0f) -#define DEGREES(r) ((r)*180.0f/float(M_PI)) -#define HYPOT2(x,y) (sq(x)+sq(y)) -#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z)) - -#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R))) -#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R)) - -#define SIGN(a) ({__typeof__(a) _a = (a); (_a>0)-(_a<0);}) -#define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1))) - -// Macros to constrain values -#ifdef __cplusplus - - // C++11 solution that is standards compliant. - template static constexpr void NOLESS(V& v, const N n) { - if (n > v) v = n; - } - template static constexpr void NOMORE(V& v, const N n) { - if (n < v) v = n; - } - template static constexpr void LIMIT(V& v, const N1 n1, const N2 n2) { - if (n1 > v) v = n1; - else if (n2 < v) v = n2; - } - -#else - - #define NOLESS(v, n) \ - do{ \ - __typeof__(v) _n = (n); \ - if (_n > v) v = _n; \ - }while(0) - - #define NOMORE(v, n) \ - do{ \ - __typeof__(v) _n = (n); \ - if (_n < v) v = _n; \ - }while(0) - - #define LIMIT(v, n1, n2) \ - do{ \ - __typeof__(v) _n1 = (n1); \ - __typeof__(v) _n2 = (n2); \ - if (_n1 > v) v = _n1; \ - else if (_n2 < v) v = _n2; \ - }while(0) - -#endif - -// Macros to chain up to 40 conditions -#define _DO_1(W,C,A) (_##W##_1(A)) -#define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B)) -#define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V)) -#define _DO_4(W,C,A,V...) (_##W##_1(A) C _DO_3(W,C,V)) -#define _DO_5(W,C,A,V...) (_##W##_1(A) C _DO_4(W,C,V)) -#define _DO_6(W,C,A,V...) (_##W##_1(A) C _DO_5(W,C,V)) -#define _DO_7(W,C,A,V...) (_##W##_1(A) C _DO_6(W,C,V)) -#define _DO_8(W,C,A,V...) (_##W##_1(A) C _DO_7(W,C,V)) -#define _DO_9(W,C,A,V...) (_##W##_1(A) C _DO_8(W,C,V)) -#define _DO_10(W,C,A,V...) (_##W##_1(A) C _DO_9(W,C,V)) -#define _DO_11(W,C,A,V...) (_##W##_1(A) C _DO_10(W,C,V)) -#define _DO_12(W,C,A,V...) (_##W##_1(A) C _DO_11(W,C,V)) -#define _DO_13(W,C,A,V...) (_##W##_1(A) C _DO_12(W,C,V)) -#define _DO_14(W,C,A,V...) (_##W##_1(A) C _DO_13(W,C,V)) -#define _DO_15(W,C,A,V...) (_##W##_1(A) C _DO_14(W,C,V)) -#define _DO_16(W,C,A,V...) (_##W##_1(A) C _DO_15(W,C,V)) -#define _DO_17(W,C,A,V...) (_##W##_1(A) C _DO_16(W,C,V)) -#define _DO_18(W,C,A,V...) (_##W##_1(A) C _DO_17(W,C,V)) -#define _DO_19(W,C,A,V...) (_##W##_1(A) C _DO_18(W,C,V)) -#define _DO_20(W,C,A,V...) (_##W##_1(A) C _DO_19(W,C,V)) -#define _DO_21(W,C,A,V...) (_##W##_1(A) C _DO_20(W,C,V)) -#define _DO_22(W,C,A,V...) (_##W##_1(A) C _DO_21(W,C,V)) -#define _DO_23(W,C,A,V...) (_##W##_1(A) C _DO_22(W,C,V)) -#define _DO_24(W,C,A,V...) (_##W##_1(A) C _DO_23(W,C,V)) -#define _DO_25(W,C,A,V...) (_##W##_1(A) C _DO_24(W,C,V)) -#define _DO_26(W,C,A,V...) (_##W##_1(A) C _DO_25(W,C,V)) -#define _DO_27(W,C,A,V...) (_##W##_1(A) C _DO_26(W,C,V)) -#define _DO_28(W,C,A,V...) (_##W##_1(A) C _DO_27(W,C,V)) -#define _DO_29(W,C,A,V...) (_##W##_1(A) C _DO_28(W,C,V)) -#define _DO_30(W,C,A,V...) (_##W##_1(A) C _DO_29(W,C,V)) -#define _DO_31(W,C,A,V...) (_##W##_1(A) C _DO_30(W,C,V)) -#define _DO_32(W,C,A,V...) (_##W##_1(A) C _DO_31(W,C,V)) -#define _DO_33(W,C,A,V...) (_##W##_1(A) C _DO_32(W,C,V)) -#define _DO_34(W,C,A,V...) (_##W##_1(A) C _DO_33(W,C,V)) -#define _DO_35(W,C,A,V...) (_##W##_1(A) C _DO_34(W,C,V)) -#define _DO_36(W,C,A,V...) (_##W##_1(A) C _DO_35(W,C,V)) -#define _DO_37(W,C,A,V...) (_##W##_1(A) C _DO_36(W,C,V)) -#define _DO_38(W,C,A,V...) (_##W##_1(A) C _DO_37(W,C,V)) -#define _DO_39(W,C,A,V...) (_##W##_1(A) C _DO_38(W,C,V)) -#define _DO_40(W,C,A,V...) (_##W##_1(A) C _DO_39(W,C,V)) -#define __DO_N(W,C,N,V...) _DO_##N(W,C,V) -#define _DO_N(W,C,N,V...) __DO_N(W,C,N,V) -#define DO(W,C,V...) (_DO_N(W,C,NUM_ARGS(V),V)) - -// Macros to support option testing -#define _CAT(a,V...) a##V -#define CAT(a,V...) _CAT(a,V) - -#define _ISENA_ ~,1 -#define _ISENA_1 ~,1 -#define _ISENA_0x1 ~,1 -#define _ISENA_true ~,1 -#define _ISENA(V...) IS_PROBE(V) - -#define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O))) -#define _DIS_1(O) NOT(_ENA_1(O)) -#define ENABLED(V...) DO(ENA,&&,V) -#define DISABLED(V...) DO(DIS,&&,V) -#define COUNT_ENABLED(V...) DO(ENA,+,V) - -#define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION ? 'A' : 'B' -#define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION ? 'A' : '0' -#define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION ? 'A' : '1' -#define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION ? 'A' : '' -#define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1' -#define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1' -#define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B. - -#define _OPTITEM(A...) A, -#define OPTITEM(O,A...) TERN_(O,DEFER4(_OPTITEM)(A)) -#define _OPTARG(A...) , A -#define OPTARG(O,A...) TERN_(O,DEFER4(_OPTARG)(A)) -#define _OPTCODE(A) A; -#define OPTCODE(O,A) TERN_(O,DEFER4(_OPTCODE)(A)) - -// Macros to avoid 'f + 0.0' which is not always optimized away. Minus included for symmetry. -// Compiler flags -fno-signed-zeros -ffinite-math-only also cover 'f * 1.0', 'f - f', etc. -#define PLUS_TERN0(O,A) _TERN(_ENA_1(O),,+ (A)) // OPTION ? '+ (A)' : '' -#define MINUS_TERN0(O,A) _TERN(_ENA_1(O),,- (A)) // OPTION ? '- (A)' : '' -#define SUM_TERN(O,B,A) ((B) PLUS_TERN0(O,A)) // ((B) (OPTION ? '+ (A)' : '')) -#define DIFF_TERN(O,B,A) ((B) MINUS_TERN0(O,A)) // ((B) (OPTION ? '- (A)' : '')) - -#define IF_ENABLED TERN_ -#define IF_DISABLED(O,A) TERN(O,,A) - -#define ANY(V...) !DISABLED(V) -#define NONE(V...) DISABLED(V) -#define ALL(V...) ENABLED(V) -#define BOTH(V1,V2) ALL(V1,V2) -#define EITHER(V1,V2) ANY(V1,V2) -#define MANY(V...) (COUNT_ENABLED(V) > 1) - -// Macros to support pins/buttons exist testing -#define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0) -#define _PINEX_1 PIN_EXISTS -#define PINS_EXIST(V...) DO(PINEX,&&,V) -#define ANY_PIN(V...) DO(PINEX,||,V) - -#define BUTTON_EXISTS(BN) (defined(BTN_##BN) && BTN_##BN >= 0) -#define _BTNEX_1 BUTTON_EXISTS -#define BUTTONS_EXIST(V...) DO(BTNEX,&&,V) -#define ANY_BUTTON(V...) DO(BTNEX,||,V) - -#define WITHIN(N,L,H) ((N) >= (L) && (N) <= (H)) -#define ISEOL(C) ((C) == '\n' || (C) == '\r') -#define NUMERIC(a) WITHIN(a, '0', '9') -#define DECIMAL(a) (NUMERIC(a) || a == '.') -#define HEXCHR(a) (NUMERIC(a) ? (a) - '0' : WITHIN(a, 'a', 'f') ? ((a) - 'a' + 10) : WITHIN(a, 'A', 'F') ? ((a) - 'A' + 10) : -1) -#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+') -#define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+') -#define COUNT(a) (sizeof(a)/sizeof(*a)) -#define ZERO(a) memset((void*)a,0,sizeof(a)) -#define COPY(a,b) do{ \ - static_assert(sizeof(a[0]) == sizeof(b[0]), "COPY: '" STRINGIFY(a) "' and '" STRINGIFY(b) "' types (sizes) don't match!"); \ - memcpy(&a[0],&b[0],_MIN(sizeof(a),sizeof(b))); \ - }while(0) - -#define CODE_16( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P -#define CODE_15( A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N; O -#define CODE_14( A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A; B; C; D; E; F; G; H; I; J; K; L; M; N -#define CODE_13( A,B,C,D,E,F,G,H,I,J,K,L,M,...) A; B; C; D; E; F; G; H; I; J; K; L; M -#define CODE_12( A,B,C,D,E,F,G,H,I,J,K,L,...) A; B; C; D; E; F; G; H; I; J; K; L -#define CODE_11( A,B,C,D,E,F,G,H,I,J,K,...) A; B; C; D; E; F; G; H; I; J; K -#define CODE_10( A,B,C,D,E,F,G,H,I,J,...) A; B; C; D; E; F; G; H; I; J -#define CODE_9( A,B,C,D,E,F,G,H,I,...) A; B; C; D; E; F; G; H; I -#define CODE_8( A,B,C,D,E,F,G,H,...) A; B; C; D; E; F; G; H -#define CODE_7( A,B,C,D,E,F,G,...) A; B; C; D; E; F; G -#define CODE_6( A,B,C,D,E,F,...) A; B; C; D; E; F -#define CODE_5( A,B,C,D,E,...) A; B; C; D; E -#define CODE_4( A,B,C,D,...) A; B; C; D -#define CODE_3( A,B,C,...) A; B; C -#define CODE_2( A,B,...) A; B -#define CODE_1( A,...) A -#define CODE_0(...) -#define _CODE_N(N,V...) CODE_##N(V) -#define CODE_N(N,V...) _CODE_N(N,V) - -#define GANG_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A B C D E F G H I J K L M N O P -#define GANG_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A B C D E F G H I J K L M N O -#define GANG_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A B C D E F G H I J K L M N -#define GANG_13(A,B,C,D,E,F,G,H,I,J,K,L,M...) A B C D E F G H I J K L M -#define GANG_12(A,B,C,D,E,F,G,H,I,J,K,L...) A B C D E F G H I J K L -#define GANG_11(A,B,C,D,E,F,G,H,I,J,K,...) A B C D E F G H I J K -#define GANG_10(A,B,C,D,E,F,G,H,I,J,...) A B C D E F G H I J -#define GANG_9( A,B,C,D,E,F,G,H,I,...) A B C D E F G H I -#define GANG_8( A,B,C,D,E,F,G,H,...) A B C D E F G H -#define GANG_7( A,B,C,D,E,F,G,...) A B C D E F G -#define GANG_6( A,B,C,D,E,F,...) A B C D E F -#define GANG_5( A,B,C,D,E,...) A B C D E -#define GANG_4( A,B,C,D,...) A B C D -#define GANG_3( A,B,C,...) A B C -#define GANG_2( A,B,...) A B -#define GANG_1( A,...) A -#define GANG_0(...) -#define _GANG_N(N,V...) GANG_##N(V) -#define GANG_N(N,V...) _GANG_N(N,V) -#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K) - -// Macros for initializing arrays -#define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T -#define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S -#define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R -#define LIST_17(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q -#define LIST_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P -#define LIST_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O -#define LIST_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N -#define LIST_13(A,B,C,D,E,F,G,H,I,J,K,L,M,...) A,B,C,D,E,F,G,H,I,J,K,L,M -#define LIST_12(A,B,C,D,E,F,G,H,I,J,K,L,...) A,B,C,D,E,F,G,H,I,J,K,L -#define LIST_11(A,B,C,D,E,F,G,H,I,J,K,...) A,B,C,D,E,F,G,H,I,J,K -#define LIST_10(A,B,C,D,E,F,G,H,I,J,...) A,B,C,D,E,F,G,H,I,J -#define LIST_9( A,B,C,D,E,F,G,H,I,...) A,B,C,D,E,F,G,H,I -#define LIST_8( A,B,C,D,E,F,G,H,...) A,B,C,D,E,F,G,H -#define LIST_7( A,B,C,D,E,F,G,...) A,B,C,D,E,F,G -#define LIST_6( A,B,C,D,E,F,...) A,B,C,D,E,F -#define LIST_5( A,B,C,D,E,...) A,B,C,D,E -#define LIST_4( A,B,C,D,...) A,B,C,D -#define LIST_3( A,B,C,...) A,B,C -#define LIST_2( A,B,...) A,B -#define LIST_1( A,...) A -#define LIST_0(...) - -#define _LIST_N(N,V...) LIST_##N(V) -#define LIST_N(N,V...) _LIST_N(N,V) -#define LIST_N_1(N,K) _LIST_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K) -#define ARRAY_N(N,V...) { _LIST_N(N,V) } -#define ARRAY_N_1(N,K) { LIST_N_1(N,K) } - -#define _JOIN_1(O) (O) -#define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V))) - -#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++) -#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++) -#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N) -#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N) - -#define NOOP (void(0)) - -#define CEILING(x,y) (((x) + (y) - 1) / (y)) - -#undef ABS -#ifdef __cplusplus - template static constexpr const T ABS(const T v) { return v >= 0 ? v : -v; } -#else - #define ABS(a) ({__typeof__(a) _a = (a); _a >= 0 ? _a : -_a;}) -#endif - -#define UNEAR_ZERO(x) ((x) < 0.000001f) -#define NEAR_ZERO(x) WITHIN(x, -0.000001f, 0.000001f) -#define NEAR(x,y) NEAR_ZERO((x)-(y)) - -#define RECIPROCAL(x) (NEAR_ZERO(x) ? 0 : (1 / float(x))) -#define FIXFLOAT(f) ({__typeof__(f) _f = (f); _f + (_f < 0 ? -0.0000005f : 0.0000005f);}) - -// -// Maths macros that can be overridden by HAL -// -#define ACOS(x) acosf(x) -#define ATAN2(y, x) atan2f(y, x) -#define POW(x, y) powf(x, y) -#define SQRT(x) sqrtf(x) -#define RSQRT(x) (1.0f / sqrtf(x)) -#define CEIL(x) ceilf(x) -#define FLOOR(x) floorf(x) -#define TRUNC(x) truncf(x) -#define LROUND(x) lroundf(x) -#define FMOD(x, y) fmodf(x, y) -#define HYPOT(x,y) SQRT(HYPOT2(x,y)) - -// Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments -#define _NUM_ARGS(_,n,m,l,k,j,i,h,g,f,e,d,c,b,a,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT -#define NUM_ARGS(V...) _NUM_ARGS(0,V,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) - -// Use TWO_ARGS(__VA_ARGS__) to get whether there are 1, 2, or >2 arguments -#define _TWO_ARGS(_,n,m,l,k,j,i,h,g,f,e,d,c,b,a,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT -#define TWO_ARGS(V...) _TWO_ARGS(0,V,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,0) - -#ifdef __cplusplus - - #ifndef _MINMAX_H_ - #define _MINMAX_H_ - - extern "C++" { - - // C++11 solution that is standards compliant. Return type is deduced automatically - template static constexpr auto _MIN(const L lhs, const R rhs) -> decltype(lhs + rhs) { - return lhs < rhs ? lhs : rhs; - } - template static constexpr auto _MAX(const L lhs, const R rhs) -> decltype(lhs + rhs) { - return lhs > rhs ? lhs : rhs; - } - template static constexpr const T _MIN(T V, Ts... Vs) { return _MIN(V, _MIN(Vs...)); } - template static constexpr const T _MAX(T V, Ts... Vs) { return _MAX(V, _MAX(Vs...)); } - - } - - #endif - - // Allow manipulating enumeration value like flags without ugly cast everywhere - #define ENUM_FLAGS(T) \ - FORCE_INLINE constexpr T operator&(T x, T y) { return static_cast(static_cast(x) & static_cast(y)); } \ - FORCE_INLINE constexpr T operator|(T x, T y) { return static_cast(static_cast(x) | static_cast(y)); } \ - FORCE_INLINE constexpr T operator^(T x, T y) { return static_cast(static_cast(x) ^ static_cast(y)); } \ - FORCE_INLINE constexpr T operator~(T x) { return static_cast(~static_cast(x)); } \ - FORCE_INLINE T & operator&=(T &x, T y) { return x &= y; } \ - FORCE_INLINE T & operator|=(T &x, T y) { return x |= y; } \ - FORCE_INLINE T & operator^=(T &x, T y) { return x ^= y; } - - // C++11 solution that is standard compliant. is not available on all platform - namespace Private { - template struct enable_if { }; - template struct enable_if { typedef _Tp type; }; - - template struct is_same { enum { value = false }; }; - template struct is_same { enum { value = true }; }; - - template struct first_type_of { typedef T type; }; - template struct first_type_of { typedef T type; }; - } - // C++11 solution using SFINAE to detect the existence of a member in a class at compile time. - // It creates a HasMember structure containing 'value' set to true if the member exists - #define HAS_MEMBER_IMPL(Member) \ - namespace Private { \ - template struct HasMember_ ## Member { \ - template static Yes& test( decltype(&C::Member) ) ; \ - template static No& test(...); \ - enum { value = sizeof(test(0)) == sizeof(Yes) }; }; \ - } - - // Call the method if it exists, but do nothing if it does not. The method is detected at compile time. - // If the method exists, this is inlined and does not cost anything. Else, an "empty" wrapper is created, returning a default value - #define CALL_IF_EXISTS_IMPL(Return, Method, ...) \ - HAS_MEMBER_IMPL(Method) \ - namespace Private { \ - template FORCE_INLINE typename enable_if::value, Return>::type Call_ ## Method(T * t, Args... a) { return static_cast(t->Method(a...)); } \ - _UNUSED static Return Call_ ## Method(...) { return __VA_ARGS__; } \ - } - #define CALL_IF_EXISTS(Return, That, Method, ...) \ - static_cast(Private::Call_ ## Method(That, ##__VA_ARGS__)) - - // Compile-time string manipulation - namespace CompileTimeString { - // Simple compile-time parser to find the position of the end of a string - constexpr const char* findStringEnd(const char *str) { - return *str ? findStringEnd(str + 1) : str; - } - - // Check whether a string contains a specific character - constexpr bool contains(const char *str, const char ch) { - return *str == ch ? true : (*str ? contains(str + 1, ch) : false); - } - // Find the last position of the specific character (should be called with findStringEnd) - constexpr const char* findLastPos(const char *str, const char ch) { - return *str == ch ? (str + 1) : findLastPos(str - 1, ch); - } - // Compile-time evaluation of the last part of a file path - // Typically used to shorten the path to file in compiled strings - // CompileTimeString::baseName(__FILE__) returns "macros.h" and not /path/to/Marlin/src/core/macros.h - constexpr const char* baseName(const char *str) { - return contains(str, '/') ? findLastPos(findStringEnd(str), '/') : str; - } - - // Find the first occurrence of a character in a string (or return the last position in the string) - constexpr const char* findFirst(const char *str, const char ch) { - return *str == ch || *str == 0 ? (str + 1) : findFirst(str + 1, ch); - } - // Compute the string length at compile time - constexpr unsigned stringLen(const char *str) { - return *str == 0 ? 0 : 1 + stringLen(str + 1); - } - } - - #define ONLY_FILENAME CompileTimeString::baseName(__FILE__) - /** Get the templated type name. This does not depends on RTTI, but on the preprocessor, so it should be quite safe to use even on old compilers. - WARNING: DO NOT RENAME THIS FUNCTION (or change the text inside the function to match what the preprocessor will generate) - The name is chosen very short since the binary will store "const char* gtn(T*) [with T = YourTypeHere]" so avoid long function name here */ - template - inline const char* gtn(T*) { - // It works on GCC by instantiating __PRETTY_FUNCTION__ and parsing the result. So the syntax here is very limited to GCC output - constexpr unsigned verboseChatLen = sizeof("const char* gtn(T*) [with T = ") - 1; - static char templateType[sizeof(__PRETTY_FUNCTION__) - verboseChatLen] = {}; - __builtin_memcpy(templateType, __PRETTY_FUNCTION__ + verboseChatLen, sizeof(__PRETTY_FUNCTION__) - verboseChatLen - 2); - return templateType; - } - -#else - - #define __MIN_N(N,V...) MIN_##N(V) - #define _MIN_N(N,V...) __MIN_N(N,V) - #define _MIN_N_REF() _MIN_N - #define _MIN(V...) EVAL(_MIN_N(TWO_ARGS(V),V)) - #define MIN_2(a,b) ((a)<(b)?(a):(b)) - #define MIN_3(a,V...) MIN_2(a,DEFER2(_MIN_N_REF)()(TWO_ARGS(V),V)) - - #define __MAX_N(N,V...) MAX_##N(V) - #define _MAX_N(N,V...) __MAX_N(N,V) - #define _MAX_N_REF() _MAX_N - #define _MAX(V...) EVAL(_MAX_N(TWO_ARGS(V),V)) - #define MAX_2(a,b) ((a)>(b)?(a):(b)) - #define MAX_3(a,V...) MAX_2(a,DEFER2(_MAX_N_REF)()(TWO_ARGS(V),V)) - -#endif - -// Macros for adding -#define INC_0 1 -#define INC_1 2 -#define INC_2 3 -#define INC_3 4 -#define INC_4 5 -#define INC_5 6 -#define INC_6 7 -#define INC_7 8 -#define INC_8 9 -#define INC_9 10 -#define INC_10 11 -#define INC_11 12 -#define INC_12 13 -#define INC_13 14 -#define INC_14 15 -#define INC_15 16 -#define INC_16 17 -#define INC_17 18 -#define INC_18 19 -#define INC_19 20 -#define INC_20 21 -#define INCREMENT_(n) INC_##n -#define INCREMENT(n) INCREMENT_(n) - -#define ADD0(N) N -#define ADD1(N) INCREMENT_(N) -#define ADD2(N) ADD1(ADD1(N)) -#define ADD3(N) ADD1(ADD2(N)) -#define ADD4(N) ADD2(ADD2(N)) -#define ADD5(N) ADD2(ADD3(N)) -#define ADD6(N) ADD3(ADD3(N)) -#define ADD7(N) ADD3(ADD4(N)) -#define ADD8(N) ADD4(ADD4(N)) -#define ADD9(N) ADD4(ADD5(N)) -#define ADD10(N) ADD5(ADD5(N)) -#define SUM(A,B) _CAT(ADD,A)(B) -#define DOUBLE_(n) ADD##n(n) -#define DOUBLE(n) DOUBLE_(n) - -// Macros for subtracting -#define DEC_0 0 -#define DEC_1 0 -#define DEC_2 1 -#define DEC_3 2 -#define DEC_4 3 -#define DEC_5 4 -#define DEC_6 5 -#define DEC_7 6 -#define DEC_8 7 -#define DEC_9 8 -#define DEC_10 9 -#define DEC_11 10 -#define DEC_12 11 -#define DEC_13 12 -#define DEC_14 13 -#define DEC_15 14 -#define DECREMENT_(n) DEC_##n -#define DECREMENT(n) DECREMENT_(n) - -#define SUB0(N) N -#define SUB1(N) DECREMENT_(N) -#define SUB2(N) SUB1(SUB1(N)) -#define SUB3(N) SUB1(SUB2(N)) -#define SUB4(N) SUB2(SUB2(N)) -#define SUB5(N) SUB2(SUB3(N)) -#define SUB6(N) SUB3(SUB3(N)) -#define SUB7(N) SUB3(SUB4(N)) -#define SUB8(N) SUB4(SUB4(N)) -#define SUB9(N) SUB4(SUB5(N)) -#define SUB10(N) SUB5(SUB5(N)) - -// -// Primitives supporting precompiler REPEAT -// -#define FIRST(a,...) a -#define SECOND(a,b,...) b -#define THIRD(a,b,c,...) c - -// Defer expansion -#define EMPTY() -#define DEFER(M) M EMPTY() -#define DEFER2(M) M EMPTY EMPTY()() -#define DEFER3(M) M EMPTY EMPTY EMPTY()()() -#define DEFER4(M) M EMPTY EMPTY EMPTY EMPTY()()()() - -// Force define expansion -#define EVAL(V...) EVAL16(V) -#define EVAL1024(V...) EVAL512(EVAL512(V)) -#define EVAL512(V...) EVAL256(EVAL256(V)) -#define EVAL256(V...) EVAL128(EVAL128(V)) -#define EVAL128(V...) EVAL64(EVAL64(V)) -#define EVAL64(V...) EVAL32(EVAL32(V)) -#define EVAL32(V...) EVAL16(EVAL16(V)) -#define EVAL16(V...) EVAL8(EVAL8(V)) -#define EVAL8(V...) EVAL4(EVAL4(V)) -#define EVAL4(V...) EVAL2(EVAL2(V)) -#define EVAL2(V...) EVAL1(EVAL1(V)) -#define EVAL1(V...) V - -#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0 -#define PROBE() ~, 1 // Second item will be 1 if this is passed -#define _NOT_0 PROBE() -#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'. -#define _BOOL(x) NOT(NOT(x)) // _BOOL('0') gets '0'. Anything else gets '1'. - -#define IF_ELSE(TF) _IF_ELSE(_BOOL(TF)) -#define _IF_ELSE(TF) _CAT(_IF_, TF) - -#define _IF_1(V...) V _IF_1_ELSE -#define _IF_0(...) _IF_0_ELSE - -#define _IF_1_ELSE(...) -#define _IF_0_ELSE(V...) V - -#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)()) -#define _END_OF_ARGUMENTS_() 0 - -// Simple Inline IF Macros, friendly to use in other macro definitions -#define IF(O, A, B) ((O) ? (A) : (B)) -#define IF_0(O, A) IF(O, A, 0) -#define IF_1(O, A) IF(O, A, 1) - -// -// REPEAT core macros. Recurse N times with ascending I. -// - -// Call OP(I) N times with ascending counter. -#define _REPEAT(_RPT_I,_RPT_N,_RPT_OP) \ - _RPT_OP(_RPT_I) \ - IF_ELSE(SUB1(_RPT_N)) \ - ( DEFER2(__REPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \ - ( /* Do nothing */ ) -#define __REPEAT() _REPEAT - -// Call OP(I, ...) N times with ascending counter. -#define _REPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \ - _RPT_OP(_RPT_I,V) \ - IF_ELSE(SUB1(_RPT_N)) \ - ( DEFER2(__REPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \ - ( /* Do nothing */ ) -#define __REPEAT2() _REPEAT2 - -// Repeat a macro passing S...N-1. -#define REPEAT_S(S,N,OP) EVAL(_REPEAT(S,SUB##S(N),OP)) -#define REPEAT(N,OP) REPEAT_S(0,N,OP) -#define REPEAT_1(N,OP) REPEAT_S(1,INCREMENT(N),OP) - -// Repeat a macro passing 0...N-1 plus additional arguments. -#define REPEAT2_S(S,N,OP,V...) EVAL(_REPEAT2(S,SUB##S(N),OP,V)) -#define REPEAT2(N,OP,V...) REPEAT2_S(0,N,OP,V) - -// Use RREPEAT macros with REPEAT macros for nesting -#define _RREPEAT(_RPT_I,_RPT_N,_RPT_OP) \ - _RPT_OP(_RPT_I) \ - IF_ELSE(SUB1(_RPT_N)) \ - ( DEFER2(__RREPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \ - ( /* Do nothing */ ) -#define __RREPEAT() _RREPEAT -#define _RREPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \ - _RPT_OP(_RPT_I,V) \ - IF_ELSE(SUB1(_RPT_N)) \ - ( DEFER2(__RREPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \ - ( /* Do nothing */ ) -#define __RREPEAT2() _RREPEAT2 -#define RREPEAT_S(S,N,OP) EVAL1024(_RREPEAT(S,SUB##S(N),OP)) -#define RREPEAT(N,OP) RREPEAT_S(0,N,OP) -#define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V)) -#define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V) - -// Call OP(A) with each item as an argument -#define _MAP(_MAP_OP,A,V...) \ - _MAP_OP(A) \ - IF_ELSE(HAS_ARGS(V)) \ - ( DEFER2(__MAP)()(_MAP_OP,V) ) \ - ( /* Do nothing */ ) -#define __MAP() _MAP - -#define MAP(OP,V...) EVAL(_MAP(OP,V)) - -// Emit a list of OP(A) with the given items -#define _MAPLIST(_MAP_OP,A,V...) \ - _MAP_OP(A) \ - IF_ELSE(HAS_ARGS(V)) \ - ( , DEFER2(__MAPLIST)()(_MAP_OP,V) ) \ - ( /* Do nothing */ ) -#define __MAPLIST() _MAPLIST - -#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V)) diff --git a/src/core/millis_t.h b/src/core/millis_t.h deleted file mode 100644 index 95bc40e..0000000 --- a/src/core/millis_t.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -typedef uint32_t millis_t; - -#define SEC_TO_MS(N) millis_t((N)*1000UL) -#define MIN_TO_MS(N) SEC_TO_MS((N)*60UL) -#define MS_TO_SEC(N) millis_t((N)/1000UL) - -#define PENDING(NOW,SOON) ((int32_t)(NOW-(SOON))<0) -#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON)) diff --git a/src/core/multi_language.h b/src/core/multi_language.h deleted file mode 100644 index 05a713e..0000000 --- a/src/core/multi_language.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/******************************************************* - * multi_language.h * - * By Marcio Teixeira 2019 for Aleph Objects * - *******************************************************/ - -#include "../inc/MarlinConfigPre.h" - -typedef const char Language_Str[]; -#define LSTR PROGMEM Language_Str - -#ifdef LCD_LANGUAGE_5 - #define NUM_LANGUAGES 5 -#elif defined(LCD_LANGUAGE_4) - #define NUM_LANGUAGES 4 -#elif defined(LCD_LANGUAGE_3) - #define NUM_LANGUAGES 3 -#elif defined(LCD_LANGUAGE_2) - #define NUM_LANGUAGES 2 -#else - #define NUM_LANGUAGES 1 -#endif - -// Set unused languages equal to each other so the -// compiler can optimize away the conditionals. -#define LCD_LANGUAGE_1 LCD_LANGUAGE -#ifndef LCD_LANGUAGE_2 - #define LCD_LANGUAGE_2 LCD_LANGUAGE -#endif -#ifndef LCD_LANGUAGE_3 - #define LCD_LANGUAGE_3 LCD_LANGUAGE_2 -#endif -#ifndef LCD_LANGUAGE_4 - #define LCD_LANGUAGE_4 LCD_LANGUAGE_3 -#endif -#ifndef LCD_LANGUAGE_5 - #define LCD_LANGUAGE_5 LCD_LANGUAGE_4 -#endif - -#define _GET_LANG(LANG) Language_##LANG -#define GET_LANG(LANG) _GET_LANG(LANG) - -#if NUM_LANGUAGES > 1 - #define HAS_MULTI_LANGUAGE 1 - #define GET_TEXT(MSG) ( \ - ui.language == 4 ? GET_LANG(LCD_LANGUAGE_5)::MSG : \ - ui.language == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \ - ui.language == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \ - ui.language == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \ - GET_LANG(LCD_LANGUAGE )::MSG ) - #define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE )::CHARSIZE, \ - GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \ - GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \ - GET_LANG(LCD_LANGUAGE_4)::CHARSIZE, \ - GET_LANG(LCD_LANGUAGE_5)::CHARSIZE ) -#else - #define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG - #define MAX_LANG_CHARSIZE LANG_CHARSIZE -#endif -#define GET_TEXT_F(MSG) FPSTR(GET_TEXT(MSG)) - -#define GET_EN_TEXT(MSG) GET_LANG(en)::MSG -#define GET_EN_TEXT_F(MSG) FPSTR(GET_EN_TEXT(MSG)) - -#define GET_LANGUAGE_NAME(INDEX) GET_LANG(LCD_LANGUAGE_##INDEX)::LANGUAGE -#define LANG_CHARSIZE GET_TEXT(CHARSIZE) -#define USE_WIDE_GLYPH (LANG_CHARSIZE > 2) - -#define MSG_1_LINE(A) A "\0" "\0" -#define MSG_2_LINE(A,B) A "\0" B "\0" -#define MSG_3_LINE(A,B,C) A "\0" B "\0" C diff --git a/src/core/serial.cpp b/src/core/serial.cpp deleted file mode 100644 index 990c892..0000000 --- a/src/core/serial.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "serial.h" -#include "../inc/MarlinConfig.h" - -#if HAS_ETHERNET - #include "../feature/ethernet.h" -#endif - -uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE; - -// Commonly-used strings in serial output -PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C"); -PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T"); PGMSTR(NUL_STR, ""); - -#define _N_STR(N) PGMSTR(N##_STR, STR_##N); -#define _N_LBL(N) PGMSTR(N##_LBL, STR_##N ":"); -#define _SP_N_STR(N) PGMSTR(SP_##N##_STR, " " STR_##N); -#define _SP_N_LBL(N) PGMSTR(SP_##N##_LBL, " " STR_##N ":"); -MAP(_N_STR, LOGICAL_AXIS_NAMES); MAP(_SP_N_STR, LOGICAL_AXIS_NAMES); -MAP(_N_LBL, LOGICAL_AXIS_NAMES); MAP(_SP_N_LBL, LOGICAL_AXIS_NAMES); - -// Hook Meatpack if it's enabled on the first leaf -#if ENABLED(MEATPACK_ON_SERIAL_PORT_1) - SerialLeafT1 mpSerial1(false, _SERIAL_LEAF_1); -#endif -#if ENABLED(MEATPACK_ON_SERIAL_PORT_2) - SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2); -#endif -#if ENABLED(MEATPACK_ON_SERIAL_PORT_3) - SerialLeafT3 mpSerial3(false, _SERIAL_LEAF_3); -#endif - -// Step 2: For multiserial, handle the second serial port as well -#if HAS_MULTI_SERIAL - #if HAS_ETHERNET - // We need a definition here - SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false); - #endif - - #define __S_LEAF(N) ,SERIAL_LEAF_##N - #define _S_LEAF(N) __S_LEAF(N) - - SerialOutputT multiSerial( SERIAL_LEAF_1 REPEAT_S(2, INCREMENT(NUM_SERIAL), _S_LEAF) ); - - #undef __S_LEAF - #undef _S_LEAF - -#endif - -void serial_print_P(PGM_P str) { - while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c); -} - -void serial_echo_start() { serial_print(F("echo:")); } -void serial_error_start() { serial_print(F("Error:")); } - -void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); } - -void serial_offset(const_float_t v, const uint8_t sp/*=0*/) { - if (v == 0 && sp == 1) - SERIAL_CHAR(' '); - else if (v > 0 || (v == 0 && sp == 2)) - SERIAL_CHAR('+'); - SERIAL_DECIMAL(v); -} - -void serial_ternary(const bool onoff, FSTR_P const pre, FSTR_P const on, FSTR_P const off, FSTR_P const post/*=nullptr*/) { - if (pre) serial_print(pre); - serial_print(onoff ? on : off); - if (post) serial_print(post); -} -void serialprint_onoff(const bool onoff) { serial_print(onoff ? F(STR_ON) : F(STR_OFF)); } -void serialprintln_onoff(const bool onoff) { serialprint_onoff(onoff); SERIAL_EOL(); } -void serialprint_truefalse(const bool tf) { serial_print(tf ? F("true") : F("false")); } - -void print_bin(uint16_t val) { - for (uint8_t i = 16; i--;) { - SERIAL_CHAR('0' + TEST(val, i)); - if (!(i & 0x3) && i) SERIAL_CHAR(' '); - } -} - -void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { - if (prefix) serial_print(prefix); - SERIAL_ECHOPGM_P( - LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k) - ); - if (suffix) serial_print(suffix); else SERIAL_EOL(); -} diff --git a/src/core/serial.h b/src/core/serial.h deleted file mode 100644 index c19bc08..0000000 --- a/src/core/serial.h +++ /dev/null @@ -1,374 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" -#include "serial_hook.h" - -#if HAS_MEATPACK - #include "../feature/meatpack.h" -#endif - -// -// Debugging flags for use by M111 -// -enum MarlinDebugFlags : uint8_t { - MARLIN_DEBUG_NONE = 0, - MARLIN_DEBUG_ECHO = _BV(0), ///< Echo commands in order as they are processed - MARLIN_DEBUG_INFO = _BV(1), ///< Print messages for code that has debug output - MARLIN_DEBUG_ERRORS = _BV(2), ///< Not implemented - MARLIN_DEBUG_DRYRUN = _BV(3), ///< Ignore temperature setting and E movement commands - MARLIN_DEBUG_COMMUNICATION = _BV(4), ///< Not implemented - #if ENABLED(DEBUG_LEVELING_FEATURE) - MARLIN_DEBUG_LEVELING = _BV(5), ///< Print detailed output for homing and leveling - MARLIN_DEBUG_MESH_ADJUST = _BV(6), ///< UBL bed leveling - #else - MARLIN_DEBUG_LEVELING = 0, - MARLIN_DEBUG_MESH_ADJUST = 0, - #endif - MARLIN_DEBUG_ALL = 0xFF -}; - -extern uint8_t marlin_debug_flags; -#define DEBUGGING(F) (marlin_debug_flags & (MARLIN_DEBUG_## F)) - -// -// Serial redirection -// -// Step 1: Find out what the first serial leaf is -#if HAS_MULTI_SERIAL && defined(SERIAL_CATCHALL) - #define _SERIAL_LEAF_1 MYSERIAL -#else - #define _SERIAL_LEAF_1 MYSERIAL1 -#endif - -// Hook Meatpack if it's enabled on the first leaf -#if ENABLED(MEATPACK_ON_SERIAL_PORT_1) - typedef MeatpackSerial SerialLeafT1; - extern SerialLeafT1 mpSerial1; - #define SERIAL_LEAF_1 mpSerial1 -#else - #define SERIAL_LEAF_1 _SERIAL_LEAF_1 -#endif - -// Step 2: For multiserial wrap all serial ports in a single -// interface with the ability to output to multiple serial ports. -#if HAS_MULTI_SERIAL - #define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p) - #define _PORT_RESTORE(n) RESTORE(n) - #define SERIAL_ASSERT(P) if (multiSerial.portMask!=(P)) { debugger(); } - // If we have a catchall, use that directly - #ifdef SERIAL_CATCHALL - #define _SERIAL_LEAF_2 SERIAL_CATCHALL - #elif HAS_ETHERNET - typedef ConditionalSerial SerialLeafT2; // We need to create an instance here - extern SerialLeafT2 msSerial2; - #define _SERIAL_LEAF_2 msSerial2 - #else - #define _SERIAL_LEAF_2 MYSERIAL2 // Don't create a useless instance here, directly use the existing instance - #endif - - // Nothing complicated here - #define _SERIAL_LEAF_3 MYSERIAL3 - - // Hook Meatpack if it's enabled on the second leaf - #if ENABLED(MEATPACK_ON_SERIAL_PORT_2) - typedef MeatpackSerial SerialLeafT2; - extern SerialLeafT2 mpSerial2; - #define SERIAL_LEAF_2 mpSerial2 - #else - #define SERIAL_LEAF_2 _SERIAL_LEAF_2 - #endif - - // Hook Meatpack if it's enabled on the third leaf - #if ENABLED(MEATPACK_ON_SERIAL_PORT_3) - typedef MeatpackSerial SerialLeafT3; - extern SerialLeafT3 mpSerial3; - #define SERIAL_LEAF_3 mpSerial3 - #else - #define SERIAL_LEAF_3 _SERIAL_LEAF_3 - #endif - - #define __S_MULTI(N) decltype(SERIAL_LEAF_##N), - #define _S_MULTI(N) __S_MULTI(N) - - typedef MultiSerial< REPEAT_1(NUM_SERIAL, _S_MULTI) 0> SerialOutputT; - - #undef __S_MULTI - #undef _S_MULTI - - extern SerialOutputT multiSerial; - #define SERIAL_IMPL multiSerial -#else - #define _PORT_REDIRECT(n,p) NOOP - #define _PORT_RESTORE(n) NOOP - #define SERIAL_ASSERT(P) NOOP - #define SERIAL_IMPL SERIAL_LEAF_1 -#endif - -#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V) - -#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p) -#define PORT_RESTORE() _PORT_RESTORE(1) -#define SERIAL_PORTMASK(P) SerialMask::from(P) - -// -// SERIAL_CHAR - Print one or more individual chars -// -inline void SERIAL_CHAR(char a) { SERIAL_IMPL.write(a); } -template -void SERIAL_CHAR(char a, Args ... args) { SERIAL_IMPL.write(a); SERIAL_CHAR(args ...); } - -/** - * SERIAL_ECHO - Print a single string or value. - * Any numeric parameter (including char) is printed as a base-10 number. - * A string pointer or literal will be output as a string. - * - * NOTE: Use SERIAL_CHAR to print char as a single character. - */ -template -void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); } - -// Wrapper for ECHO commands to interpret a char -typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t; -inline void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); } -#define AS_CHAR(C) serial_char_t(C) -#define AS_DIGIT(C) AS_CHAR('0' + (C)) - -template -void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); } - -// SERIAL_PRINT works like SERIAL_ECHO but also takes the numeric base -template -void SERIAL_PRINT(T x, U y) { SERIAL_IMPL.print(x, y); } - -template -void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); } - -// Flush the serial port -inline void SERIAL_FLUSH() { SERIAL_IMPL.flush(); } -inline void SERIAL_FLUSHTX() { SERIAL_IMPL.flushTX(); } - -// Serial echo and error prefixes -#define SERIAL_ECHO_START() serial_echo_start() -#define SERIAL_ERROR_START() serial_error_start() - -// Serial end-of-line -#define SERIAL_EOL() SERIAL_CHAR('\n') - -// Print a single PROGMEM, PGM_P, or PSTR() string. -void serial_print_P(PGM_P str); -inline void serial_println_P(PGM_P str) { serial_print_P(str); SERIAL_EOL(); } - -// Print a single FSTR_P, F(), or FPSTR() string. -inline void serial_print(FSTR_P const fstr) { serial_print_P(FTOP(fstr)); } -inline void serial_println(FSTR_P const fstr) { serial_println_P(FTOP(fstr)); } - -// -// SERIAL_ECHOPGM... macros are used to output string-value pairs. -// - -// Print up to 20 pairs of values. Odd elements must be literal strings. -#define __SEP_N(N,V...) _SEP_##N(V) -#define _SEP_N(N,V...) __SEP_N(N,V) -#define _SEP_N_REF() _SEP_N -#define _SEP_1(s) serial_print(F(s)); -#define _SEP_2(s,v) serial_echopair(F(s),v); -#define _SEP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SEP_N_REF)()(TWO_ARGS(V),V); -#define SERIAL_ECHOPGM(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values followed by newline. Odd elements must be literal strings. -#define __SELP_N(N,V...) _SELP_##N(V) -#define _SELP_N(N,V...) __SELP_N(N,V) -#define _SELP_N_REF() _SELP_N -#define _SELP_1(s) serial_print(F(s "\n")); -#define _SELP_2(s,v) serial_echolnpair(F(s),v); -#define _SELP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SELP_N_REF)()(TWO_ARGS(V),V); -#define SERIAL_ECHOLNPGM(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values. Odd elements must be PSTR pointers. -#define __SEP_N_P(N,V...) _SEP_##N##_P(V) -#define _SEP_N_P(N,V...) __SEP_N_P(N,V) -#define _SEP_N_P_REF() _SEP_N_P -#define _SEP_1_P(p) serial_print_P(p); -#define _SEP_2_P(p,v) serial_echopair_P(p,v); -#define _SEP_3_P(p,v,V...) _SEP_2_P(p,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V); -#define SERIAL_ECHOPGM_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values followed by newline. Odd elements must be PSTR pointers. -#define __SELP_N_P(N,V...) _SELP_##N##_P(V) -#define _SELP_N_P(N,V...) __SELP_N_P(N,V) -#define _SELP_N_P_REF() _SELP_N_P -#define _SELP_1_P(p) serial_println_P(p) -#define _SELP_2_P(p,v) serial_echolnpair_P(p,v) -#define _SELP_3_P(p,v,V...) { _SEP_2_P(p,v); DEFER2(_SELP_N_P_REF)()(TWO_ARGS(V),V); } -#define SERIAL_ECHOLNPGM_P(V...) do{ EVAL(_SELP_N_P(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values. Odd elements must be FSTR_P, F(), or FPSTR(). -#define __SEP_N_F(N,V...) _SEP_##N##_F(V) -#define _SEP_N_F(N,V...) __SEP_N_F(N,V) -#define _SEP_N_F_REF() _SEP_N_F -#define _SEP_1_F(p) serial_print(p); -#define _SEP_2_F(p,v) serial_echopair(p,v); -#define _SEP_3_F(p,v,V...) _SEP_2_F(p,v); DEFER2(_SEP_N_F_REF)()(TWO_ARGS(V),V); -#define SERIAL_ECHOF(V...) do{ EVAL(_SEP_N_F(TWO_ARGS(V),V)); }while(0) - -// Print up to 20 pairs of values followed by newline. Odd elements must be FSTR_P, F(), or FPSTR(). -#define __SELP_N_F(N,V...) _SELP_##N##_F(V) -#define _SELP_N_F(N,V...) __SELP_N_F(N,V) -#define _SELP_N_F_REF() _SELP_N_F -#define _SELP_1_F(p) serial_println(p) -#define _SELP_2_F(p,v) serial_echolnpair(p,v) -#define _SELP_3_F(p,v,V...) { _SEP_2_F(p,v); DEFER2(_SELP_N_F_REF)()(TWO_ARGS(V),V); } -#define SERIAL_ECHOLNF(V...) do{ EVAL(_SELP_N_F(TWO_ARGS(V),V)); }while(0) - -#ifdef AllowDifferentTypeInList - - inline void SERIAL_ECHOLIST_IMPL() {} - template - void SERIAL_ECHOLIST_IMPL(T && t) { SERIAL_IMPL.print(t); } - - template - void SERIAL_ECHOLIST_IMPL(T && t, Args && ... args) { - SERIAL_IMPL.print(t); - serial_print(F(", ")); - SERIAL_ECHOLIST_IMPL(args...); - } - - template - void SERIAL_ECHOLIST(FSTR_P const str, Args && ... args) { - SERIAL_IMPL.print(FTOP(str)); - SERIAL_ECHOLIST_IMPL(args...); - } - -#else // Optimization if the listed type are all the same (seems to be the case in the codebase so use that instead) - - template - void SERIAL_ECHOLIST(FSTR_P const fstr, Args && ... args) { - serial_print(fstr); - typename Private::first_type_of::type values[] = { args... }; - constexpr size_t argsSize = sizeof...(args); - for (size_t i = 0; i < argsSize; i++) { - if (i) serial_print(F(", ")); - SERIAL_IMPL.print(values[i]); - } - } - -#endif - -// SERIAL_ECHO_F prints a floating point value with optional precision -inline void SERIAL_ECHO_F(EnsureDouble x, int digit=2) { SERIAL_IMPL.print(x, digit); } - -#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serial_print_P(P); SERIAL_ECHO_F(V); }while(0) -#define SERIAL_ECHOLNPAIR_F_P(P,V...) do{ SERIAL_ECHOPAIR_F_P(P,V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHOPAIR_F_F(S,V...) do{ serial_print(S); SERIAL_ECHO_F(V); }while(0) -#define SERIAL_ECHOLNPAIR_F_F(S,V...) do{ SERIAL_ECHOPAIR_F_F(S,V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_F(F(S),V) -#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0) - -#define SERIAL_ECHO_MSG(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0) -#define SERIAL_ERROR_MSG(V...) do{ SERIAL_ERROR_START(); SERIAL_ECHOLNPGM(V); }while(0) - -#define SERIAL_ECHO_SP(C) serial_spaces(C) - -#define SERIAL_ECHO_TERNARY(TF, PRE, ON, OFF, POST) serial_ternary(TF, F(PRE), F(ON), F(OFF), F(POST)) - -#if SERIAL_FLOAT_PRECISION - #define SERIAL_DECIMAL(V) SERIAL_PRINT(V, SERIAL_FLOAT_PRECISION) -#else - #define SERIAL_DECIMAL(V) SERIAL_ECHO(V) -#endif - -// -// Functions for serial printing from PROGMEM. (Saves loads of SRAM.) -// -inline void serial_echopair_P(PGM_P const pstr, serial_char_t v) { serial_print_P(pstr); SERIAL_CHAR(v.c); } -inline void serial_echopair_P(PGM_P const pstr, float v) { serial_print_P(pstr); SERIAL_DECIMAL(v); } -inline void serial_echopair_P(PGM_P const pstr, double v) { serial_print_P(pstr); SERIAL_DECIMAL(v); } -//inline void serial_echopair_P(PGM_P const pstr, const char *v) { serial_print_P(pstr); SERIAL_ECHO(v); } -inline void serial_echopair_P(PGM_P const pstr, FSTR_P v) { serial_print_P(pstr); SERIAL_ECHOF(v); } - -// Default implementation for types without a specialization. Handles integers. -template -inline void serial_echopair_P(PGM_P const pstr, T v) { serial_print_P(pstr); SERIAL_ECHO(v); } - -// Add a newline. -template -inline void serial_echolnpair_P(PGM_P const pstr, T v) { serial_echopair_P(pstr, v); SERIAL_EOL(); } - -// Catch-all for __FlashStringHelper * -template -inline void serial_echopair(FSTR_P const fstr, T v) { serial_echopair_P(FTOP(fstr), v); } - -// Add a newline to the serial output -template -inline void serial_echolnpair(FSTR_P const fstr, T v) { serial_echolnpair_P(FTOP(fstr), v); } - -void serial_echo_start(); -void serial_error_start(); -void serial_ternary(const bool onoff, FSTR_P const pre, FSTR_P const on, FSTR_P const off, FSTR_P const post=nullptr); -void serialprint_onoff(const bool onoff); -void serialprintln_onoff(const bool onoff); -void serialprint_truefalse(const bool tf); -void serial_spaces(uint8_t count); -void serial_offset(const_float_t v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2) - -void print_bin(const uint16_t val); -void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); - -inline void print_pos(const xyz_pos_t &xyz, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) { - print_pos(NUM_AXIS_ELEM(xyz), prefix, suffix); -} - -#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0) -#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, F(PREFIX)); }while(0) - -// -// Commonly-used strings in serial output -// - -#define _N_STR(N) N##_STR -#define _N_LBL(N) N##_LBL -#define _N_STR_A(N) _N_STR(N)[] -#define _N_LBL_A(N) _N_LBL(N)[] -#define _SP_N_STR(N) SP_##N##_STR -#define _SP_N_LBL(N) SP_##N##_LBL -#define _SP_N_STR_A(N) _SP_N_STR(N)[] -#define _SP_N_LBL_A(N) _SP_N_LBL(N)[] - -extern const char SP_A_STR[], SP_B_STR[], SP_C_STR[], SP_P_STR[], SP_T_STR[], NUL_STR[], - MAPLIST(_N_STR_A, LOGICAL_AXIS_NAMES), MAPLIST(_SP_N_STR_A, LOGICAL_AXIS_NAMES), - MAPLIST(_N_LBL_A, LOGICAL_AXIS_NAMES), MAPLIST(_SP_N_LBL_A, LOGICAL_AXIS_NAMES); - -PGM_P const SP_AXIS_LBL[] PROGMEM = { MAPLIST(_SP_N_LBL, LOGICAL_AXIS_NAMES) }; -PGM_P const SP_AXIS_STR[] PROGMEM = { MAPLIST(_SP_N_STR, LOGICAL_AXIS_NAMES) }; - -#undef _N_STR -#undef _N_LBL -#undef _N_STR_A -#undef _N_LBL_A -#undef _SP_N_STR -#undef _SP_N_LBL -#undef _SP_N_STR_A -#undef _SP_N_LBL_A diff --git a/src/core/serial_base.h b/src/core/serial_base.h deleted file mode 100644 index a5abd67..0000000 --- a/src/core/serial_base.h +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - #include "../feature/e_parser.h" -#endif - -// Used in multiple places -// You can build it but not manipulate it. -// There are only few places where it's required to access the underlying member: GCodeQueue, SerialMask and MultiSerial -struct serial_index_t { - // A signed index, where -1 is a special case meaning no action (neither output or input) - int8_t index; - - // Check if the index is within the range [a ... b] - constexpr inline bool within(const int8_t a, const int8_t b) const { return WITHIN(index, a, b); } - constexpr inline bool valid() const { return WITHIN(index, 0, 7); } // At most, 8 bits - - // Construction is either from an index - constexpr serial_index_t(const int8_t index) : index(index) {} - - // Default to "no index" - constexpr serial_index_t() : index(-1) {} -}; - -// In order to catch usage errors in code, we make the base to encode number explicit -// If given a number (and not this enum), the compiler will reject the overload, falling back to the (double, digit) version -// We don't want hidden conversion of the first parameter to double, so it has to be as hard to do for the compiler as creating this enum -enum class PrintBase { - Dec = 10, - Hex = 16, - Oct = 8, - Bin = 2 -}; - -// A simple feature list enumeration -enum class SerialFeature { - None = 0x00, - MeatPack = 0x01, //!< Enabled when Meatpack is present - BinaryFileTransfer = 0x02, //!< Enabled for BinaryFile transfer support (in the future) - Virtual = 0x04, //!< Enabled for virtual serial port (like Telnet / Websocket / ...) - Hookable = 0x08, //!< Enabled if the serial class supports a setHook method -}; -ENUM_FLAGS(SerialFeature); - -// flushTX is not implemented in all HAL, so use SFINAE to call the method where it is. -CALL_IF_EXISTS_IMPL(void, flushTX); -CALL_IF_EXISTS_IMPL(bool, connected, true); -CALL_IF_EXISTS_IMPL(SerialFeature, features, SerialFeature::None); - -// A simple forward struct to prevent the compiler from selecting print(double, int) as a default overload -// for any type other than double/float. For double/float, a conversion exists so the call will be invisible. -struct EnsureDouble { - double a; - operator double() { return a; } - // If the compiler breaks on ambiguity here, it's likely because print(X, base) is called with X not a double/float, and - // a base that's not a PrintBase value. This code is made to detect the error. You MUST set a base explicitly like this: - // SERIAL_PRINT(v, PrintBase::Hex) - EnsureDouble(double a) : a(a) {} - EnsureDouble(float a) : a(a) {} -}; - -// Using Curiously-Recurring Template Pattern here to avoid virtual table cost when compiling. -// Since the real serial class is known at compile time, this results in the compiler writing -// a completely efficient code. -template -struct SerialBase { - #if ENABLED(EMERGENCY_PARSER) - const bool ep_enabled; - EmergencyParser::State emergency_state; - inline bool emergency_parser_enabled() { return ep_enabled; } - SerialBase(bool ep_capable) : ep_enabled(ep_capable), emergency_state(EmergencyParser::State::EP_RESET) {} - #else - SerialBase(const bool) {} - #endif - - #define SerialChild static_cast(this) - - // Static dispatch methods below: - // The most important method here is where it all ends to: - void write(uint8_t c) { SerialChild->write(c); } - - // Called when the parser finished processing an instruction, usually build to nothing - void msgDone() const { SerialChild->msgDone(); } - - // Called on initialization - void begin(const long baudRate) { SerialChild->begin(baudRate); } - - // Called on destruction - void end() { SerialChild->end(); } - - /** Check for available data from the port - @param index The port index, usually 0 */ - int available(serial_index_t index=0) const { return SerialChild->available(index); } - - /** Read a value from the port - @param index The port index, usually 0 */ - int read(serial_index_t index=0) { return SerialChild->read(index); } - - /** Combine the features of this serial instance and return it - @param index The port index, usually 0 */ - SerialFeature features(serial_index_t index=0) const { return static_cast(this)->features(index); } - - // Check if the serial port has a feature - bool has_feature(serial_index_t index, SerialFeature flag) const { return (features(index) & flag) != SerialFeature::None; } - - // Check if the serial port is connected (usually bypassed) - bool connected() const { return SerialChild->connected(); } - - // Redirect flush - void flush() { SerialChild->flush(); } - - // Not all implementation have a flushTX, so let's call them only if the child has the implementation - void flushTX() { CALL_IF_EXISTS(void, SerialChild, flushTX); } - - // Glue code here - void write(const char *str) { while (*str) write(*str++); } - void write(const uint8_t *buffer, size_t size) { while (size--) write(*buffer++); } - void print(char *str) { write(str); } - void print(const char *str) { write(str); } - // No default argument to avoid ambiguity - - // Define print for every fundamental integer type, to ensure that all redirect properly - // to the correct underlying implementation. - - // Prints are performed with a single size, to avoid needing multiple print functions. - // The fixed integer size used for prints will be the larger of long or a pointer. - #if __LONG_WIDTH__ >= __INTPTR_WIDTH__ - typedef long int_fixed_print_t; - typedef unsigned long uint_fixed_print_t; - #else - typedef intptr_t int_fixed_print_t; - typedef uintptr_t uint_fixed_print_t; - - FORCE_INLINE void print(intptr_t c, PrintBase base) { printNumber_signed(c, base); } - FORCE_INLINE void print(uintptr_t c, PrintBase base) { printNumber_unsigned(c, base); } - #endif - - FORCE_INLINE void print(char c, PrintBase base) { printNumber_signed(c, base); } - FORCE_INLINE void print(short c, PrintBase base) { printNumber_signed(c, base); } - FORCE_INLINE void print(int c, PrintBase base) { printNumber_signed(c, base); } - FORCE_INLINE void print(long c, PrintBase base) { printNumber_signed(c, base); } - FORCE_INLINE void print(unsigned char c, PrintBase base) { printNumber_unsigned(c, base); } - FORCE_INLINE void print(unsigned short c, PrintBase base) { printNumber_unsigned(c, base); } - FORCE_INLINE void print(unsigned int c, PrintBase base) { printNumber_unsigned(c, base); } - FORCE_INLINE void print(unsigned long c, PrintBase base) { printNumber_unsigned(c, base); } - - - void print(EnsureDouble c, int digits) { printFloat(c, digits); } - - // Forward the call to the former's method - - // Default implementation for anything without a specialization - // This handles integers since they are the most common - template - void print(T c) { print(c, PrintBase::Dec); } - - void print(float c) { print(c, 2); } - void print(double c) { print(c, 2); } - - void println(char *s) { print(s); println(); } - void println(const char *s) { print(s); println(); } - void println(float c, int digits) { print(c, digits); println(); } - void println(double c, int digits) { print(c, digits); println(); } - void println() { write('\r'); write('\n'); } - - // Default implementations for types without a specialization. Handles integers. - template - void println(T c, PrintBase base) { print(c, base); println(); } - - template - void println(T c) { println(c, PrintBase::Dec); } - - // Forward the call to the former's method - void println(float c) { println(c, 2); } - void println(double c) { println(c, 2); } - - // Print a number with the given base - NO_INLINE void printNumber_unsigned(uint_fixed_print_t n, PrintBase base) { - if (n) { - unsigned char buf[8 * sizeof(long)]; // Enough space for base 2 - int8_t i = 0; - while (n) { - buf[i++] = n % (uint_fixed_print_t)base; - n /= (uint_fixed_print_t)base; - } - while (i--) write((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10))); - } - else write('0'); - } - - NO_INLINE void printNumber_signed(int_fixed_print_t n, PrintBase base) { - if (base == PrintBase::Dec && n < 0) { - n = -n; // This works because all platforms Marlin's builds on are using 2-complement encoding for negative number - // On such CPU, changing the sign of a number is done by inverting the bits and adding one, so if n = 0x80000000 = -2147483648 then - // -n = 0x7FFFFFFF + 1 => 0x80000000 = 2147483648 (if interpreted as unsigned) or -2147483648 if interpreted as signed. - // On non 2-complement CPU, there would be no possible representation for 2147483648. - write('-'); - } - printNumber_unsigned((uint_fixed_print_t)n , base); - } - - // Print a decimal number - NO_INLINE void printFloat(double number, uint8_t digits) { - // Handle negative numbers - if (number < 0.0) { - write('-'); - number = -number; - } - - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - LOOP_L_N(i, digits) rounding *= 0.1; - number += rounding; - - // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - printNumber_unsigned(int_part, PrintBase::Dec); - - // Print the decimal point, but only if there are digits beyond - if (digits) { - write('.'); - // Extract digits from the remainder one at a time - while (digits--) { - remainder *= 10.0; - unsigned long toPrint = (unsigned long)remainder; - printNumber_unsigned(toPrint, PrintBase::Dec); - remainder -= toPrint; - } - } - } -}; - -// All serial instances will be built by chaining the features required -// for the function in the form of a template type definition. diff --git a/src/core/serial_hook.h b/src/core/serial_hook.h deleted file mode 100644 index 65c553c..0000000 --- a/src/core/serial_hook.h +++ /dev/null @@ -1,308 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "serial_base.h" - -// A mask containing a bitmap of the serial port to act upon -// This is written to ensure a serial index is never used as a serial mask -class SerialMask { - uint8_t mask; - - // This constructor is private to ensure you can't convert an index to a mask - // The compiler will stop here if you are mixing index and mask in your code. - // If you need to, you'll have to use the explicit static "from" method here - SerialMask(const serial_index_t); - -public: - inline constexpr bool enabled(const SerialMask PortMask) const { return mask & PortMask.mask; } - inline constexpr SerialMask combine(const SerialMask other) const { return SerialMask(mask | other.mask); } - inline constexpr SerialMask operator<< (const int offset) const { return SerialMask(mask << offset); } - static SerialMask from(const serial_index_t index) { - if (index.valid()) return SerialMask(_BV(index.index)); - return SerialMask(0); // A invalid index mean no output - } - - constexpr SerialMask(const uint8_t mask) : mask(mask) {} - constexpr SerialMask(const SerialMask &rs) : mask(rs.mask) {} // Can't use = default here since not all frameworks support this - - SerialMask& operator=(const SerialMask &rs) { mask = rs.mask; return *this; } - - static constexpr uint8_t All = 0xFF; -}; - -// The most basic serial class: it dispatch to the base serial class with no hook whatsoever. This will compile to nothing but the base serial class -template -struct BaseSerial : public SerialBase< BaseSerial >, public SerialT { - typedef SerialBase< BaseSerial > BaseClassT; - - // It's required to implement a write method here to help compiler disambiguate what method to call - using SerialT::write; - using SerialT::flush; - - void msgDone() {} - - // We don't care about indices here, since if one can call us, it's the right index anyway - int available(serial_index_t) { return (int)SerialT::available(); } - int read(serial_index_t) { return (int)SerialT::read(); } - bool connected() { return CALL_IF_EXISTS(bool, static_cast(this), connected);; } - void flushTX() { CALL_IF_EXISTS(void, static_cast(this), flushTX); } - - SerialFeature features(serial_index_t index) const { return CALL_IF_EXISTS(SerialFeature, static_cast(this), features, index); } - - // Two implementations of the same method exist in both base classes so indicate the right one - using SerialT::available; - using SerialT::read; - using SerialT::begin; - using SerialT::end; - - using BaseClassT::print; - using BaseClassT::println; - - BaseSerial(const bool e) : BaseClassT(e) {} - - // Forward constructor - template - BaseSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...) {} -}; - -// A serial with a condition checked at runtime for its output -// A bit less efficient than static dispatching but since it's only used for ethernet's serial output right now, it's ok. -template -struct ConditionalSerial : public SerialBase< ConditionalSerial > { - typedef SerialBase< ConditionalSerial > BaseClassT; - - bool & condition; - SerialT & out; - NO_INLINE size_t write(uint8_t c) { if (condition) return out.write(c); return 0; } - void flush() { if (condition) out.flush(); } - void begin(long br) { out.begin(br); } - void end() { out.end(); } - - void msgDone() {} - bool connected() { return CALL_IF_EXISTS(bool, &out, connected); } - void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); } - - int available(serial_index_t) { return (int)out.available(); } - int read(serial_index_t) { return (int)out.read(); } - int available() { return (int)out.available(); } - int read() { return (int)out.read(); } - SerialFeature features(serial_index_t index) const { return CALL_IF_EXISTS(SerialFeature, &out, features, index); } - - ConditionalSerial(bool & conditionVariable, SerialT & out, const bool e) : BaseClassT(e), condition(conditionVariable), out(out) {} -}; - -// A simple forward class that taking a reference to an existing serial instance (likely created in their respective framework) -template -struct ForwardSerial : public SerialBase< ForwardSerial > { - typedef SerialBase< ForwardSerial > BaseClassT; - - SerialT & out; - NO_INLINE size_t write(uint8_t c) { return out.write(c); } - void flush() { out.flush(); } - void begin(long br) { out.begin(br); } - void end() { out.end(); } - - void msgDone() {} - // Existing instances implement Arduino's operator bool, so use that if it's available - bool connected() { return Private::HasMember_connected::value ? CALL_IF_EXISTS(bool, &out, connected) : (bool)out; } - void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); } - - int available(serial_index_t) { return (int)out.available(); } - int read(serial_index_t) { return (int)out.read(); } - int available() { return (int)out.available(); } - int read() { return (int)out.read(); } - SerialFeature features(serial_index_t index) const { return CALL_IF_EXISTS(SerialFeature, &out, features, index); } - - ForwardSerial(const bool e, SerialT & out) : BaseClassT(e), out(out) {} -}; - -// A class that can be hooked and unhooked at runtime, useful to capture the output of the serial interface -template -struct RuntimeSerial : public SerialBase< RuntimeSerial >, public SerialT { - typedef SerialBase< RuntimeSerial > BaseClassT; - typedef void (*WriteHook)(void * userPointer, uint8_t c); - typedef void (*EndOfMessageHook)(void * userPointer); - - WriteHook writeHook; - EndOfMessageHook eofHook; - void * userPointer; - - NO_INLINE size_t write(uint8_t c) { - if (writeHook) writeHook(userPointer, c); - return SerialT::write(c); - } - - NO_INLINE void msgDone() { - if (eofHook) eofHook(userPointer); - } - - int available(serial_index_t) { return (int)SerialT::available(); } - int read(serial_index_t) { return (int)SerialT::read(); } - using SerialT::available; - using SerialT::read; - using SerialT::flush; - using SerialT::begin; - using SerialT::end; - - using BaseClassT::print; - using BaseClassT::println; - - // Underlying implementation might use Arduino's bool operator - bool connected() { - return Private::HasMember_connected::value - ? CALL_IF_EXISTS(bool, static_cast(this), connected) - : static_cast(this)->operator bool(); - } - - void flushTX() { CALL_IF_EXISTS(void, static_cast(this), flushTX); } - - // Append Hookable for this class - SerialFeature features(serial_index_t index) const { return SerialFeature::Hookable | CALL_IF_EXISTS(SerialFeature, static_cast(this), features, index); } - - void setHook(WriteHook writeHook = 0, EndOfMessageHook eofHook = 0, void * userPointer = 0) { - // Order is important here as serial code can be called inside interrupts - // When setting a hook, the user pointer must be set first so if writeHook is called as soon as it's set, it'll be valid - if (userPointer) this->userPointer = userPointer; - this->writeHook = writeHook; - this->eofHook = eofHook; - // Order is important here because of asynchronous access here - // When unsetting a hook, the user pointer must be unset last so that any pending writeHook is still using the old pointer - if (!userPointer) this->userPointer = 0; - } - - RuntimeSerial(const bool e) : BaseClassT(e), writeHook(0), eofHook(0), userPointer(0) {} - - // Forward constructor - template - RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {} -}; - -#define _S_CLASS(N) class Serial##N##T, -#define _S_NAME(N) Serial##N##T, - -template < REPEAT(NUM_SERIAL, _S_CLASS) const uint8_t offset=0, const uint8_t step=1 > -struct MultiSerial : public SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > { - typedef SerialBase< MultiSerial< REPEAT(NUM_SERIAL, _S_NAME) offset, step > > BaseClassT; - - #undef _S_CLASS - #undef _S_NAME - - SerialMask portMask; - - #define _S_DECLARE(N) Serial##N##T & serial##N; - REPEAT(NUM_SERIAL, _S_DECLARE); - #undef _S_DECLARE - - static constexpr uint8_t Usage = _BV(step) - 1; // A bit mask containing 'step' bits - - #define _OUT_PORT(N) (Usage << (offset + (step * N))), - static constexpr uint8_t output[] = { REPEAT(NUM_SERIAL, _OUT_PORT) }; - #undef _OUT_PORT - - #define _OUT_MASK(N) | output[N] - static constexpr uint8_t ALL = 0 REPEAT(NUM_SERIAL, _OUT_MASK); - #undef _OUT_MASK - - NO_INLINE void write(uint8_t c) { - #define _S_WRITE(N) if (portMask.enabled(output[N])) serial##N.write(c); - REPEAT(NUM_SERIAL, _S_WRITE); - #undef _S_WRITE - } - NO_INLINE void msgDone() { - #define _S_DONE(N) if (portMask.enabled(output[N])) serial##N.msgDone(); - REPEAT(NUM_SERIAL, _S_DONE); - #undef _S_DONE - } - int available(serial_index_t index) { - uint8_t pos = offset; - #define _S_AVAILABLE(N) if (index.within(pos, pos + step - 1)) return serial##N.available(index); else pos += step; - REPEAT(NUM_SERIAL, _S_AVAILABLE); - #undef _S_AVAILABLE - return false; - } - int read(serial_index_t index) { - uint8_t pos = offset; - #define _S_READ(N) if (index.within(pos, pos + step - 1)) return serial##N.read(index); else pos += step; - REPEAT(NUM_SERIAL, _S_READ); - #undef _S_READ - return -1; - } - void begin(const long br) { - #define _S_BEGIN(N) if (portMask.enabled(output[N])) serial##N.begin(br); - REPEAT(NUM_SERIAL, _S_BEGIN); - #undef _S_BEGIN - } - void end() { - #define _S_END(N) if (portMask.enabled(output[N])) serial##N.end(); - REPEAT(NUM_SERIAL, _S_END); - #undef _S_END - } - bool connected() { - bool ret = true; - #define _S_CONNECTED(N) if (portMask.enabled(output[N]) && !CALL_IF_EXISTS(bool, &serial##N, connected)) ret = false; - REPEAT(NUM_SERIAL, _S_CONNECTED); - #undef _S_CONNECTED - return ret; - } - - using BaseClassT::available; - using BaseClassT::read; - - // Redirect flush - NO_INLINE void flush() { - #define _S_FLUSH(N) if (portMask.enabled(output[N])) serial##N.flush(); - REPEAT(NUM_SERIAL, _S_FLUSH); - #undef _S_FLUSH - } - NO_INLINE void flushTX() { - #define _S_FLUSHTX(N) if (portMask.enabled(output[N])) CALL_IF_EXISTS(void, &serial0, flushTX); - REPEAT(NUM_SERIAL, _S_FLUSHTX); - #undef _S_FLUSHTX - } - - // Forward feature queries - SerialFeature features(serial_index_t index) const { - uint8_t pos = offset; - #define _S_FEATURES(N) if (index.within(pos, pos + step - 1)) return serial##N.features(index); else pos += step; - REPEAT(NUM_SERIAL, _S_FEATURES); - #undef _S_FEATURES - return SerialFeature::None; - } - - #define _S_REFS(N) Serial##N##T & serial##N, - #define _S_INIT(N) ,serial##N (serial##N) - - MultiSerial(REPEAT(NUM_SERIAL, _S_REFS) const SerialMask mask = ALL, const bool e = false) - : BaseClassT(e), portMask(mask) REPEAT(NUM_SERIAL, _S_INIT) {} - -}; - -// Build the actual serial object depending on current configuration -#define Serial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, BaseSerial) -#define ForwardSerial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial) -#if HAS_MULTI_SERIAL - #define Serial2Class ConditionalSerial - #if NUM_SERIAL >= 3 - #define Serial3Class ConditionalSerial - #endif -#endif diff --git a/src/core/types.h b/src/core/types.h deleted file mode 100644 index e3c4b9e..0000000 --- a/src/core/types.h +++ /dev/null @@ -1,743 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include -#include - -#include "../inc/MarlinConfigPre.h" - -// -// Conditional type assignment magic. For example... -// -// typename IF<(MYOPT==12), int, float>::type myvar; -// -template -struct IF { typedef R type; }; -template -struct IF { typedef L type; }; - -#define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V) -#define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V) -#define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V) -#define NUM_AXIS_LIST_1(V) LIST_N_1(NUM_AXES, V) -#define NUM_AXIS_ARRAY(V...) { NUM_AXIS_LIST(V) } -#define NUM_AXIS_ARRAY_1(V) { NUM_AXIS_LIST_1(V) } -#define NUM_AXIS_ARGS(T...) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k) -#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k) -#define NUM_AXIS_DEFS(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V) - -#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K) -#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES) -#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K) - -#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E) -#define LOGICAL_AXIS_CODE(E,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(E) -#define LOGICAL_AXIS_LIST(E,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(E) -#define LOGICAL_AXIS_LIST_1(V) NUM_AXIS_LIST_1(V) LIST_ITEM_E(V) -#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) } -#define LOGICAL_AXIS_ARRAY_1(V) { LOGICAL_AXIS_LIST_1(V) } -#define LOGICAL_AXIS_ARGS(T...) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k) -#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k) -#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V) - -#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K) -#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES) - -#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K) - -#define XYZ_GANG(V...) GANG_N(PRIMARY_LINEAR_AXES, V) -#define XYZ_CODE(V...) CODE_N(PRIMARY_LINEAR_AXES, V) - -#define SECONDARY_AXIS_GANG(V...) GANG_N(SECONDARY_AXES, V) -#define SECONDARY_AXIS_CODE(V...) CODE_N(SECONDARY_AXES, V) - -#if HAS_EXTRUDERS - #define LIST_ITEM_E(N) , N - #define CODE_ITEM_E(N) ; N - #define GANG_ITEM_E(N) N -#else - #define LIST_ITEM_E(N) - #define CODE_ITEM_E(N) - #define GANG_ITEM_E(N) -#endif - -#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L) - -// General Flags for some number of states -template -struct Flags { - typedef typename IF<(N>8), uint16_t, uint8_t>::type bits_t; - typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8; - typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1; } N16; - union { - bits_t b; - typename IF<(N>8), N16, N8>::type flag; - }; - void reset() { b = 0; } - void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); } - void set(const int n) { b |= (bits_t)_BV(n); } - void clear(const int n) { b &= ~(bits_t)_BV(n); } - bool test(const int n) const { return TEST(b, n); } - const bool operator[](const int n) { return test(n); } - const bool operator[](const int n) const { return test(n); } - int size() const { return sizeof(b); } -}; - -// Specialization for a single bool flag -template<> -struct Flags<1> { - bool b; - void reset() { b = false; } - void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); } - void set(const int) { b = true; } - void clear(const int) { b = false; } - bool test(const int) const { return b; } - bool& operator[](const int) { return b; } - bool operator[](const int) const { return b; } - int size() const { return sizeof(b); } -}; - -typedef Flags<8> flags_8_t; -typedef Flags<16> flags_16_t; - -// Flags for some axis states, with per-axis aliases xyzijkuvwe -typedef struct AxisFlags { - union { - struct Flags flags; - struct { bool LOGICAL_AXIS_LIST(e:1, x:1, y:1, z:1, i:1, j:1, k:1, u:1, v:1, w:1); }; - }; - void reset() { flags.reset(); } - void set(const int n) { flags.set(n); } - void set(const int n, const bool onoff) { flags.set(n, onoff); } - void clear(const int n) { flags.clear(n); } - bool test(const int n) const { return flags.test(n); } - bool operator[](const int n) { return flags[n]; } - bool operator[](const int n) const { return flags[n]; } - int size() const { return sizeof(flags); } -} axis_flags_t; - -// -// Enumerated axis indices -// -// - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space -// - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians -// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics -// -enum AxisEnum : uint8_t { - - // Linear axes may be controlled directly or indirectly - NUM_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS) - - // Extruder axes may be considered distinctly - #define _EN_ITEM(N) , E##N##_AXIS - REPEAT(EXTRUDERS, _EN_ITEM) - #undef _EN_ITEM - - // Core also keeps toolhead directions - #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) - , X_HEAD, Y_HEAD, Z_HEAD - #endif - - // Distinct axes, including all E and Core - , NUM_AXIS_ENUMS - - // Most of the time we refer only to the single E_AXIS - #if HAS_EXTRUDERS - , E_AXIS = E0_AXIS - #endif - - // A, B, and C are for DELTA, SCARA, etc. - , A_AXIS = X_AXIS - #if HAS_Y_AXIS - , B_AXIS = Y_AXIS - #endif - #if HAS_Z_AXIS - , C_AXIS = Z_AXIS - #endif - - // To refer to all or none - , ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF -}; - -typedef IF<(NUM_AXIS_ENUMS > 8), uint16_t, uint8_t>::type axis_bits_t; - -// -// Loop over axes -// -#define LOOP_ABC(VAR) LOOP_S_LE_N(VAR, A_AXIS, C_AXIS) -#define LOOP_NUM_AXES(VAR) LOOP_S_L_N(VAR, X_AXIS, NUM_AXES) -#define LOOP_LOGICAL_AXES(VAR) LOOP_S_L_N(VAR, X_AXIS, LOGICAL_AXES) -#define LOOP_DISTINCT_AXES(VAR) LOOP_S_L_N(VAR, X_AXIS, DISTINCT_AXES) -#define LOOP_DISTINCT_E(VAR) LOOP_L_N(VAR, DISTINCT_E) - -// -// feedRate_t is just a humble float -// -typedef float feedRate_t; - -// -// celsius_t is the native unit of temperature. Signed to handle a disconnected thermistor value (-14). -// For more resolition (e.g., for a chocolate printer) this may later be changed to Celsius x 100 -// -typedef uint16_t raw_adc_t; -typedef int16_t celsius_t; -typedef float celsius_float_t; - -// -// On AVR pointers are only 2 bytes so use 'const float &' for 'const float' -// -#ifdef __AVR__ - typedef const float & const_float_t; -#else - typedef const float const_float_t; -#endif -typedef const_float_t const_feedRate_t; -typedef const_float_t const_celsius_float_t; - -// Conversion macros -#define MMM_TO_MMS(MM_M) feedRate_t(static_cast(MM_M) / 60.0f) -#define MMS_TO_MMM(MM_S) (static_cast(MM_S) * 60.0f) - -// -// Coordinates structures for XY, XYZ, XYZE... -// - -// Helpers -#define _RECIP(N) ((N) ? 1.0f / static_cast(N) : 0.0f) -#define _ABS(N) ((N) < 0 ? -(N) : (N)) -#define _LS(N) (N = (T)(uint32_t(N) << v)) -#define _RS(N) (N = (T)(uint32_t(N) >> v)) -#define FI FORCE_INLINE - -// Forward declarations -template struct XYval; -template struct XYZval; -template struct XYZEval; - -typedef struct XYval xy_bool_t; -typedef struct XYZval xyz_bool_t; -typedef struct XYZEval xyze_bool_t; - -typedef struct XYval xy_char_t; -typedef struct XYZval xyz_char_t; -typedef struct XYZEval xyze_char_t; - -typedef struct XYval xy_uchar_t; -typedef struct XYZval xyz_uchar_t; -typedef struct XYZEval xyze_uchar_t; - -typedef struct XYval xy_int8_t; -typedef struct XYZval xyz_int8_t; -typedef struct XYZEval xyze_int8_t; - -typedef struct XYval xy_uint8_t; -typedef struct XYZval xyz_uint8_t; -typedef struct XYZEval xyze_uint8_t; - -typedef struct XYval xy_int_t; -typedef struct XYZval xyz_int_t; -typedef struct XYZEval xyze_int_t; - -typedef struct XYval xy_uint_t; -typedef struct XYZval xyz_uint_t; -typedef struct XYZEval xyze_uint_t; - -typedef struct XYval xy_long_t; -typedef struct XYZval xyz_long_t; -typedef struct XYZEval xyze_long_t; - -typedef struct XYval xy_ulong_t; -typedef struct XYZval xyz_ulong_t; -typedef struct XYZEval xyze_ulong_t; - -typedef struct XYZval xyz_vlong_t; -typedef struct XYZEval xyze_vlong_t; - -typedef struct XYval xy_float_t; -typedef struct XYZval xyz_float_t; -typedef struct XYZEval xyze_float_t; - -typedef struct XYval xy_feedrate_t; -typedef struct XYZval xyz_feedrate_t; -typedef struct XYZEval xyze_feedrate_t; - -typedef xy_uint8_t xy_byte_t; -typedef xyz_uint8_t xyz_byte_t; -typedef xyze_uint8_t xyze_byte_t; - -typedef xyz_long_t abc_long_t; -typedef xyze_long_t abce_long_t; -typedef xyz_ulong_t abc_ulong_t; -typedef xyze_ulong_t abce_ulong_t; - -typedef xy_float_t xy_pos_t; -typedef xyz_float_t xyz_pos_t; -typedef xyze_float_t xyze_pos_t; - -typedef xy_float_t ab_float_t; -typedef xyz_float_t abc_float_t; -typedef xyze_float_t abce_float_t; - -typedef ab_float_t ab_pos_t; -typedef abc_float_t abc_pos_t; -typedef abce_float_t abce_pos_t; - -// External conversion methods -void toLogical(xy_pos_t &raw); -void toLogical(xyz_pos_t &raw); -void toLogical(xyze_pos_t &raw); -void toNative(xy_pos_t &raw); -void toNative(xyz_pos_t &raw); -void toNative(xyze_pos_t &raw); - -// -// Paired XY coordinates, counters, flags, etc. -// -template -struct XYval { - union { - struct { T x, y; }; - struct { T a, b; }; - T pos[2]; - }; - - // Set all to 0 - FI void reset() { x = y = 0; } - - // Setters taking struct types and arrays - FI void set(const T px) { x = px; } - #if HAS_Y_AXIS - FI void set(const T px, const T py) { x = px; y = py; } - FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } - #endif - #if NUM_AXES > XY - FI void set(const T (&arr)[NUM_AXES]) { x = arr[0]; y = arr[1]; } - #endif - #if LOGICAL_AXES > NUM_AXES - FI void set(const T (&arr)[LOGICAL_AXES]) { x = arr[0]; y = arr[1]; } - #if DISTINCT_AXES > LOGICAL_AXES - FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; } - #endif - #endif - - // Length reduced to one dimension - FI T magnitude() const { return (T)sqrtf(x*x + y*y); } - // Pointer to the data as a simple array - FI operator T* () { return pos; } - // If any element is true then it's true - FI operator bool() { return x || y; } - - // Explicit copy and copies with conversion - FI XYval copy() const { return *this; } - FI XYval ABS() const { return { T(_ABS(x)), T(_ABS(y)) }; } - FI XYval asInt() { return { int16_t(x), int16_t(y) }; } - FI XYval asInt() const { return { int16_t(x), int16_t(y) }; } - FI XYval asLong() { return { int32_t(x), int32_t(y) }; } - FI XYval asLong() const { return { int32_t(x), int32_t(y) }; } - FI XYval ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } - FI XYval ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)) }; } - FI XYval asFloat() { return { static_cast(x), static_cast(y) }; } - FI XYval asFloat() const { return { static_cast(x), static_cast(y) }; } - FI XYval reciprocal() const { return { _RECIP(x), _RECIP(y) }; } - - // Marlin workspace shifting is done with G92 and M206 - FI XYval asLogical() const { XYval o = asFloat(); toLogical(o); return o; } - FI XYval asNative() const { XYval o = asFloat(); toNative(o); return o; } - - // Cast to a type with more fields by making a new object - FI operator XYZval() { return { x, y }; } - FI operator XYZval() const { return { x, y }; } - FI operator XYZEval() { return { x, y }; } - FI operator XYZEval() const { return { x, y }; } - - // Accessor via an AxisEnum (or any integer) [index] - FI T& operator[](const int n) { return pos[n]; } - FI const T& operator[](const int n) const { return pos[n]; } - - // Assignment operator overrides do the expected thing - FI XYval& operator= (const T v) { set(v, v ); return *this; } - FI XYval& operator= (const XYZval &rs) { set(rs.x, rs.y); return *this; } - FI XYval& operator= (const XYZEval &rs) { set(rs.x, rs.y); return *this; } - - // Override other operators to get intuitive behaviors - FI XYval operator+ (const XYval &rs) const { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator+ (const XYval &rs) { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator- (const XYval &rs) const { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator- (const XYval &rs) { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator* (const XYval &rs) const { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator* (const XYval &rs) { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator/ (const XYval &rs) const { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator/ (const XYval &rs) { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator+ (const XYZval &rs) const { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator+ (const XYZval &rs) { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator- (const XYZval &rs) const { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator- (const XYZval &rs) { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator* (const XYZval &rs) const { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator* (const XYZval &rs) { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator/ (const XYZval &rs) const { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator/ (const XYZval &rs) { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator+ (const XYZEval &rs) const { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator+ (const XYZEval &rs) { XYval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYval operator- (const XYZEval &rs) const { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator- (const XYZEval &rs) { XYval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYval operator* (const XYZEval &rs) const { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator* (const XYZEval &rs) { XYval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYval operator/ (const XYZEval &rs) const { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator/ (const XYZEval &rs) { XYval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYval operator* (const float &v) const { XYval ls = *this; ls.x *= v; ls.y *= v; return ls; } - FI XYval operator* (const float &v) { XYval ls = *this; ls.x *= v; ls.y *= v; return ls; } - FI XYval operator* (const int &v) const { XYval ls = *this; ls.x *= v; ls.y *= v; return ls; } - FI XYval operator* (const int &v) { XYval ls = *this; ls.x *= v; ls.y *= v; return ls; } - FI XYval operator/ (const float &v) const { XYval ls = *this; ls.x /= v; ls.y /= v; return ls; } - FI XYval operator/ (const float &v) { XYval ls = *this; ls.x /= v; ls.y /= v; return ls; } - FI XYval operator/ (const int &v) const { XYval ls = *this; ls.x /= v; ls.y /= v; return ls; } - FI XYval operator/ (const int &v) { XYval ls = *this; ls.x /= v; ls.y /= v; return ls; } - FI XYval operator>>(const int &v) const { XYval ls = *this; _RS(ls.x); _RS(ls.y); return ls; } - FI XYval operator>>(const int &v) { XYval ls = *this; _RS(ls.x); _RS(ls.y); return ls; } - FI XYval operator<<(const int &v) const { XYval ls = *this; _LS(ls.x); _LS(ls.y); return ls; } - FI XYval operator<<(const int &v) { XYval ls = *this; _LS(ls.x); _LS(ls.y); return ls; } - FI const XYval operator-() const { XYval o = *this; o.x = -x; o.y = -y; return o; } - FI XYval operator-() { XYval o = *this; o.x = -x; o.y = -y; return o; } - - // Modifier operators - FI XYval& operator+=(const XYval &rs) { x += rs.x; y += rs.y; return *this; } - FI XYval& operator-=(const XYval &rs) { x -= rs.x; y -= rs.y; return *this; } - FI XYval& operator*=(const XYval &rs) { x *= rs.x; y *= rs.y; return *this; } - FI XYval& operator+=(const XYZval &rs) { x += rs.x; y += rs.y; return *this; } - FI XYval& operator-=(const XYZval &rs) { x -= rs.x; y -= rs.y; return *this; } - FI XYval& operator*=(const XYZval &rs) { x *= rs.x; y *= rs.y; return *this; } - FI XYval& operator+=(const XYZEval &rs) { x += rs.x; y += rs.y; return *this; } - FI XYval& operator-=(const XYZEval &rs) { x -= rs.x; y -= rs.y; return *this; } - FI XYval& operator*=(const XYZEval &rs) { x *= rs.x; y *= rs.y; return *this; } - FI XYval& operator*=(const float &v) { x *= v; y *= v; return *this; } - FI XYval& operator*=(const int &v) { x *= v; y *= v; return *this; } - FI XYval& operator>>=(const int &v) { _RS(x); _RS(y); return *this; } - FI XYval& operator<<=(const int &v) { _LS(x); _LS(y); return *this; } - - // Exact comparisons. For floats a "NEAR" operation may be better. - FI bool operator==(const XYval &rs) { return x == rs.x && y == rs.y; } - FI bool operator==(const XYZval &rs) { return x == rs.x && y == rs.y; } - FI bool operator==(const XYZEval &rs) { return x == rs.x && y == rs.y; } - FI bool operator==(const XYval &rs) const { return x == rs.x && y == rs.y; } - FI bool operator==(const XYZval &rs) const { return x == rs.x && y == rs.y; } - FI bool operator==(const XYZEval &rs) const { return x == rs.x && y == rs.y; } - FI bool operator!=(const XYval &rs) { return !operator==(rs); } - FI bool operator!=(const XYZval &rs) { return !operator==(rs); } - FI bool operator!=(const XYZEval &rs) { return !operator==(rs); } - FI bool operator!=(const XYval &rs) const { return !operator==(rs); } - FI bool operator!=(const XYZval &rs) const { return !operator==(rs); } - FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } -}; - -// -// Linear Axes coordinates, counters, flags, etc. -// -template -struct XYZval { - union { - struct { T NUM_AXIS_ARGS(); }; - struct { T NUM_AXIS_LIST(a, b, c, _i, _j, _k); }; - T pos[NUM_AXES]; - }; - - // Set all to 0 - FI void reset() { NUM_AXIS_GANG(x =, y =, z =, i =, j =, k =) 0; } - - // Setters taking struct types and arrays - FI void set(const T px) { x = px; } - FI void set(const T px, const T py) { x = px; y = py; } - FI void set(const XYval pxy) { x = pxy.x; y = pxy.y; } - FI void set(const XYval pxy, const T pz) { NUM_AXIS_CODE(x = pxy.x, y = pxy.y, z = pz, NOOP, NOOP, NOOP); } - FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; } - #if HAS_Z_AXIS - FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); } - FI void set(NUM_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k); } - #endif - #if LOGICAL_AXES > NUM_AXES - FI void set(const T (&arr)[LOGICAL_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); } - FI void set(LOGICAL_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k); } - #if DISTINCT_AXES > LOGICAL_AXES - FI void set(const T (&arr)[DISTINCT_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5]); } - #endif - #endif - #if HAS_I_AXIS - FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; } - #endif - #if HAS_J_AXIS - FI void set(const T px, const T py, const T pz, const T pi) { x = px; y = py; z = pz; i = pi; } - #endif - #if HAS_K_AXIS - FI void set(const T px, const T py, const T pz, const T pi, const T pj) { x = px; y = py; z = pz; i = pi; j = pj; } - #endif - - // Length reduced to one dimension - FI T magnitude() const { return (T)sqrtf(NUM_AXIS_GANG(x*x, + y*y, + z*z, + i*i, + j*j, + k*k)); } - // Pointer to the data as a simple array - FI operator T* () { return pos; } - // If any element is true then it's true - FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k); } - - // Explicit copy and copies with conversion - FI XYZval copy() const { XYZval o = *this; return o; } - FI XYZval ABS() const { return NUM_AXIS_ARRAY(T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k))); } - FI XYZval asInt() { return NUM_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } - FI XYZval asInt() const { return NUM_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } - FI XYZval asLong() { return NUM_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } - FI XYZval asLong() const { return NUM_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } - FI XYZval ROUNDL() { return NUM_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } - FI XYZval ROUNDL() const { return NUM_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } - FI XYZval asFloat() { return NUM_AXIS_ARRAY(static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k)); } - FI XYZval asFloat() const { return NUM_AXIS_ARRAY(static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k)); } - FI XYZval reciprocal() const { return NUM_AXIS_ARRAY(_RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k)); } - - // Marlin workspace shifting is done with G92 and M206 - FI XYZval asLogical() const { XYZval o = asFloat(); toLogical(o); return o; } - FI XYZval asNative() const { XYZval o = asFloat(); toNative(o); return o; } - - // In-place cast to types having fewer fields - FI operator XYval&() { return *(XYval*)this; } - FI operator const XYval&() const { return *(const XYval*)this; } - - // Cast to a type with more fields by making a new object - FI operator XYZEval() const { return NUM_AXIS_ARRAY(x, y, z, i, j, k); } - - // Accessor via an AxisEnum (or any integer) [index] - FI T& operator[](const int n) { return pos[n]; } - FI const T& operator[](const int n) const { return pos[n]; } - - // Assignment operator overrides do the expected thing - FI XYZval& operator= (const T v) { set(ARRAY_N_1(NUM_AXES, v)); return *this; } - FI XYZval& operator= (const XYval &rs) { set(rs.x, rs.y ); return *this; } - FI XYZval& operator= (const XYZEval &rs) { set(NUM_AXIS_ELEM(rs)); return *this; } - - // Override other operators to get intuitive behaviors - FI XYZval operator+ (const XYval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator+ (const XYval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator- (const XYval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator- (const XYval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator* (const XYval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator* (const XYval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator/ (const XYval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator/ (const XYval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP , NOOP , NOOP , NOOP ); return ls; } - FI XYZval operator+ (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZval operator+ (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZval operator- (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZval operator- (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZval operator* (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZval operator* (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZval operator/ (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZval operator/ (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZval operator+ (const XYZEval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZval operator+ (const XYZEval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZval operator- (const XYZEval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZval operator- (const XYZEval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZval operator* (const XYZEval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZval operator* (const XYZEval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZval operator/ (const XYZEval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZval operator/ (const XYZEval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZval operator* (const float &v) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZval operator* (const float &v) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZval operator* (const int &v) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZval operator* (const int &v) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZval operator/ (const float &v) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZval operator/ (const float &v) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZval operator/ (const int &v) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZval operator/ (const int &v) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZval operator>>(const int &v) const { XYZval ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } - FI XYZval operator>>(const int &v) { XYZval ls = *this; NUM_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } - FI XYZval operator<<(const int &v) const { XYZval ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } - FI XYZval operator<<(const int &v) { XYZval ls = *this; NUM_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } - FI const XYZval operator-() const { XYZval o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k); return o; } - FI XYZval operator-() { XYZval o = *this; NUM_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z, o.i = -i, o.j = -j, o.k = -k); return o; } - - // Modifier operators - FI XYZval& operator+=(const XYval &rs) { NUM_AXIS_CODE(x += rs.x, y += rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } - FI XYZval& operator-=(const XYval &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } - FI XYZval& operator*=(const XYval &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } - FI XYZval& operator/=(const XYval &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, NOOP, NOOP, NOOP, NOOP ); return *this; } - FI XYZval& operator+=(const XYZval &rs) { NUM_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } - FI XYZval& operator-=(const XYZval &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } - FI XYZval& operator*=(const XYZval &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } - FI XYZval& operator/=(const XYZval &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; } - FI XYZval& operator+=(const XYZEval &rs) { NUM_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } - FI XYZval& operator-=(const XYZEval &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } - FI XYZval& operator*=(const XYZEval &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } - FI XYZval& operator/=(const XYZEval &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; } - FI XYZval& operator*=(const float &v) { NUM_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; } - FI XYZval& operator*=(const int &v) { NUM_AXIS_CODE(x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; } - FI XYZval& operator>>=(const int &v) { NUM_AXIS_CODE(_RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k)); return *this; } - FI XYZval& operator<<=(const int &v) { NUM_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k)); return *this; } - - // Exact comparisons. For floats a "NEAR" operation may be better. - FI bool operator==(const XYZEval &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); } - FI bool operator==(const XYZEval &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); } - FI bool operator!=(const XYZEval &rs) { return !operator==(rs); } - FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } -}; - -// -// Logical Axes coordinates, counters, etc. -// -template -struct XYZEval { - union { - struct { T LOGICAL_AXIS_ARGS(); }; - struct { T LOGICAL_AXIS_LIST(_e, a, b, c, _i, _j, _k); }; - T pos[LOGICAL_AXES]; - }; - // Reset all to 0 - FI void reset() { LOGICAL_AXIS_GANG(e =, x =, y =, z =, i =, j =, k =) 0; } - - // Setters for some number of linear axes, not all - FI void set(const T px) { x = px; } - FI void set(const T px, const T py) { x = px; y = py; } - #if HAS_I_AXIS - FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; } - #endif - #if HAS_J_AXIS - FI void set(const T px, const T py, const T pz, const T pi) { x = px; y = py; z = pz; i = pi; } - #endif - #if HAS_K_AXIS - FI void set(const T px, const T py, const T pz, const T pi, const T pj) { x = px; y = py; z = pz; i = pi; j = pj; } - #endif - // Setters taking struct types and arrays - FI void set(const XYval pxy) { x = pxy.x; y = pxy.y; } - FI void set(const XYZval pxyz) { set(NUM_AXIS_ELEM(pxyz)); } - #if HAS_Z_AXIS - FI void set(NUM_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k); } - #endif - FI void set(const XYval pxy, const T pz) { set(pxy); TERN_(HAS_Z_AXIS, z = pz); } - #if LOGICAL_AXES > NUM_AXES - FI void set(const XYval pxy, const T pz, const T pe) { set(pxy, pz); e = pe; } - FI void set(const XYZval pxyz, const T pe) { set(pxyz); e = pe; } - FI void set(LOGICAL_AXIS_ARGS(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k); } - #endif - - // Length reduced to one dimension - FI T magnitude() const { return (T)sqrtf(LOGICAL_AXIS_GANG(+ e*e, + x*x, + y*y, + z*z, + i*i, + j*j, + k*k)); } - // Pointer to the data as a simple array - FI operator T* () { return pos; } - // If any element is true then it's true - FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k); } - - // Explicit copy and copies with conversion - FI XYZEval copy() const { XYZEval o = *this; return o; } - FI XYZEval ABS() const { return LOGICAL_AXIS_ARRAY(T(_ABS(e)), T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(i)), T(_ABS(j)), T(_ABS(k))); } - FI XYZEval asInt() { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } - FI XYZEval asInt() const { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z), int16_t(i), int16_t(j), int16_t(k)); } - FI XYZEval asLong() { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } - FI XYZEval asLong() const { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z), int32_t(i), int32_t(j), int32_t(k)); } - FI XYZEval ROUNDL() { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } - FI XYZEval ROUNDL() const { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(i)), int32_t(LROUND(j)), int32_t(LROUND(k))); } - FI XYZEval asFloat() { return LOGICAL_AXIS_ARRAY(static_cast(e), static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k)); } - FI XYZEval asFloat() const { return LOGICAL_AXIS_ARRAY(static_cast(e), static_cast(x), static_cast(y), static_cast(z), static_cast(i), static_cast(j), static_cast(k)); } - FI XYZEval reciprocal() const { return LOGICAL_AXIS_ARRAY(_RECIP(e), _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(i), _RECIP(j), _RECIP(k)); } - - // Marlin workspace shifting is done with G92 and M206 - FI XYZEval asLogical() const { XYZEval o = asFloat(); toLogical(o); return o; } - FI XYZEval asNative() const { XYZEval o = asFloat(); toNative(o); return o; } - - // In-place cast to types having fewer fields - FI operator XYval&() { return *(XYval*)this; } - FI operator const XYval&() const { return *(const XYval*)this; } - FI operator XYZval&() { return *(XYZval*)this; } - FI operator const XYZval&() const { return *(const XYZval*)this; } - - // Accessor via an AxisEnum (or any integer) [index] - FI T& operator[](const int n) { return pos[n]; } - FI const T& operator[](const int n) const { return pos[n]; } - - // Assignment operator overrides do the expected thing - FI XYZEval& operator= (const T v) { set(LOGICAL_AXIS_LIST_1(v)); return *this; } - FI XYZEval& operator= (const XYval &rs) { set(rs.x, rs.y); return *this; } - FI XYZEval& operator= (const XYZval &rs) { set(NUM_AXIS_ELEM(rs)); return *this; } - - // Override other operators to get intuitive behaviors - FI XYZEval operator+ (const XYval &rs) const { XYZEval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYZEval operator+ (const XYval &rs) { XYZEval ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; } - FI XYZEval operator- (const XYval &rs) const { XYZEval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYZEval operator- (const XYval &rs) { XYZEval ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; } - FI XYZEval operator* (const XYval &rs) const { XYZEval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYZEval operator* (const XYval &rs) { XYZEval ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; } - FI XYZEval operator/ (const XYval &rs) const { XYZEval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYZEval operator/ (const XYval &rs) { XYZEval ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; } - FI XYZEval operator+ (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZEval operator+ (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZEval operator- (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZEval operator- (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZEval operator* (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZEval operator* (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZEval operator/ (const XYZval &rs) const { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZEval operator/ (const XYZval &rs) { XYZval ls = *this; NUM_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZEval operator+ (const XYZEval &rs) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZEval operator+ (const XYZEval &rs) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z, ls.i += rs.i, ls.j += rs.j, ls.k += rs.k); return ls; } - FI XYZEval operator- (const XYZEval &rs) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZEval operator- (const XYZEval &rs) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z, ls.i -= rs.i, ls.j -= rs.j, ls.k -= rs.k); return ls; } - FI XYZEval operator* (const XYZEval &rs) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZEval operator* (const XYZEval &rs) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z, ls.i *= rs.i, ls.j *= rs.j, ls.k *= rs.k); return ls; } - FI XYZEval operator/ (const XYZEval &rs) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZEval operator/ (const XYZEval &rs) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z, ls.i /= rs.i, ls.j /= rs.j, ls.k /= rs.k); return ls; } - FI XYZEval operator* (const float &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZEval operator* (const float &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZEval operator* (const int &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZEval operator* (const int &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v, ls.i *= v, ls.j *= v, ls.k *= v ); return ls; } - FI XYZEval operator/ (const float &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZEval operator/ (const float &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZEval operator/ (const int &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZEval operator/ (const int &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v, ls.i /= v, ls.j /= v, ls.k /= v ); return ls; } - FI XYZEval operator>>(const int &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } - FI XYZEval operator>>(const int &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z), _RS(ls.i), _RS(ls.j), _RS(ls.k) ); return ls; } - FI XYZEval operator<<(const int &v) const { XYZEval ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } - FI XYZEval operator<<(const int &v) { XYZEval ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z), _LS(ls.i), _LS(ls.j), _LS(ls.k) ); return ls; } - FI const XYZEval operator-() const { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k); } - FI XYZEval operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z, -i, -j, -k); } - - // Modifier operators - FI XYZEval& operator+=(const XYval &rs) { x += rs.x; y += rs.y; return *this; } - FI XYZEval& operator-=(const XYval &rs) { x -= rs.x; y -= rs.y; return *this; } - FI XYZEval& operator*=(const XYval &rs) { x *= rs.x; y *= rs.y; return *this; } - FI XYZEval& operator/=(const XYval &rs) { x /= rs.x; y /= rs.y; return *this; } - FI XYZEval& operator+=(const XYZval &rs) { NUM_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } - FI XYZEval& operator-=(const XYZval &rs) { NUM_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } - FI XYZEval& operator*=(const XYZval &rs) { NUM_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } - FI XYZEval& operator/=(const XYZval &rs) { NUM_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; } - FI XYZEval& operator+=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e += rs.e, x += rs.x, y += rs.y, z += rs.z, i += rs.i, j += rs.j, k += rs.k); return *this; } - FI XYZEval& operator-=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z, i -= rs.i, j -= rs.j, k -= rs.k); return *this; } - FI XYZEval& operator*=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z, i *= rs.i, j *= rs.j, k *= rs.k); return *this; } - FI XYZEval& operator/=(const XYZEval &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z, i /= rs.i, j /= rs.j, k /= rs.k); return *this; } - FI XYZEval& operator*=(const T &v) { LOGICAL_AXIS_CODE(e *= v, x *= v, y *= v, z *= v, i *= v, j *= v, k *= v); return *this; } - FI XYZEval& operator>>=(const int &v) { LOGICAL_AXIS_CODE(_RS(e), _RS(x), _RS(y), _RS(z), _RS(i), _RS(j), _RS(k)); return *this; } - FI XYZEval& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k)); return *this; } - - // Exact comparisons. For floats a "NEAR" operation may be better. - FI bool operator==(const XYZval &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); } - FI bool operator==(const XYZval &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k); } - FI bool operator!=(const XYZval &rs) { return !operator==(rs); } - FI bool operator!=(const XYZval &rs) const { return !operator==(rs); } -}; - -#undef _RECIP -#undef _ABS -#undef _LS -#undef _RS -#undef FI diff --git a/src/core/utility.cpp b/src/core/utility.cpp deleted file mode 100644 index e4fd525..0000000 --- a/src/core/utility.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "utility.h" - -#include "../MarlinCore.h" -#include "../module/temperature.h" - -void safe_delay(millis_t ms) { - while (ms > 50) { - ms -= 50; - delay(50); - thermalManager.task(); - } - delay(ms); - thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made -} - -// A delay to provide brittle hosts time to receive bytes -#if ENABLED(SERIAL_OVERRUN_PROTECTION) - - #include "../gcode/gcode.h" // for set_autoreport_paused - - void serial_delay(const millis_t ms) { - const bool was = gcode.set_autoreport_paused(true); - safe_delay(ms); - gcode.set_autoreport_paused(was); - } -#endif - -#if ENABLED(DEBUG_LEVELING_FEATURE) - - #include "../module/probe.h" - #include "../module/motion.h" - #include "../module/planner.h" - #include "../libs/numtostr.h" - #include "../feature/bedlevel/bedlevel.h" - - void log_machine_info() { - SERIAL_ECHOLNPGM("Machine Type: " - TERN_(DELTA, "Delta") - TERN_(IS_SCARA, "SCARA") - TERN_(IS_CORE, "Core") - TERN_(MARKFORGED_XY, "MarkForgedXY") - TERN_(MARKFORGED_YX, "MarkForgedYX") - TERN_(IS_CARTESIAN, "Cartesian") - ); - - SERIAL_ECHOLNPGM("Probe: " - TERN_(PROBE_MANUALLY, "PROBE_MANUALLY") - TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE") - TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE") - TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE")) - TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE") - TERN_(Z_PROBE_SLED, "Z_PROBE_SLED") - TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY") - TERN_(SOLENOID_PROBE, "SOLENOID_PROBE") - TERN_(MAGLEV4, "MAGLEV4") - IF_DISABLED(PROBE_SELECTED, "NONE") - ); - - #if HAS_BED_PROBE - - #if !HAS_PROBE_XY_OFFSET - SERIAL_ECHOPGM("Probe Offset X0 Y0 Z", probe.offset.z, " ("); - #else - SERIAL_ECHOPGM_P(PSTR("Probe Offset X"), probe.offset_xy.x, SP_Y_STR, probe.offset_xy.y, SP_Z_STR, probe.offset.z); - if (probe.offset_xy.x > 0) - SERIAL_ECHOPGM(" (Right"); - else if (probe.offset_xy.x < 0) - SERIAL_ECHOPGM(" (Left"); - else if (probe.offset_xy.y != 0) - SERIAL_ECHOPGM(" (Middle"); - else - SERIAL_ECHOPGM(" (Aligned With"); - - if (probe.offset_xy.y > 0) - SERIAL_ECHOF(F(TERN(IS_SCARA, "-Distal", "-Back"))); - else if (probe.offset_xy.y < 0) - SERIAL_ECHOF(F(TERN(IS_SCARA, "-Proximal", "-Front"))); - else if (probe.offset_xy.x != 0) - SERIAL_ECHOPGM("-Center"); - - SERIAL_ECHOPGM(" & "); - - #endif - - SERIAL_ECHOF(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as")); - SERIAL_ECHOLNPGM(" Nozzle)"); - - #endif - - #if HAS_ABL_OR_UBL - SERIAL_ECHOPGM("Auto Bed Leveling: " - TERN_(AUTO_BED_LEVELING_LINEAR, "LINEAR") - TERN_(AUTO_BED_LEVELING_BILINEAR, "BILINEAR") - TERN_(AUTO_BED_LEVELING_3POINT, "3POINT") - TERN_(AUTO_BED_LEVELING_UBL, "UBL") - ); - - if (planner.leveling_active) { - SERIAL_ECHOLNPGM(" (enabled)"); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (planner.z_fade_height) - SERIAL_ECHOLNPGM("Z Fade: ", planner.z_fade_height); - #endif - #if ABL_PLANAR - SERIAL_ECHOPGM("ABL Adjustment"); - LOOP_NUM_AXES(a) { - SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a])); - serial_offset(planner.get_axis_position_mm(AxisEnum(a)) - current_position[a]); - } - #else - #if ENABLED(AUTO_BED_LEVELING_UBL) - SERIAL_ECHOPGM("UBL Adjustment Z"); - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - SERIAL_ECHOPGM("ABL Adjustment Z"); - #endif - const float rz = bedlevel.get_z_correction(current_position); - SERIAL_ECHO(ftostr43sign(rz, '+')); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (planner.z_fade_height) { - SERIAL_ECHOPGM(" (", ftostr43sign(rz * planner.fade_scaling_factor_for_z(current_position.z), '+')); - SERIAL_CHAR(')'); - } - #endif - #endif - } - else - SERIAL_ECHOLNPGM(" (disabled)"); - - SERIAL_EOL(); - - #elif ENABLED(MESH_BED_LEVELING) - - SERIAL_ECHOPGM("Mesh Bed Leveling"); - if (planner.leveling_active) { - SERIAL_ECHOLNPGM(" (enabled)"); - const float z_offset = bedlevel.get_z_offset(), - z_correction = bedlevel.get_z_correction(current_position); - SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(z_offset + z_correction, '+')); - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (planner.z_fade_height) { - SERIAL_ECHOPGM(" (", ftostr43sign( - z_offset + z_correction * planner.fade_scaling_factor_for_z(current_position.z), '+' - )); - SERIAL_CHAR(')'); - } - #endif - } - else - SERIAL_ECHOPGM(" (disabled)"); - - SERIAL_EOL(); - - #endif // MESH_BED_LEVELING - } - -#endif // DEBUG_LEVELING_FEATURE diff --git a/src/core/utility.h b/src/core/utility.h deleted file mode 100644 index a3cd794..0000000 --- a/src/core/utility.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" -#include "../core/types.h" -#include "../core/millis_t.h" - -void safe_delay(millis_t ms); // Delay ensuring that temperatures are updated and the watchdog is kept alive. - -#if ENABLED(SERIAL_OVERRUN_PROTECTION) - void serial_delay(const millis_t ms); -#else - inline void serial_delay(const millis_t) {} -#endif - -#if (GRID_MAX_POINTS_X) && (GRID_MAX_POINTS_Y) - - // 16x16 bit arrays - template - struct FlagBits { - typename IF<(W>8), uint16_t, uint8_t>::type bits[H]; - void fill() { memset(bits, 0xFF, sizeof(bits)); } - void reset() { memset(bits, 0x00, sizeof(bits)); } - void unmark(const uint8_t x, const uint8_t y) { CBI(bits[y], x); } - void mark(const uint8_t x, const uint8_t y) { SBI(bits[y], x); } - bool marked(const uint8_t x, const uint8_t y) { return TEST(bits[y], x); } - inline void unmark(const xy_int8_t &xy) { unmark(xy.x, xy.y); } - inline void mark(const xy_int8_t &xy) { mark(xy.x, xy.y); } - inline bool marked(const xy_int8_t &xy) { return marked(xy.x, xy.y); } - }; - - typedef FlagBits MeshFlags; - -#endif - -#if ENABLED(DEBUG_LEVELING_FEATURE) - void log_machine_info(); -#else - #define log_machine_info() NOOP -#endif - -/** - * A restorer instance remembers a variable's value before setting a - * new value, then restores the old value when it goes out of scope. - * Put operator= on your type to get extended behavior on value change. - */ -template -class restorer { - T& ref_; - T val_; -public: - restorer(T& perm) : ref_(perm), val_(perm) {} - restorer(T& perm, T temp_val) : ref_(perm), val_(perm) { perm = temp_val; } - ~restorer() { restore(); } - inline void restore() { ref_ = val_; } -}; - -#define REMEMBER(N,X,V...) restorer<__typeof__(X)> restorer_##N(X, ##V) -#define RESTORE(N) restorer_##N.restore() - -// Converts from an uint8_t in the range of 0-255 to an uint8_t -// in the range 0-100 while avoiding rounding artifacts -constexpr uint8_t ui8_to_percent(const uint8_t i) { return (int(i) * 100 + 127) / 255; } - -// Axis names for G-code parsing, reports, etc. -const xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', AXIS4_NAME, AXIS5_NAME, AXIS6_NAME); -#if NUM_AXES <= XYZ && !HAS_EXTRUDERS - #define AXIS_CHAR(A) ((char)('X' + A)) - #define IAXIS_CHAR AXIS_CHAR -#else - const xyze_char_t iaxis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z', 'I', 'J', 'K'); - #define AXIS_CHAR(A) axis_codes[A] - #define IAXIS_CHAR(A) iaxis_codes[A] -#endif diff --git a/src/feature/adc/adc_mcp3426.cpp b/src/feature/adc/adc_mcp3426.cpp deleted file mode 100644 index 49bb67e..0000000 --- a/src/feature/adc/adc_mcp3426.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * adc_mcp3426.cpp - library for MicroChip MCP3426 I2C A/D converter - * - * For implementation details, please take a look at the datasheet: - * https://www.microchip.com/en-us/product/MCP3426 - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(HAS_MCP3426_ADC) - -#include "adc_mcp3426.h" - -// Read the ADC value from MCP342X on a specific channel -int16_t MCP3426::ReadValue(uint8_t channel, uint8_t gain, uint8_t address) { - Error = false; - - #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM) - Wire.setSDA(pin_t(I2C_SDA_PIN)); - Wire.setSCL(pin_t(I2C_SCL_PIN)); - #endif - - Wire.begin(); // No address joins the BUS as the master - - Wire.beginTransmission(I2C_ADDRESS(address)); - - // Continuous Conversion Mode, 16 bit, Channel 1, Gain x4 - // 26 = 0b00011000 - // RXXCSSGG - // R = Ready Bit - // XX = Channel (00=1, 01=2, 10=3 (MCP3428), 11=4 (MCP3428)) - // C = Conversion Mode Bit (1= Continuous Conversion Mode (Default)) - // SS = Sample rate, 10=15 samples per second @ 16 bits - // GG = Gain 00 =x1 - uint8_t controlRegister = 0b00011000; - - if (channel == 2) controlRegister |= 0b00100000; // Select channel 2 - - if (gain == 2) - controlRegister |= 0b00000001; - else if (gain == 4) - controlRegister |= 0b00000010; - else if (gain == 8) - controlRegister |= 0b00000011; - - Wire.write(controlRegister); - if (Wire.endTransmission() != 0) { - Error = true; - return 0; - } - - const uint8_t len = 3; - uint8_t buffer[len] = {}; - - do { - Wire.requestFrom(I2C_ADDRESS(address), len); - if (Wire.available() != len) { - Error = true; - return 0; - } - - for (uint8_t i = 0; i < len; ++i) - buffer[i] = Wire.read(); - - // Is conversion ready, if not loop around again - } while ((buffer[2] & 0x80) != 0); - - union TwoBytesToInt16 { - uint8_t bytes[2]; - int16_t integervalue; - }; - TwoBytesToInt16 ConversionUnion; - - ConversionUnion.bytes[1] = buffer[0]; - ConversionUnion.bytes[0] = buffer[1]; - - return ConversionUnion.integervalue; -} - -MCP3426 mcp3426; - -#endif // HAS_MCP3426_ADC diff --git a/src/feature/adc/adc_mcp3426.h b/src/feature/adc/adc_mcp3426.h deleted file mode 100644 index af48593..0000000 --- a/src/feature/adc/adc_mcp3426.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Arduino library for MicroChip MCP3426 I2C A/D converter. - * https://www.microchip.com/en-us/product/MCP3426 - */ - -#include -#include - -class MCP3426 { - public: - int16_t ReadValue(uint8_t channel, uint8_t gain, uint8_t address); - bool Error; -}; - -extern MCP3426 mcp3426; diff --git a/src/feature/ammeter.cpp b/src/feature/ammeter.cpp deleted file mode 100644 index 71b84f1..0000000 --- a/src/feature/ammeter.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(I2C_AMMETER) - -#include "ammeter.h" - -#ifndef I2C_AMMETER_IMAX - #define I2C_AMMETER_IMAX 0.500 // Calibration range 500 Milliamps -#endif - -INA226 ina; - -Ammeter ammeter; - -float Ammeter::scale; -float Ammeter::current; - -void Ammeter::init() { - ina.begin(); - ina.configure(INA226_AVERAGES_16, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT); - ina.calibrate(I2C_AMMETER_SHUNT_RESISTOR, I2C_AMMETER_IMAX); -} - -float Ammeter::read() { - scale = 1; - current = ina.readShuntCurrent(); - if (current <= 0.0001f) current = 0; // Clean up least-significant-bit amplification errors - if (current < 0.1f) scale = 1000; - return current * scale; -} - -#endif // I2C_AMMETER diff --git a/src/feature/ammeter.h b/src/feature/ammeter.h deleted file mode 100644 index 86f09bb..0000000 --- a/src/feature/ammeter.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -#include -#include - -class Ammeter { -private: - static float scale; - -public: - static float current; - static void init(); - static float read(); -}; - -extern Ammeter ammeter; diff --git a/src/feature/babystep.cpp b/src/feature/babystep.cpp deleted file mode 100644 index 54ad958..0000000 --- a/src/feature/babystep.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(BABYSTEPPING) - -#include "babystep.h" -#include "../MarlinCore.h" -#include "../module/motion.h" // for axes_should_home() -#include "../module/planner.h" // for axis_steps_per_mm[] -#include "../module/stepper.h" - -#if ENABLED(BABYSTEP_ALWAYS_AVAILABLE) - #include "../gcode/gcode.h" -#endif - -Babystep babystep; - -volatile int16_t Babystep::steps[BS_AXIS_IND(Z_AXIS) + 1]; -#if ENABLED(BABYSTEP_DISPLAY_TOTAL) - int16_t Babystep::axis_total[BS_TOTAL_IND(Z_AXIS) + 1]; -#endif -int16_t Babystep::accum; - -void Babystep::step_axis(const AxisEnum axis) { - const int16_t curTodo = steps[BS_AXIS_IND(axis)]; // get rid of volatile for performance - if (curTodo) { - stepper.do_babystep((AxisEnum)axis, curTodo > 0); - if (curTodo > 0) steps[BS_AXIS_IND(axis)]--; else steps[BS_AXIS_IND(axis)]++; - } -} - -void Babystep::add_mm(const AxisEnum axis, const_float_t mm) { - add_steps(axis, mm * planner.settings.axis_steps_per_mm[axis]); -} - -void Babystep::add_steps(const AxisEnum axis, const int16_t distance) { - if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return; - - accum += distance; // Count up babysteps for the UI - steps[BS_AXIS_IND(axis)] += distance; - TERN_(BABYSTEP_DISPLAY_TOTAL, axis_total[BS_TOTAL_IND(axis)] += distance); - TERN_(BABYSTEP_ALWAYS_AVAILABLE, gcode.reset_stepper_timeout()); - TERN_(INTEGRATED_BABYSTEPPING, if (has_steps()) stepper.initiateBabystepping()); -} - -#endif // BABYSTEPPING diff --git a/src/feature/babystep.h b/src/feature/babystep.h deleted file mode 100644 index 5693afb..0000000 --- a/src/feature/babystep.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(INTEGRATED_BABYSTEPPING) - #define BABYSTEPS_PER_SEC 1000UL - #define BABYSTEP_TICKS ((STEPPER_TIMER_RATE) / (BABYSTEPS_PER_SEC)) -#else - #define BABYSTEPS_PER_SEC 976UL - #define BABYSTEP_TICKS ((TEMP_TIMER_RATE) / (BABYSTEPS_PER_SEC)) -#endif - -#if IS_CORE || EITHER(BABYSTEP_XY, I2C_POSITION_ENCODERS) - #define BS_AXIS_IND(A) A - #define BS_AXIS(I) AxisEnum(I) -#else - #define BS_AXIS_IND(A) 0 - #define BS_AXIS(I) Z_AXIS -#endif - -#if ENABLED(BABYSTEP_DISPLAY_TOTAL) - #if ENABLED(BABYSTEP_XY) - #define BS_TOTAL_IND(A) A - #else - #define BS_TOTAL_IND(A) 0 - #endif -#endif - -class Babystep { -public: - static volatile int16_t steps[BS_AXIS_IND(Z_AXIS) + 1]; - static int16_t accum; // Total babysteps in current edit - - #if ENABLED(BABYSTEP_DISPLAY_TOTAL) - static int16_t axis_total[BS_TOTAL_IND(Z_AXIS) + 1]; // Total babysteps since G28 - static void reset_total(const AxisEnum axis) { - if (TERN1(BABYSTEP_XY, axis == Z_AXIS)) - axis_total[BS_TOTAL_IND(axis)] = 0; - } - #endif - - static void add_steps(const AxisEnum axis, const int16_t distance); - static void add_mm(const AxisEnum axis, const_float_t mm); - - static bool has_steps() { - return steps[BS_AXIS_IND(X_AXIS)] || steps[BS_AXIS_IND(Y_AXIS)] || steps[BS_AXIS_IND(Z_AXIS)]; - } - - // - // Called by the Temperature or Stepper ISR to - // apply accumulated babysteps to the axes. - // - static void task() { - LOOP_LE_N(i, BS_AXIS_IND(Z_AXIS)) step_axis(BS_AXIS(i)); - } - -private: - static void step_axis(const AxisEnum axis); -}; - -extern Babystep babystep; diff --git a/src/feature/backlash.cpp b/src/feature/backlash.cpp deleted file mode 100644 index 13e2cd9..0000000 --- a/src/feature/backlash.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(BACKLASH_COMPENSATION) - -#include "backlash.h" - -#include "../module/motion.h" -#include "../module/planner.h" - -axis_bits_t Backlash::last_direction_bits; -xyz_long_t Backlash::residual_error{0}; - -#ifdef BACKLASH_DISTANCE_MM - #if ENABLED(BACKLASH_GCODE) - xyz_float_t Backlash::distance_mm = BACKLASH_DISTANCE_MM; - #else - const xyz_float_t Backlash::distance_mm = BACKLASH_DISTANCE_MM; - #endif -#endif - -#if ENABLED(BACKLASH_GCODE) - uint8_t Backlash::correction = (BACKLASH_CORRECTION) * all_on; - #ifdef BACKLASH_SMOOTHING_MM - float Backlash::smoothing_mm = BACKLASH_SMOOTHING_MM; - #endif -#endif - -#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - xyz_float_t Backlash::measured_mm{0}; - xyz_uint8_t Backlash::measured_count{0}; -#endif - -Backlash backlash; - -/** - * To minimize seams in the printed part, backlash correction only adds - * steps to the current segment (instead of creating a new segment, which - * causes discontinuities and print artifacts). - * - * With a non-zero BACKLASH_SMOOTHING_MM value the backlash correction is - * spread over multiple segments, smoothing out artifacts even more. - */ - -void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block) { - axis_bits_t changed_dir = last_direction_bits ^ dm; - // Ignore direction change unless steps are taken in that direction - #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX) - if (!da) CBI(changed_dir, X_AXIS); - if (!db) CBI(changed_dir, Y_AXIS); - if (!dc) CBI(changed_dir, Z_AXIS); - #elif CORE_IS_XY - if (!(da + db)) CBI(changed_dir, X_AXIS); - if (!(da - db)) CBI(changed_dir, Y_AXIS); - if (!dc) CBI(changed_dir, Z_AXIS); - #elif CORE_IS_XZ - if (!(da + dc)) CBI(changed_dir, X_AXIS); - if (!(da - dc)) CBI(changed_dir, Z_AXIS); - if (!db) CBI(changed_dir, Y_AXIS); - #elif CORE_IS_YZ - if (!(db + dc)) CBI(changed_dir, Y_AXIS); - if (!(db - dc)) CBI(changed_dir, Z_AXIS); - if (!da) CBI(changed_dir, X_AXIS); - #endif - last_direction_bits ^= changed_dir; - - if (!correction && !residual_error) return; - - #ifdef BACKLASH_SMOOTHING_MM - // The segment proportion is a value greater than 0.0 indicating how much residual_error - // is corrected for in this segment. The contribution is based on segment length and the - // smoothing distance. Since the computation of this proportion involves a floating point - // division, defer computation until needed. - float segment_proportion = 0; - #endif - - const float f_corr = float(correction) / all_on; - - LOOP_NUM_AXES(axis) { - if (distance_mm[axis]) { - const bool reverse = TEST(dm, axis); - - // When an axis changes direction, add axis backlash to the residual error - if (TEST(changed_dir, axis)) - residual_error[axis] += (reverse ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; - - // Decide how much of the residual error to correct in this segment - int32_t error_correction = residual_error[axis]; - if (reverse != (error_correction < 0)) - error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps - - #ifdef BACKLASH_SMOOTHING_MM - if (error_correction && smoothing_mm != 0) { - // Take up a portion of the residual_error in this segment - if (segment_proportion == 0) segment_proportion = _MIN(1.0f, block->millimeters / smoothing_mm); - error_correction = CEIL(segment_proportion * error_correction); - } - #endif - - // This correction reduces the residual error and adds block steps - if (error_correction) { - block->steps[axis] += ABS(error_correction); - #if ENABLED(CORE_BACKLASH) - switch (axis) { - case CORE_AXIS_1: - //block->steps[CORE_AXIS_2] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_2]; - //SERIAL_ECHOLNPGM("CORE_AXIS_1 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis], - // " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction); - break; - case CORE_AXIS_2: - //block->steps[CORE_AXIS_1] += influence_distance_mm[axis] * planner.settings.axis_steps_per_mm[CORE_AXIS_1];; - //SERIAL_ECHOLNPGM("CORE_AXIS_2 dir change. distance=", distance_mm[axis], " r.err=", residual_error[axis], - // " da=", da, " db=", db, " block->steps[axis]=", block->steps[axis], " err_corr=", error_correction); - break; - case NORMAL_AXIS: break; - } - residual_error[axis] = 0; // No residual_error needed for next CORE block, I think... - #else - residual_error[axis] -= error_correction; - #endif - } - } - } -} - -int32_t Backlash::get_applied_steps(const AxisEnum axis) { - if (axis >= NUM_AXES) return 0; - - const bool reverse = TEST(last_direction_bits, axis); - - const int32_t residual_error_axis = residual_error[axis]; - - // At startup it is assumed the last move was forwards. So the applied - // steps will always be a non-positive number. - - if (!reverse) return -residual_error_axis; - - const float f_corr = float(correction) / all_on; - const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; - return full_error_axis - residual_error_axis; -} - -class Backlash::StepAdjuster { - private: - xyz_long_t applied_steps; - public: - StepAdjuster() { - LOOP_NUM_AXES(axis) applied_steps[axis] = backlash.get_applied_steps((AxisEnum)axis); - } - ~StepAdjuster() { - // after backlash compensation parameter changes, ensure applied step count does not change - LOOP_NUM_AXES(axis) residual_error[axis] += backlash.get_applied_steps((AxisEnum)axis) - applied_steps[axis]; - } -}; - -#if ENABLED(BACKLASH_GCODE) - - void Backlash::set_correction_uint8(const uint8_t v) { - StepAdjuster adjuster; - correction = v; - } - - void Backlash::set_distance_mm(const AxisEnum axis, const float v) { - StepAdjuster adjuster; - distance_mm[axis] = v; - } - - #ifdef BACKLASH_SMOOTHING_MM - void Backlash::set_smoothing_mm(const float v) { - StepAdjuster adjuster; - smoothing_mm = v; - } - #endif - -#endif - -#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - - #include "../module/probe.h" - - // Measure Z backlash by raising nozzle in increments until probe deactivates - void Backlash::measure_with_probe() { - if (measured_count.z == 255) return; - - const float start_height = current_position.z; - while (current_position.z < (start_height + BACKLASH_MEASUREMENT_LIMIT) && PROBE_TRIGGERED()) - do_blocking_move_to_z(current_position.z + BACKLASH_MEASUREMENT_RESOLUTION, MMM_TO_MMS(BACKLASH_MEASUREMENT_FEEDRATE)); - - // The backlash from all probe points is averaged, so count the number of measurements - measured_mm.z += current_position.z - start_height; - measured_count.z++; - } - -#endif - -#endif // BACKLASH_COMPENSATION diff --git a/src/feature/backlash.h b/src/feature/backlash.h deleted file mode 100644 index 0bace52..0000000 --- a/src/feature/backlash.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" -#include "../module/planner.h" - -class Backlash { -public: - static constexpr uint8_t all_on = 0xFF, all_off = 0x00; - -private: - static axis_bits_t last_direction_bits; - static xyz_long_t residual_error; - - #if ENABLED(BACKLASH_GCODE) - static uint8_t correction; - static xyz_float_t distance_mm; - #ifdef BACKLASH_SMOOTHING_MM - static float smoothing_mm; - #endif - #else - static constexpr uint8_t correction = (BACKLASH_CORRECTION) * all_on; - static const xyz_float_t distance_mm; - #ifdef BACKLASH_SMOOTHING_MM - static constexpr float smoothing_mm = BACKLASH_SMOOTHING_MM; - #endif - #endif - - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - static xyz_float_t measured_mm; - static xyz_uint8_t measured_count; - #endif - - class StepAdjuster; - -public: - static float get_measurement(const AxisEnum a) { - UNUSED(a); - // Return the measurement averaged over all readings - return TERN(MEASURE_BACKLASH_WHEN_PROBING - , measured_count[a] > 0 ? measured_mm[a] / measured_count[a] : 0 - , 0 - ); - } - - static bool has_measurement(const AxisEnum a) { - UNUSED(a); - return TERN0(MEASURE_BACKLASH_WHEN_PROBING, measured_count[a] > 0); - } - - static bool has_any_measurement() { - return has_measurement(X_AXIS) || has_measurement(Y_AXIS) || has_measurement(Z_AXIS); - } - - static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block); - static int32_t get_applied_steps(const AxisEnum axis); - - #if ENABLED(BACKLASH_GCODE) - static void set_correction_uint8(const uint8_t v); - static uint8_t get_correction_uint8() { return correction; } - static void set_correction(const float v) { set_correction_uint8(_MAX(0, _MIN(1.0, v)) * all_on + 0.5f); } - static float get_correction() { return float(get_correction_uint8()) / all_on; } - static void set_distance_mm(const AxisEnum axis, const float v); - static float get_distance_mm(const AxisEnum axis) {return distance_mm[axis];} - #ifdef BACKLASH_SMOOTHING_MM - static void set_smoothing_mm(const float v); - static float get_smoothing_mm() {return smoothing_mm;} - #endif - #endif - - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - static void measure_with_probe(); - #endif -}; - -extern Backlash backlash; diff --git a/src/feature/baricuda.cpp b/src/feature/baricuda.cpp deleted file mode 100644 index 5968917..0000000 --- a/src/feature/baricuda.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(BARICUDA) - -#include "baricuda.h" - -uint8_t baricuda_valve_pressure = 0, - baricuda_e_to_p_pressure = 0; - -#endif // BARICUDA diff --git a/src/feature/baricuda.h b/src/feature/baricuda.h deleted file mode 100644 index f28d07d..0000000 --- a/src/feature/baricuda.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -extern uint8_t baricuda_valve_pressure, - baricuda_e_to_p_pressure; diff --git a/src/feature/bedlevel/abl/bbl.cpp b/src/feature/bedlevel/abl/bbl.cpp deleted file mode 100644 index be0e862..0000000 --- a/src/feature/bedlevel/abl/bbl.cpp +++ /dev/null @@ -1,439 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_BILINEAR) - -#include "../bedlevel.h" - -#include "../../../module/motion.h" - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../../core/debug_out.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#endif - -LevelingBilinear bedlevel; - -xy_pos_t LevelingBilinear::grid_spacing, - LevelingBilinear::grid_start; -xy_float_t LevelingBilinear::grid_factor; -bed_mesh_t LevelingBilinear::z_values; -xy_pos_t LevelingBilinear::cached_rel; -xy_int8_t LevelingBilinear::cached_g; - -/** - * Extrapolate a single point from its neighbors - */ -void LevelingBilinear::extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir) { - if (!isnan(z_values[x][y])) return; - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPGM("Extrapolate ["); - if (x < 10) DEBUG_CHAR(' '); - DEBUG_ECHO(x); - DEBUG_CHAR(xdir ? (xdir > 0 ? '+' : '-') : ' '); - DEBUG_CHAR(' '); - if (y < 10) DEBUG_CHAR(' '); - DEBUG_ECHO(y); - DEBUG_CHAR(ydir ? (ydir > 0 ? '+' : '-') : ' '); - DEBUG_ECHOLNPGM("]"); - } - - // 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; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - - // Median is robust (ignores outliers). - // z_values[x][y] = (a < b) ? ((b < c) ? b : (c < a) ? a : c) - // : ((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 - -void LevelingBilinear::reset() { - grid_start.reset(); - grid_spacing.reset(); - GRID_LOOP(x, y) { - z_values[x][y] = NAN; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, 0)); - } -} - -void LevelingBilinear::set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start) { - grid_spacing = _grid_spacing; - grid_start = _grid_start; - grid_factor = grid_spacing.reciprocal(); -} - -/** - * Fill in the unprobed points (corners of circular print surface) - * using linear extrapolation, away from the center. - */ -void LevelingBilinear::extrapolate_unprobed_bed_level() { - #ifdef HALF_IN_X - constexpr uint8_t ctrx2 = 0, xend = GRID_MAX_POINTS_X - 1; - #else - constexpr uint8_t ctrx1 = (GRID_MAX_CELLS_X) / 2, // left-of-center - ctrx2 = (GRID_MAX_POINTS_X) / 2, // right-of-center - xend = ctrx1; - #endif - - #ifdef HALF_IN_Y - constexpr uint8_t ctry2 = 0, yend = GRID_MAX_POINTS_Y - 1; - #else - constexpr uint8_t ctry1 = (GRID_MAX_CELLS_Y) / 2, // top-of-center - ctry2 = (GRID_MAX_POINTS_Y) / 2, // bottom-of-center - yend = ctry1; - #endif - - LOOP_LE_N(xo, xend) - LOOP_LE_N(yo, yend) { - 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 - - - } -} - -void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values /*= NULL*/) { - // print internal grid(s) or just the one passed as a parameter - SERIAL_ECHOLNPGM("Bilinear Leveling Grid:"); - print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 3, _z_values ? *_z_values[0] : z_values[0]); - - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - if (!_z_values) { - SERIAL_ECHOLNPGM("Subdivided with CATMULL ROM Leveling Grid:"); - print_2d_array(ABL_GRID_POINTS_VIRT_X, ABL_GRID_POINTS_VIRT_Y, 5, z_values_virt[0]); - } - #endif -} - -#if ENABLED(ABL_BILINEAR_SUBDIVISION) - - #define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2) - #define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2) - float LevelingBilinear::z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y]; - xy_pos_t LevelingBilinear::grid_spacing_virt; - xy_float_t LevelingBilinear::grid_factor_virt; - - #define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I)) - float LevelingBilinear::bed_level_virt_coord(const uint8_t x, const uint8_t y) { - uint8_t ep = 0, ip = 1; - if (x > (GRID_MAX_POINTS_X) + 1 || y > (GRID_MAX_POINTS_Y) + 1) { - // The requested point requires extrapolating two points beyond the mesh. - // These values are only requested for the edges of the mesh, which are always an actual mesh point, - // and do not require interpolation. When interpolation is not needed, this "Mesh + 2" point is - // cancelled out in bed_level_virt_cmr and does not impact the result. Return 0.0 rather than - // making this function more complex by extrapolating two points. - return 0.0; - } - if (!x || x == ABL_TEMP_POINTS_X - 1) { - if (x) { - ep = (GRID_MAX_POINTS_X) - 1; - ip = GRID_MAX_CELLS_X - 1; - } - 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_CELLS_Y - 1; - } - 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]; - } - - float LevelingBilinear::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.5f; - } - - float LevelingBilinear::bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty) { - float row[4], column[4]; - LOOP_L_N(i, 4) { - LOOP_L_N(j, 4) { - column[j] = bed_level_virt_coord(i + x - 1, j + y - 1); - } - row[i] = bed_level_virt_cmr(column, 1, ty); - } - return bed_level_virt_cmr(row, 1, tx); - } - - void LevelingBilinear::bed_level_virt_interpolate() { - grid_spacing_virt = grid_spacing / (BILINEAR_SUBDIVISIONS); - grid_factor_virt = grid_spacing_virt.reciprocal(); - LOOP_L_N(y, GRID_MAX_POINTS_Y) - LOOP_L_N(x, GRID_MAX_POINTS_X) - LOOP_L_N(ty, BILINEAR_SUBDIVISIONS) - LOOP_L_N(tx, BILINEAR_SUBDIVISIONS) { - if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1)) - continue; - z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = - bed_level_virt_2cmr( - x + 1, - y + 1, - (float)tx / (BILINEAR_SUBDIVISIONS), - (float)ty / (BILINEAR_SUBDIVISIONS) - ); - } - } - -#endif // ABL_BILINEAR_SUBDIVISION - -// Refresh after other values have been updated -void LevelingBilinear::refresh_bed_level() { - TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); - cached_rel.x = cached_rel.y = -999.999; - cached_g.x = cached_g.y = -99; -} - -#if ENABLED(ABL_BILINEAR_SUBDIVISION) - #define ABL_BG_SPACING(A) grid_spacing_virt.A - #define ABL_BG_FACTOR(A) 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) grid_spacing.A - #define ABL_BG_FACTOR(A) 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 LevelingBilinear::get_z_correction(const xy_pos_t &raw) { - - static float z1, d2, z3, d4, L, D; - - static xy_pos_t ratio; - - // Whole units for the grid line indices. Constrained within bounds. - static xy_int8_t thisg, nextg; - - // XY relative to the probed area - xy_pos_t rel = raw - grid_start.asFloat(); - - #if ENABLED(EXTRAPOLATE_BEYOND_GRID) - #define FAR_EDGE_OR_BOX 2 // Keep using the last grid box - #else - #define FAR_EDGE_OR_BOX 1 // Just use the grid far edge - #endif - - if (cached_rel.x != rel.x) { - cached_rel.x = rel.x; - ratio.x = rel.x * ABL_BG_FACTOR(x); - 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 (>1 is ok when nextg.x==thisg.x) - #endif - - thisg.x = gx; - nextg.x = _MIN(thisg.x + 1, ABL_BG_POINTS_X - 1); - } - - if (cached_rel.y != rel.y || cached_g.x != thisg.x) { - - if (cached_rel.y != rel.y) { - cached_rel.y = rel.y; - ratio.y = rel.y * ABL_BG_FACTOR(y); - 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 nextg.y==thisg.y.) - #endif - - thisg.y = gy; - nextg.y = _MIN(thisg.y + 1, ABL_BG_POINTS_Y - 1); - } - - if (cached_g != thisg) { - cached_g = thisg; - // Z at the box corners - z1 = ABL_BG_GRID(thisg.x, thisg.y); // left-front - d2 = ABL_BG_GRID(thisg.x, nextg.y) - z1; // left-back (delta) - z3 = ABL_BG_GRID(nextg.x, thisg.y); // right-front - d4 = ABL_BG_GRID(nextg.x, nextg.y) - z3; // right-back (delta) - } - - // Bilinear interpolate. Needed since rel.y or thisg.x 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 (ABS(last_offset - offset) > 0.2) { - SERIAL_ECHOLNPGM("Sudden Shift at x=", rel.x, " / ", grid_spacing.x, " -> thisg.x=", thisg.x); - SERIAL_ECHOLNPGM(" y=", rel.y, " / ", grid_spacing.y, " -> thisg.y=", thisg.y); - SERIAL_ECHOLNPGM(" ratio.x=", ratio.x, " ratio.y=", ratio.y); - SERIAL_ECHOLNPGM(" z1=", z1, " z2=", z2, " z3=", z3, " z4=", z4); - SERIAL_ECHOLNPGM(" L=", L, " R=", R, " offset=", offset); - } - last_offset = offset; - //*/ - - return offset; -} - -#if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - - #define CELL_INDEX(A,V) ((V - grid_start.A) * ABL_BG_FACTOR(A)) - - /** - * Prepare a bilinear-leveled linear move on Cartesian, - * splitting the move where it crosses grid borders. - */ - void LevelingBilinear::line_to_destination(const_feedRate_t scaled_fr_mm_s, uint16_t x_splits, uint16_t y_splits) { - // Get current and destination cells for this line - xy_int_t c1 { CELL_INDEX(x, current_position.x), CELL_INDEX(y, current_position.y) }, - c2 { CELL_INDEX(x, destination.x), CELL_INDEX(y, destination.y) }; - LIMIT(c1.x, 0, ABL_BG_POINTS_X - 2); - LIMIT(c1.y, 0, ABL_BG_POINTS_Y - 2); - LIMIT(c2.x, 0, ABL_BG_POINTS_X - 2); - LIMIT(c2.y, 0, ABL_BG_POINTS_Y - 2); - - // Start and end in the same cell? No split needed. - if (c1 == c2) { - current_position = destination; - line_to_current_position(scaled_fr_mm_s); - return; - } - - #define LINE_SEGMENT_END(A) (current_position.A + (destination.A - current_position.A) * normalized_dist) - - float normalized_dist; - xyze_pos_t end; - const xy_int8_t gc { _MAX(c1.x, c2.x), _MAX(c1.y, c2.y) }; - - // Crosses on the X and not already split on this X? - // The x_splits flags are insurance against rounding errors. - if (c2.x != c1.x && TEST(x_splits, gc.x)) { - // Split on the X grid line - CBI(x_splits, gc.x); - end = destination; - destination.x = grid_start.x + ABL_BG_SPACING(x) * gc.x; - normalized_dist = (destination.x - current_position.x) / (end.x - current_position.x); - destination.y = LINE_SEGMENT_END(y); - } - // Crosses on the Y and not already split on this Y? - else if (c2.y != c1.y && TEST(y_splits, gc.y)) { - // Split on the Y grid line - CBI(y_splits, gc.y); - end = destination; - destination.y = grid_start.y + ABL_BG_SPACING(y) * gc.y; - normalized_dist = (destination.y - current_position.y) / (end.y - current_position.y); - destination.x = LINE_SEGMENT_END(x); - } - else { - // Must already have been split on these border(s) - // This should be a rare case. - current_position = destination; - line_to_current_position(scaled_fr_mm_s); - return; - } - - destination.z = LINE_SEGMENT_END(z); - destination.e = LINE_SEGMENT_END(e); - - // Do the split and look for more borders - line_to_destination(scaled_fr_mm_s, x_splits, y_splits); - - // Restore destination from stack - destination = end; - line_to_destination(scaled_fr_mm_s, x_splits, y_splits); - } - -#endif // IS_CARTESIAN && !SEGMENT_LEVELED_MOVES - -#endif // AUTO_BED_LEVELING_BILINEAR diff --git a/src/feature/bedlevel/abl/bbl.h b/src/feature/bedlevel/abl/bbl.h deleted file mode 100644 index c2be4fe..0000000 --- a/src/feature/bedlevel/abl/bbl.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfigPre.h" - -class LevelingBilinear { -public: - static bed_mesh_t z_values; - static xy_pos_t grid_spacing, grid_start; - -private: - static xy_float_t grid_factor; - static xy_pos_t cached_rel; - static xy_int8_t cached_g; - - static void extrapolate_one_point(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); - - #if ENABLED(ABL_BILINEAR_SUBDIVISION) - #define ABL_GRID_POINTS_VIRT_X (GRID_MAX_CELLS_X * (BILINEAR_SUBDIVISIONS) + 1) - #define ABL_GRID_POINTS_VIRT_Y (GRID_MAX_CELLS_Y * (BILINEAR_SUBDIVISIONS) + 1) - - static float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y]; - static xy_pos_t grid_spacing_virt; - static xy_float_t grid_factor_virt; - - static float bed_level_virt_coord(const uint8_t x, const uint8_t y); - static float bed_level_virt_cmr(const float p[4], const uint8_t i, const float t); - static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty); - static void bed_level_virt_interpolate(); - #endif - -public: - static void reset(); - static void set_grid(const xy_pos_t& _grid_spacing, const xy_pos_t& _grid_start); - static void extrapolate_unprobed_bed_level(); - static void print_leveling_grid(const bed_mesh_t* _z_values = NULL); - static void refresh_bed_level(); - static bool has_mesh() { return !!grid_spacing.x; } - static bool mesh_is_valid() { return has_mesh(); } - static float get_mesh_x(const uint8_t i) { return grid_start.x + i * grid_spacing.x; } - static float get_mesh_y(const uint8_t j) { return grid_start.y + j * grid_spacing.y; } - static float get_z_correction(const xy_pos_t &raw); - static constexpr float get_z_offset() { return 0.0f; } - - #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - static void line_to_destination(const_feedRate_t scaled_fr_mm_s, uint16_t x_splits=0xFFFF, uint16_t y_splits=0xFFFF); - #endif -}; - -extern LevelingBilinear bedlevel; diff --git a/src/feature/bedlevel/bedlevel.cpp b/src/feature/bedlevel/bedlevel.cpp deleted file mode 100644 index 2207884..0000000 --- a/src/feature/bedlevel/bedlevel.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_LEVELING - -#include "bedlevel.h" -#include "../../module/planner.h" - -#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY) - #include "../../module/motion.h" -#endif - -#if ENABLED(PROBE_MANUALLY) - bool g29_in_progress = false; -#endif - -#if ENABLED(LCD_BED_LEVELING) - #include "../../lcd/marlinui.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#endif - -bool leveling_is_valid() { - return TERN1(HAS_MESH, bedlevel.mesh_is_valid()); -} - -/** - * Turn bed leveling on or off, correcting the current position. - * - * Disable: Current position = physical position - * Enable: Current position = "unleveled" physical position - */ -void set_bed_leveling_enabled(const bool enable/*=true*/) { - - const bool can_change = TERN1(AUTO_BED_LEVELING_BILINEAR, !enable || leveling_is_valid()); - - if (can_change && enable != planner.leveling_active) { - - auto _report_leveling = []{ - if (DEBUGGING(LEVELING)) { - if (planner.leveling_active) - DEBUG_POS("Leveling ON", current_position); - else - DEBUG_POS("Leveling OFF", current_position); - } - }; - - _report_leveling(); - planner.synchronize(); - - // Get the corrected leveled / unleveled position - planner.apply_modifiers(current_position); // Physical position with all modifiers - planner.leveling_active ^= true; // Toggle leveling between apply and unapply - planner.unapply_modifiers(current_position); // Logical position with modifiers removed - - sync_plan_position(); - _report_leveling(); - } -} - -TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved(planner.leveling_active) { - set_bed_leveling_enabled(enable); -} - -#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - - void set_z_fade_height(const_float_t zfh, const bool do_report/*=true*/) { - - if (planner.z_fade_height == zfh) return; - - const bool leveling_was_active = planner.leveling_active; - set_bed_leveling_enabled(false); - - planner.set_z_fade_height(zfh); - - if (leveling_was_active) { - const xyz_pos_t oldpos = current_position; - set_bed_leveling_enabled(true); - if (do_report && oldpos != current_position) - report_current_position(); - } - } - -#endif // ENABLE_LEVELING_FADE_HEIGHT - -/** - * Reset calibration results to zero. - */ -void reset_bed_level() { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("reset_bed_level"); - IF_DISABLED(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(false)); - TERN_(HAS_MESH, bedlevel.reset()); - TERN_(ABL_PLANAR, planner.bed_level_matrix.set_to_identity()); -} - -#if EITHER(AUTO_BED_LEVELING_BILINEAR, 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. - */ - void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values) { - #ifndef SCAD_MESH_OUTPUT - LOOP_L_N(x, sx) { - serial_spaces(precision + (x < 10 ? 3 : 2)); - SERIAL_ECHO(x); - } - SERIAL_EOL(); - #endif - #ifdef SCAD_MESH_OUTPUT - SERIAL_ECHOLNPGM("measured_z = ["); // open 2D array - #endif - LOOP_L_N(y, sy) { - #ifdef SCAD_MESH_OUTPUT - SERIAL_ECHOPGM(" ["); // open sub-array - #else - if (y < 10) SERIAL_CHAR(' '); - SERIAL_ECHO(y); - #endif - LOOP_L_N(x, sx) { - SERIAL_CHAR(' '); - const float offset = values[x * sy + y]; - if (!isnan(offset)) { - if (offset >= 0) SERIAL_CHAR('+'); - SERIAL_ECHO_F(offset, int(precision)); - } - else { - #ifdef SCAD_MESH_OUTPUT - for (uint8_t i = 3; i < precision + 3; i++) - SERIAL_CHAR(' '); - SERIAL_ECHOPGM("NAN"); - #else - LOOP_L_N(i, precision + 3) - SERIAL_CHAR(i ? '=' : ' '); - #endif - } - #ifdef SCAD_MESH_OUTPUT - if (x < sx - 1) SERIAL_CHAR(','); - #endif - } - #ifdef SCAD_MESH_OUTPUT - SERIAL_ECHOPGM(" ]"); // close sub-array - if (y < sy - 1) SERIAL_CHAR(','); - #endif - SERIAL_EOL(); - } - #ifdef SCAD_MESH_OUTPUT - SERIAL_ECHOPGM("];"); // close 2D array - #endif - SERIAL_EOL(); - } - -#endif // AUTO_BED_LEVELING_BILINEAR || MESH_BED_LEVELING - -#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY) - - void _manual_goto_xy(const xy_pos_t &pos) { - - // Get the resting Z position for after the XY move - #ifdef MANUAL_PROBE_START_Z - constexpr float finalz = _MAX(0, MANUAL_PROBE_START_Z); // If a MANUAL_PROBE_START_Z value is set, always respect it - #else - #warning "It's recommended to set some MANUAL_PROBE_START_Z value for manual leveling." - #endif - #if Z_CLEARANCE_BETWEEN_MANUAL_PROBES > 0 // A probe/obstacle clearance exists so there is a raise: - #ifndef MANUAL_PROBE_START_Z - const float finalz = current_position.z; // - Use the current Z for starting-Z if no MANUAL_PROBE_START_Z was provided - #endif - do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_MANUAL_PROBES); // - Raise Z, then move to the new XY - do_blocking_move_to_z(finalz); // - Lower down to the starting Z height, ready for adjustment! - #elif defined(MANUAL_PROBE_START_Z) // A starting-Z was provided, but there's no raise: - do_blocking_move_to_xy_z(pos, finalz); // - Move in XY then down to the starting Z height, ready for adjustment! - #else // Zero raise and no starting Z height either: - do_blocking_move_to_xy(pos); // - Move over with no raise, ready for adjustment! - #endif - - TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); - } - -#endif // MESH_BED_LEVELING || PROBE_MANUALLY - -#endif // HAS_LEVELING diff --git a/src/feature/bedlevel/bedlevel.h b/src/feature/bedlevel/bedlevel.h deleted file mode 100644 index aeafec1..0000000 --- a/src/feature/bedlevel/bedlevel.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfigPre.h" - -#if EITHER(RESTORE_LEVELING_AFTER_G28, ENABLE_LEVELING_AFTER_G28) - #define CAN_SET_LEVELING_AFTER_G28 1 -#endif - -#if ENABLED(PROBE_MANUALLY) - extern bool g29_in_progress; -#else - constexpr bool g29_in_progress = false; -#endif - -bool leveling_is_valid(); -void set_bed_leveling_enabled(const bool enable=true); -void reset_bed_level(); - -#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - void set_z_fade_height(const_float_t zfh, const bool do_report=true); -#endif - -#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY) - void _manual_goto_xy(const xy_pos_t &pos); -#endif - -/** - * A class to save and change the bed leveling state, - * then restore it when it goes out of scope. - */ -class TemporaryBedLevelingState { - bool saved; - public: - TemporaryBedLevelingState(const bool enable); - ~TemporaryBedLevelingState() { set_bed_leveling_enabled(saved); } -}; -#define TEMPORARY_BED_LEVELING_STATE(enable) const TemporaryBedLevelingState tbls(enable) - -#if HAS_MESH - - typedef float bed_mesh_t[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - #include "abl/bbl.h" - #elif ENABLED(AUTO_BED_LEVELING_UBL) - #include "ubl/ubl.h" - #elif ENABLED(MESH_BED_LEVELING) - #include "mbl/mesh_bed_leveling.h" - #endif - - #if EITHER(AUTO_BED_LEVELING_BILINEAR, MESH_BED_LEVELING) - - #include - - typedef float (*element_2d_fn)(const uint8_t, const uint8_t); - - /** - * Print calibration results for plotting or manual frame adjustment. - */ - void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const float *values); - - #endif - - struct mesh_index_pair { - xy_int8_t pos; - float distance; // When populated, the distance from the search location - void invalidate() { pos = -1; } - bool valid() const { return pos.x >= 0 && pos.y >= 0; } - #if ENABLED(AUTO_BED_LEVELING_UBL) - xy_pos_t meshpos() { - return { bedlevel.get_mesh_x(pos.x), bedlevel.get_mesh_y(pos.y) }; - } - #endif - operator xy_int8_t&() { return pos; } - operator const xy_int8_t&() const { return pos; } - }; - -#endif diff --git a/src/feature/bedlevel/hilbert_curve.cpp b/src/feature/bedlevel/hilbert_curve.cpp deleted file mode 100644 index 7474123..0000000 --- a/src/feature/bedlevel/hilbert_curve.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/********************* - * hilbert_curve.cpp * - *********************/ - -/**************************************************************************** - * Written By Marcio Teixeira 2021 - SynDaver Labs, Inc. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * To view a copy of the GNU General Public License, go to the following * - * location: . * - ****************************************************************************/ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(UBL_HILBERT_CURVE) - -#include "bedlevel.h" -#include "hilbert_curve.h" - -constexpr int8_t to_fix(int8_t v) { return v * 2; } -constexpr int8_t to_int(int8_t v) { return v / 2; } -constexpr uint8_t log2(uint8_t n) { return (n > 1) ? 1 + log2(n >> 1) : 0; } -constexpr uint8_t order(uint8_t n) { return uint8_t(log2(n - 1)) + 1; } -constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y)); -constexpr uint8_t dim = _BV(ord); - -static inline bool eval_candidate(int8_t x, int8_t y, hilbert_curve::callback_ptr func, void *data) { - // The print bed likely has fewer points than the full Hilbert - // curve, so cull unnecessary points - return x < (GRID_MAX_POINTS_X) && y < (GRID_MAX_POINTS_Y) ? func(x, y, data) : false; -} - -bool hilbert_curve::hilbert(int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n, hilbert_curve::callback_ptr func, void *data) { - /** - * Hilbert space-filling curve implementation - * - * x and y : coordinates of the bottom left corner - * xi and xj : i and j components of the unit x vector of the frame - * yi and yj : i and j components of the unit y vector of the frame - * - * From: http://www.fundza.com/algorithmic/space_filling/hilbert/basics/index.html - */ - if (n) - return hilbert(x, y, yi/2, yj/2, xi/2, xj/2, n-1, func, data) || - hilbert(x+xi/2, y+xj/2, xi/2, xj/2, yi/2, yj/2, n-1, func, data) || - hilbert(x+xi/2+yi/2, y+xj/2+yj/2, xi/2, xj/2, yi/2, yj/2, n-1, func, data) || - hilbert(x+xi/2+yi, y+xj/2+yj, -yi/2, -yj/2, -xi/2, -xj/2, n-1, func, data); - else - return eval_candidate(to_int(x+(xi+yi)/2), to_int(y+(xj+yj)/2), func, data); -} - -/** - * Calls func(x, y, data) for all points in the Hilbert curve. - * If that function returns true, the search is terminated. - */ -bool hilbert_curve::search(hilbert_curve::callback_ptr func, void *data) { - return hilbert(to_fix(0), to_fix(0),to_fix(dim), to_fix(0), to_fix(0), to_fix(dim), ord, func, data); -} - -/* Helper function for starting the search at a particular point */ - -typedef struct { - uint8_t x, y; - bool found_1st; - hilbert_curve::callback_ptr func; - void *data; -} search_from_t; - -static bool search_from_helper(uint8_t x, uint8_t y, void *data) { - search_from_t *d = (search_from_t *) data; - if (d->x == x && d->y == y) - d->found_1st = true; - return d->found_1st ? d->func(x, y, d->data) : false; -} - -/** - * Same as search, except start at a specific grid intersection point. - */ -bool hilbert_curve::search_from(uint8_t x, uint8_t y, hilbert_curve::callback_ptr func, void *data) { - search_from_t d; - d.x = x; - d.y = y; - d.found_1st = false; - d.func = func; - d.data = data; - // Call twice to allow search to wrap back to the beginning and picked up points prior to the start. - return search(search_from_helper, &d) || search(search_from_helper, &d); -} - -/** - * Like search_from, but takes a bed position and starts from the nearest - * point on the Hilbert curve. - */ -bool hilbert_curve::search_from_closest(const xy_pos_t &pos, hilbert_curve::callback_ptr func, void *data) { - // Find closest grid intersection - const uint8_t grid_x = LROUND(constrain(float(pos.x - (MESH_MIN_X)) / (MESH_X_DIST), 0, (GRID_MAX_POINTS_X) - 1)); - const uint8_t grid_y = LROUND(constrain(float(pos.y - (MESH_MIN_Y)) / (MESH_Y_DIST), 0, (GRID_MAX_POINTS_Y) - 1)); - return search_from(grid_x, grid_y, func, data); -} - -#endif // UBL_HILBERT_CURVE diff --git a/src/feature/bedlevel/hilbert_curve.h b/src/feature/bedlevel/hilbert_curve.h deleted file mode 100644 index a5dce8a..0000000 --- a/src/feature/bedlevel/hilbert_curve.h +++ /dev/null @@ -1,32 +0,0 @@ -/******************* - * hilbert_curve.h * - *******************/ - -/**************************************************************************** - * Written By Marcio Teixeira 2021 - SynDaver Labs, Inc. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * To view a copy of the GNU General Public License, go to the following * - * location: . * - ****************************************************************************/ - -#pragma once - -class hilbert_curve { - public: - typedef bool (*callback_ptr)(uint8_t x, uint8_t y, void *data); - static bool search(callback_ptr func, void *data); - static bool search_from(uint8_t x, uint8_t y, callback_ptr func, void *data); - static bool search_from_closest(const xy_pos_t &pos, callback_ptr func, void *data); - private: - static bool hilbert(int8_t x, int8_t y, int8_t xi, int8_t xj, int8_t yi, int8_t yj, uint8_t n, callback_ptr func, void *data); -}; diff --git a/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp deleted file mode 100644 index 193cbbf..0000000 --- a/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(MESH_BED_LEVELING) - - #include "../bedlevel.h" - - #include "../../../module/motion.h" - - #if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" - #endif - - mesh_bed_leveling bedlevel; - - 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() { - LOOP_L_N(i, GRID_MAX_POINTS_X) - index_to_xpos[i] = MESH_MIN_X + i * (MESH_X_DIST); - LOOP_L_N(i, GRID_MAX_POINTS_Y) - index_to_ypos[i] = MESH_MIN_Y + i * (MESH_Y_DIST); - reset(); - } - - void mesh_bed_leveling::reset() { - z_offset = 0; - ZERO(z_values); - #if ENABLED(EXTENSIBLE_UI) - GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0); - #endif - } - - #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - - /** - * Prepare a mesh-leveled linear move in a Cartesian setup, - * splitting the move where it crosses mesh borders. - */ - void mesh_bed_leveling::line_to_destination(const_feedRate_t scaled_fr_mm_s, uint8_t x_splits, uint8_t y_splits) { - // Get current and destination cells for this line - xy_int8_t scel = cell_indexes(current_position), ecel = cell_indexes(destination); - NOMORE(scel.x, GRID_MAX_CELLS_X - 1); - NOMORE(scel.y, GRID_MAX_CELLS_Y - 1); - NOMORE(ecel.x, GRID_MAX_CELLS_X - 1); - NOMORE(ecel.y, GRID_MAX_CELLS_Y - 1); - - // Start and end in the same cell? No split needed. - if (scel == ecel) { - current_position = destination; - line_to_current_position(scaled_fr_mm_s); - return; - } - - #define MBL_SEGMENT_END(A) (current_position.A + (destination.A - current_position.A) * normalized_dist) - - float normalized_dist; - xyze_pos_t dest; - const int8_t gcx = _MAX(scel.x, ecel.x), gcy = _MAX(scel.y, ecel.y); - - // Crosses on the X and not already split on this X? - // The x_splits flags are insurance against rounding errors. - if (ecel.x != scel.x && TEST(x_splits, gcx)) { - // Split on the X grid line - CBI(x_splits, gcx); - dest = destination; - destination.x = index_to_xpos[gcx]; - normalized_dist = (destination.x - current_position.x) / (dest.x - current_position.x); - destination.y = MBL_SEGMENT_END(y); - } - // Crosses on the Y and not already split on this Y? - else if (ecel.y != scel.y && TEST(y_splits, gcy)) { - // Split on the Y grid line - CBI(y_splits, gcy); - dest = destination; - destination.y = index_to_ypos[gcy]; - normalized_dist = (destination.y - current_position.y) / (dest.y - current_position.y); - destination.x = MBL_SEGMENT_END(x); - } - else { - // Must already have been split on these border(s) - // This should be a rare case. - current_position = destination; - line_to_current_position(scaled_fr_mm_s); - return; - } - - destination.z = MBL_SEGMENT_END(z); - destination.e = MBL_SEGMENT_END(e); - - // Do the split and look for more borders - line_to_destination(scaled_fr_mm_s, x_splits, y_splits); - - // Restore destination from stack - destination = dest; - line_to_destination(scaled_fr_mm_s, x_splits, y_splits); - } - - #endif // IS_CARTESIAN && !SEGMENT_LEVELED_MOVES - - void mesh_bed_leveling::report_mesh() { - SERIAL_ECHOPAIR_F(STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh. Z offset: ", z_offset, 5); - SERIAL_ECHOLNPGM("\nMeasured points:"); - print_2d_array(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y, 5, z_values[0]); - } - -#endif // MESH_BED_LEVELING diff --git a/src/feature/bedlevel/mbl/mesh_bed_leveling.h b/src/feature/bedlevel/mbl/mesh_bed_leveling.h deleted file mode 100644 index 1a8e693..0000000 --- a/src/feature/bedlevel/mbl/mesh_bed_leveling.h +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../../inc/MarlinConfig.h" - -enum MeshLevelingState : char { - MeshReport, // G29 S0 - MeshStart, // G29 S1 - MeshNext, // G29 S2 - MeshSet, // G29 S3 - MeshSetZOffset, // G29 S4 - MeshReset // G29 S5 -}; - -#define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / (GRID_MAX_CELLS_X)) -#define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / (GRID_MAX_CELLS_Y)) - -class mesh_bed_leveling { -public: - 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 report_mesh(); - - static void reset(); - - FORCE_INLINE static bool has_mesh() { - GRID_LOOP(x, y) if (z_values[x][y]) return true; - return false; - } - - static bool mesh_is_valid() { return has_mesh(); } - - static void set_z(const int8_t px, const int8_t py, const_float_t z) { z_values[px][py] = z; } - - static 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_t z) { - int8_t px, py; - zigzag(index, px, py); - set_z(px, py, z); - } - - static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; } - static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; } - - static int8_t cell_index_x(const_float_t x) { - int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST); - return constrain(cx, 0, GRID_MAX_CELLS_X - 1); - } - static int8_t cell_index_y(const_float_t y) { - int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST); - return constrain(cy, 0, GRID_MAX_CELLS_Y - 1); - } - static xy_int8_t cell_indexes(const_float_t x, const_float_t y) { - return { cell_index_x(x), cell_index_y(y) }; - } - static xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } - - static int8_t probe_index_x(const_float_t x) { - int8_t px = (x - (MESH_MIN_X) + 0.5f * (MESH_X_DIST)) * RECIPROCAL(MESH_X_DIST); - return WITHIN(px, 0, (GRID_MAX_POINTS_X) - 1) ? px : -1; - } - static int8_t probe_index_y(const_float_t y) { - int8_t py = (y - (MESH_MIN_Y) + 0.5f * (MESH_Y_DIST)) * RECIPROCAL(MESH_Y_DIST); - return WITHIN(py, 0, (GRID_MAX_POINTS_Y) - 1) ? py : -1; - } - static xy_int8_t probe_indexes(const_float_t x, const_float_t y) { - return { probe_index_x(x), probe_index_y(y) }; - } - static xy_int8_t probe_indexes(const xy_pos_t &xy) { return probe_indexes(xy.x, xy.y); } - - static float calc_z0(const_float_t a0, const_float_t a1, const_float_t z1, const_float_t a2, const_float_t z2) { - const float delta_z = (z2 - z1) / (a2 - a1), - delta_a = a0 - a1; - return z1 + delta_a * delta_z; - } - - static float get_z_offset() { return z_offset; } - - static float get_z_correction(const xy_pos_t &pos) { - const xy_int8_t ind = cell_indexes(pos); - const float x1 = index_to_xpos[ind.x], x2 = index_to_xpos[ind.x+1], - y1 = index_to_xpos[ind.y], y2 = index_to_xpos[ind.y+1], - z1 = calc_z0(pos.x, x1, z_values[ind.x][ind.y ], x2, z_values[ind.x+1][ind.y ]), - z2 = calc_z0(pos.x, x1, z_values[ind.x][ind.y+1], x2, z_values[ind.x+1][ind.y+1]), - zf = calc_z0(pos.y, y1, z1, y2, z2); - - return zf; - } - - #if IS_CARTESIAN && DISABLED(SEGMENT_LEVELED_MOVES) - static void line_to_destination(const_feedRate_t scaled_fr_mm_s, uint8_t x_splits=0xFF, uint8_t y_splits=0xFF); - #endif -}; - -extern mesh_bed_leveling bedlevel; diff --git a/src/feature/bedlevel/ubl/ubl.cpp b/src/feature/bedlevel/ubl/ubl.cpp deleted file mode 100644 index 2aa50be..0000000 --- a/src/feature/bedlevel/ubl/ubl.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - -#include "../bedlevel.h" - -unified_bed_leveling bedlevel; - -#include "../../../MarlinCore.h" -#include "../../../gcode/gcode.h" - -#include "../../../module/settings.h" -#include "../../../module/planner.h" -#include "../../../module/motion.h" -#include "../../../module/probe.h" -#include "../../../module/temperature.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#endif - -#include "math.h" - -void unified_bed_leveling::echo_name() { SERIAL_ECHOPGM("Unified Bed Leveling"); } - -void unified_bed_leveling::report_current_mesh() { - if (!leveling_is_valid()) return; - SERIAL_ECHO_MSG(" G29 I999"); - GRID_LOOP(x, y) - if (!isnan(z_values[x][y])) { - SERIAL_ECHO_START(); - SERIAL_ECHOPGM(" M421 I", x, " J", y); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4); - serial_delay(75); // Prevent Printrun from exploding - } -} - -void unified_bed_leveling::report_state() { - echo_name(); - SERIAL_ECHO_TERNARY(planner.leveling_active, " System v" UBL_VERSION " ", "", "in", "active\n"); - serial_delay(50); -} - -int8_t unified_bed_leveling::storage_slot; - -float unified_bed_leveling::z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - -#define _GRIDPOS(A,N) (MESH_MIN_##A + N * (MESH_##A##_DIST)) - -const float -unified_bed_leveling::_mesh_index_to_xpos[GRID_MAX_POINTS_X] PROGMEM = ARRAY_N(GRID_MAX_POINTS_X, - _GRIDPOS(X, 0), _GRIDPOS(X, 1), _GRIDPOS(X, 2), _GRIDPOS(X, 3), - _GRIDPOS(X, 4), _GRIDPOS(X, 5), _GRIDPOS(X, 6), _GRIDPOS(X, 7), - _GRIDPOS(X, 8), _GRIDPOS(X, 9), _GRIDPOS(X, 10), _GRIDPOS(X, 11), - _GRIDPOS(X, 12), _GRIDPOS(X, 13), _GRIDPOS(X, 14), _GRIDPOS(X, 15) -), -unified_bed_leveling::_mesh_index_to_ypos[GRID_MAX_POINTS_Y] PROGMEM = ARRAY_N(GRID_MAX_POINTS_Y, - _GRIDPOS(Y, 0), _GRIDPOS(Y, 1), _GRIDPOS(Y, 2), _GRIDPOS(Y, 3), - _GRIDPOS(Y, 4), _GRIDPOS(Y, 5), _GRIDPOS(Y, 6), _GRIDPOS(Y, 7), - _GRIDPOS(Y, 8), _GRIDPOS(Y, 9), _GRIDPOS(Y, 10), _GRIDPOS(Y, 11), - _GRIDPOS(Y, 12), _GRIDPOS(Y, 13), _GRIDPOS(Y, 14), _GRIDPOS(Y, 15) -); - -volatile int16_t unified_bed_leveling::encoder_diff; - -unified_bed_leveling::unified_bed_leveling() { reset(); } - -void unified_bed_leveling::reset() { - const bool was_enabled = planner.leveling_active; - set_bed_leveling_enabled(false); - storage_slot = -1; - ZERO(z_values); - #if ENABLED(EXTENSIBLE_UI) - GRID_LOOP(x, y) ExtUI::onMeshUpdate(x, y, 0); - #endif - if (was_enabled) report_current_position(); -} - -void unified_bed_leveling::invalidate() { - set_bed_leveling_enabled(false); - set_all_mesh_points_to_value(NAN); -} - -void unified_bed_leveling::set_all_mesh_points_to_value(const_float_t value) { - GRID_LOOP(x, y) { - z_values[x][y] = value; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, value)); - } -} - -#if ENABLED(OPTIMIZED_MESH_STORAGE) - - constexpr float mesh_store_scaling = 1000; - constexpr int16_t Z_STEPS_NAN = INT16_MAX; - - void unified_bed_leveling::set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values) { - auto z_to_store = [](const_float_t z) { - if (isnan(z)) return Z_STEPS_NAN; - const int32_t z_scaled = TRUNC(z * mesh_store_scaling); - if (z_scaled == Z_STEPS_NAN || !WITHIN(z_scaled, INT16_MIN, INT16_MAX)) - return Z_STEPS_NAN; // If Z is out of range, return our custom 'NaN' - return int16_t(z_scaled); - }; - GRID_LOOP(x, y) stored_values[x][y] = z_to_store(in_values[x][y]); - } - - void unified_bed_leveling::set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values) { - auto store_to_z = [](const int16_t z_scaled) { - return z_scaled == Z_STEPS_NAN ? NAN : z_scaled / mesh_store_scaling; - }; - GRID_LOOP(x, y) out_values[x][y] = store_to_z(stored_values[x][y]); - } - -#endif // OPTIMIZED_MESH_STORAGE - -static void serial_echo_xy(const uint8_t sp, const int16_t x, const int16_t y) { - SERIAL_ECHO_SP(sp); - SERIAL_CHAR('('); - if (x < 100) { SERIAL_CHAR(' '); if (x < 10) SERIAL_CHAR(' '); } - SERIAL_ECHO(x); - SERIAL_CHAR(','); - if (y < 100) { SERIAL_CHAR(' '); if (y < 10) SERIAL_CHAR(' '); } - SERIAL_ECHO(y); - SERIAL_CHAR(')'); - serial_delay(5); -} - -static void serial_echo_column_labels(const uint8_t sp) { - SERIAL_ECHO_SP(7); - LOOP_L_N(i, GRID_MAX_POINTS_X) { - if (i < 10) SERIAL_CHAR(' '); - SERIAL_ECHO(i); - SERIAL_ECHO_SP(sp); - } - serial_delay(10); -} - -/** - * Produce one of these mesh maps: - * 0: Human-readable - * 1: CSV format for spreadsheet import - * 2: TODO: Display on Graphical LCD - * 4: Compact Human-Readable - */ -void unified_bed_leveling::display_map(const uint8_t map_type) { - const bool was = gcode.set_autoreport_paused(true); - - constexpr uint8_t eachsp = 1 + 6 + 1, // [-3.567] - twixt = eachsp * (GRID_MAX_POINTS_X) - 9 * 2; // Leading 4sp, Coordinates 9sp each - - const bool human = !(map_type & 0x3), csv = map_type == 1, lcd = map_type == 2, comp = map_type & 0x4; - - SERIAL_ECHOPGM("\nBed Topography Report"); - if (human) { - SERIAL_ECHOLNPGM(":\n"); - serial_echo_xy(4, MESH_MIN_X, MESH_MAX_Y); - serial_echo_xy(twixt, MESH_MAX_X, MESH_MAX_Y); - SERIAL_EOL(); - serial_echo_column_labels(eachsp - 2); - } - else - SERIAL_ECHOPGM(" for ", csv ? F("CSV:\n") : F("LCD:\n")); - - // Add XY probe offset from extruder because probe.probe_at_point() subtracts them when - // moving to the XY position to be measured. This ensures better agreement between - // the current Z position after G28 and the mesh values. - const xy_int8_t curr = closest_indexes(xy_pos_t(current_position) + probe.offset_xy); - - if (!lcd) SERIAL_EOL(); - for (int8_t j = (GRID_MAX_POINTS_Y) - 1; j >= 0; j--) { - - // Row Label (J index) - if (human) { - if (j < 10) SERIAL_CHAR(' '); - SERIAL_ECHO(j); - SERIAL_ECHOPGM(" |"); - } - - // Row Values (I indexes) - LOOP_L_N(i, GRID_MAX_POINTS_X) { - - // Opening Brace or Space - const bool is_current = i == curr.x && j == curr.y; - if (human) SERIAL_CHAR(is_current ? '[' : ' '); - - // Z Value at current I, J - const float f = z_values[i][j]; - if (lcd) { - // TODO: Display on Graphical LCD - } - else if (isnan(f)) - SERIAL_ECHOF(human ? F(" . ") : F("NAN")); - else if (human || csv) { - if (human && f >= 0) SERIAL_CHAR(f > 0 ? '+' : ' '); // Display sign also for positive numbers (' ' for 0) - SERIAL_DECIMAL(f); // Positive: 5 digits, Negative: 6 digits - } - if (csv && i < (GRID_MAX_POINTS_X) - 1) SERIAL_CHAR('\t'); - - // Closing Brace or Space - if (human) SERIAL_CHAR(is_current ? ']' : ' '); - - SERIAL_FLUSHTX(); - idle_no_sleep(); - } - if (!lcd) SERIAL_EOL(); - - // A blank line between rows (unless compact) - if (j && human && !comp) SERIAL_ECHOLNPGM(" |"); - } - - if (human) { - serial_echo_column_labels(eachsp - 2); - SERIAL_EOL(); - serial_echo_xy(4, MESH_MIN_X, MESH_MIN_Y); - serial_echo_xy(twixt, MESH_MAX_X, MESH_MIN_Y); - SERIAL_EOL(); - SERIAL_EOL(); - } - - gcode.set_autoreport_paused(was); -} - -bool unified_bed_leveling::sanity_check() { - uint8_t error_flag = 0; - - if (settings.calc_num_meshes() < 1) { - SERIAL_ECHOLNPGM("?Mesh too big for EEPROM."); - error_flag++; - } - - return !!error_flag; -} - -#if ENABLED(UBL_MESH_WIZARD) - - /** - * M1004: UBL Mesh Wizard - One-click mesh creation with or without a probe - */ - void GcodeSuite::M1004() { - - #define ALIGN_GCODE TERN(Z_STEPPER_AUTO_ALIGN, "G34", "") - #define PROBE_GCODE TERN(HAS_BED_PROBE, "G29P1\nG29P3", "G29P4R") - - #if HAS_HOTEND - if (parser.seenval('H')) { // Handle H# parameter to set Hotend temp - const celsius_t hotend_temp = parser.value_int(); // Marlin never sends itself F or K, always C - thermalManager.setTargetHotend(hotend_temp, 0); - thermalManager.wait_for_hotend(false); - } - #endif - - #if HAS_HEATED_BED - if (parser.seenval('B')) { // Handle B# parameter to set Bed temp - const celsius_t bed_temp = parser.value_int(); // Marlin never sends itself F or K, always C - thermalManager.setTargetBed(bed_temp); - thermalManager.wait_for_bed(false); - } - #endif - - process_subcommands_now(FPSTR(G28_STR)); // Home - process_subcommands_now(F(ALIGN_GCODE "\n" // Align multi z axis if available - PROBE_GCODE "\n" // Build mesh with available hardware - "G29P3\nG29P3")); // Ensure mesh is complete by running smart fill twice - - if (parser.seenval('S')) { - char umw_gcode[32]; - sprintf_P(umw_gcode, PSTR("G29S%i"), parser.value_int()); - queue.inject(umw_gcode); - } - - process_subcommands_now(F("G29A\nG29F10\n" // Set UBL Active & Fade 10 - "M140S0\nM104S0\n" // Turn off heaters - "M500")); // Store settings - } - -#endif // UBL_MESH_WIZARD - -#endif // AUTO_BED_LEVELING_UBL diff --git a/src/feature/bedlevel/ubl/ubl.h b/src/feature/bedlevel/ubl/ubl.h deleted file mode 100644 index a7103d6..0000000 --- a/src/feature/bedlevel/ubl/ubl.h +++ /dev/null @@ -1,316 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -//#define UBL_DEVEL_DEBUGGING - -#include "../../../module/motion.h" - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../../core/debug_out.h" - -#define UBL_VERSION "1.01" -#define UBL_OK false -#define UBL_ERR true - -enum MeshPointType : char { INVALID, REAL, SET_IN_BITMAP, CLOSEST }; - -// External references - -struct mesh_index_pair; - -#define MESH_X_DIST (float(MESH_MAX_X - (MESH_MIN_X)) / (GRID_MAX_CELLS_X)) -#define MESH_Y_DIST (float(MESH_MAX_Y - (MESH_MIN_Y)) / (GRID_MAX_CELLS_Y)) - -#if ENABLED(OPTIMIZED_MESH_STORAGE) - typedef int16_t mesh_store_t[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; -#endif - -typedef struct { - bool C_seen; - int8_t KLS_storage_slot; - uint8_t R_repetition, - V_verbosity, - P_phase, - T_map_type; - float B_shim_thickness, - C_constant; - xy_pos_t XY_pos; - xy_bool_t XY_seen; - #if HAS_BED_PROBE - uint8_t J_grid_size; - #endif -} G29_parameters_t; - -class unified_bed_leveling { -private: - - static G29_parameters_t param; - - #if IS_NEWPANEL - static void move_z_with_encoder(const_float_t multiplier); - static float measure_point_with_encoder(); - static float measure_business_card_thickness(); - static void manually_probe_remaining_mesh(const xy_pos_t&, const_float_t , const_float_t , const bool) __O0; - static void fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) __O0; - #endif - - static bool G29_parse_parameters() __O0; - static void shift_mesh_height(); - static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) __O0; - static void tilt_mesh_based_on_3pts(const_float_t z1, const_float_t z2, const_float_t z3); - static void tilt_mesh_based_on_probed_grid(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 bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) { - return smart_fill_one(pos.x, pos.y, dir.x, dir.y); - } - - #if ENABLED(UBL_DEVEL_DEBUGGING) - static void g29_what_command(); - static void g29_eeprom_dump(); - static void g29_compare_current_mesh_to_stored_mesh(); - #endif - -public: - - static void echo_name(); - static void report_current_mesh(); - 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 uint8_t) __O0; - static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const xy_pos_t&, const bool=false, MeshFlags *done_flags=nullptr) __O0; - static mesh_index_pair find_furthest_invalid_mesh_point() __O0; - static void reset(); - static void invalidate(); - static void set_all_mesh_points_to_value(const_float_t value); - static void adjust_mesh_to_mean(const bool cflag, const_float_t value); - static bool sanity_check(); - static void smart_fill_mesh(); - - static void G29() __O0; // O0 for no optimization - static void smart_fill_wlsf(const_float_t ) __O2; // O2 gives smaller code than Os on A2560 - - static int8_t storage_slot; - - static bed_mesh_t z_values; - #if ENABLED(OPTIMIZED_MESH_STORAGE) - static void set_store_from_mesh(const bed_mesh_t &in_values, mesh_store_t &stored_values); - static void set_mesh_from_store(const mesh_store_t &stored_values, bed_mesh_t &out_values); - #endif - static const float _mesh_index_to_xpos[GRID_MAX_POINTS_X], - _mesh_index_to_ypos[GRID_MAX_POINTS_Y]; - - #if HAS_MARLINUI_MENU - static bool lcd_map_control; - static void steppers_were_disabled(); - #else - static void steppers_were_disabled() {} - #endif - - static volatile int16_t encoder_diff; // Volatile because buttons may change it at interrupt time - - unified_bed_leveling(); - - FORCE_INLINE static void set_z(const int8_t px, const int8_t py, const_float_t z) { z_values[px][py] = z; } - - static int8_t cell_index_x_raw(const_float_t x) { - return FLOOR((x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST)); - } - - static int8_t cell_index_y_raw(const_float_t y) { - return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST)); - } - - static int8_t cell_index_x_valid(const_float_t x) { - return WITHIN(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); - } - - static int8_t cell_index_y_valid(const_float_t y) { - return WITHIN(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); - } - - static int8_t cell_index_x(const_float_t x) { - return constrain(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); - } - - static int8_t cell_index_y(const_float_t y) { - return constrain(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); - } - - static xy_int8_t cell_indexes(const_float_t x, const_float_t y) { - return { cell_index_x(x), cell_index_y(y) }; - } - static xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } - - static int8_t closest_x_index(const_float_t x) { - const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST); - return WITHIN(px, 0, (GRID_MAX_POINTS_X) - 1) ? px : -1; - } - static int8_t closest_y_index(const_float_t y) { - const int8_t py = (y - (MESH_MIN_Y) + (MESH_Y_DIST) * 0.5) * RECIPROCAL(MESH_Y_DIST); - return WITHIN(py, 0, (GRID_MAX_POINTS_Y) - 1) ? py : -1; - } - static xy_int8_t closest_indexes(const xy_pos_t &xy) { - return { closest_x_index(xy.x), closest_y_index(xy.y) }; - } - - /** - * 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_t a0, const_float_t a1, const_float_t z1, const_float_t a2, const_float_t z2) { - return z1 + (z2 - z1) * (a0 - a1) / (a2 - a1); - } - - #ifdef UBL_Z_RAISE_WHEN_OFF_MESH - #define _UBL_OUTER_Z_RAISE UBL_Z_RAISE_WHEN_OFF_MESH - #else - #define _UBL_OUTER_Z_RAISE NAN - #endif - - /** - * 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. - */ - static float z_correction_for_x_on_horizontal_mesh_line(const_float_t rx0, const int x1_i, const int yi) { - if (!WITHIN(x1_i, 0, (GRID_MAX_POINTS_X) - 1) || !WITHIN(yi, 0, (GRID_MAX_POINTS_Y) - 1)) { - - if (DEBUGGING(LEVELING)) { - if (WITHIN(x1_i, 0, (GRID_MAX_POINTS_X) - 1)) DEBUG_ECHOPGM("yi"); else DEBUG_ECHOPGM("x1_i"); - DEBUG_ECHOLNPGM(" out of bounds in z_correction_for_x_on_horizontal_mesh_line(rx0=", rx0, ",x1_i=", x1_i, ",yi=", yi, ")"); - } - - // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN. - return _UBL_OUTER_Z_RAISE; - } - - const float xratio = (rx0 - get_mesh_x(x1_i)) * RECIPROCAL(MESH_X_DIST), - z1 = z_values[x1_i][yi]; - - return z1 + xratio * (z_values[_MIN(x1_i, (GRID_MAX_POINTS_X) - 2) + 1][yi] - z1); // Don't allow x1_i+1 to be past the end of the array - // If it is, it is clamped to the last element of the - // z_values[][] array and no correction is applied. - } - - // - // See comments above for z_correction_for_x_on_horizontal_mesh_line - // - static float z_correction_for_y_on_vertical_mesh_line(const_float_t ry0, const int xi, const int y1_i) { - if (!WITHIN(xi, 0, (GRID_MAX_POINTS_X) - 1) || !WITHIN(y1_i, 0, (GRID_MAX_POINTS_Y) - 1)) { - - if (DEBUGGING(LEVELING)) { - if (WITHIN(xi, 0, (GRID_MAX_POINTS_X) - 1)) DEBUG_ECHOPGM("y1_i"); else DEBUG_ECHOPGM("xi"); - DEBUG_ECHOLNPGM(" out of bounds in z_correction_for_y_on_vertical_mesh_line(ry0=", ry0, ", xi=", xi, ", y1_i=", y1_i, ")"); - } - - // The requested location is off the mesh. Return UBL_Z_RAISE_WHEN_OFF_MESH or NAN. - return _UBL_OUTER_Z_RAISE; - } - - const float yratio = (ry0 - get_mesh_y(y1_i)) * RECIPROCAL(MESH_Y_DIST), - z1 = z_values[xi][y1_i]; - - return z1 + yratio * (z_values[xi][_MIN(y1_i, (GRID_MAX_POINTS_Y) - 2) + 1] - z1); // Don't allow y1_i+1 to be past the end of the array - // If it is, it is clamped to the last element of the - // z_values[][] array and no correction is applied. - } - - /** - * 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_t rx0, const_float_t ry0) { - const int8_t cx = cell_index_x(rx0), cy = cell_index_y(ry0); // return values are clamped - - /** - * Check if the requested location is off the mesh. If so, and - * UBL_Z_RAISE_WHEN_OFF_MESH is specified, that value is returned. - */ - #ifdef UBL_Z_RAISE_WHEN_OFF_MESH - if (!WITHIN(rx0, MESH_MIN_X, MESH_MAX_X) || !WITHIN(ry0, MESH_MIN_Y, MESH_MAX_Y)) - return UBL_Z_RAISE_WHEN_OFF_MESH; - #endif - - const uint8_t mx = _MIN(cx, (GRID_MAX_POINTS_X) - 2) + 1, my = _MIN(cy, (GRID_MAX_POINTS_Y) - 2) + 1, - x0 = get_mesh_x(cx), x1 = get_mesh_x(cx + 1); - const float z1 = calc_z0(rx0, x0, z_values[cx][cy], x1, z_values[mx][cy]), - z2 = calc_z0(rx0, x0, z_values[cx][my], x1, z_values[mx][my]); - float z0 = calc_z0(ry0, get_mesh_y(cy), z1, get_mesh_y(cy + 1), z2); - - if (isnan(z0)) { // If part of the Mesh is undefined, it will show up as NAN - z0 = 0.0; // 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 - // needed to complete the height correction. - - if (DEBUGGING(MESH_ADJUST)) DEBUG_ECHOLNPGM("??? Yikes! NAN in "); - } - - if (DEBUGGING(MESH_ADJUST)) { - DEBUG_ECHOPGM("get_z_correction(", rx0, ", ", ry0); - DEBUG_ECHOLNPAIR_F(") => ", z0, 6); - } - - return z0; - } - static float get_z_correction(const xy_pos_t &pos) { return get_z_correction(pos.x, pos.y); } - - static constexpr float get_z_offset() { return 0.0f; } - - static float get_mesh_x(const uint8_t i) { - return i < (GRID_MAX_POINTS_X) ? pgm_read_float(&_mesh_index_to_xpos[i]) : MESH_MIN_X + i * (MESH_X_DIST); - } - static float get_mesh_y(const uint8_t i) { - return i < (GRID_MAX_POINTS_Y) ? pgm_read_float(&_mesh_index_to_ypos[i]) : MESH_MIN_Y + i * (MESH_Y_DIST); - } - - #if UBL_SEGMENTED - static bool line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s); - #else - static void line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t e); - #endif - - static bool mesh_is_valid() { - GRID_LOOP(x, y) if (isnan(z_values[x][y])) return false; - return true; - } - -}; // class unified_bed_leveling - -extern unified_bed_leveling bedlevel; - -// Prevent debugging propagating to other files -#include "../../../core/debug_out.h" diff --git a/src/feature/bedlevel/ubl/ubl_G29.cpp b/src/feature/bedlevel/ubl/ubl_G29.cpp deleted file mode 100644 index 6b45e48..0000000 --- a/src/feature/bedlevel/ubl/ubl_G29.cpp +++ /dev/null @@ -1,1851 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - -#include "../bedlevel.h" - -#include "../../../MarlinCore.h" -#include "../../../HAL/shared/eeprom_api.h" -#include "../../../libs/hex_print.h" -#include "../../../module/settings.h" -#include "../../../lcd/marlinui.h" -#include "../../../module/planner.h" -#include "../../../module/motion.h" -#include "../../../module/probe.h" -#include "../../../gcode/gcode.h" -#include "../../../libs/least_squares_fit.h" - -#if HAS_MULTI_HOTEND - #include "../../../module/tool_change.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../../core/debug_out.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#endif - -#if ENABLED(UBL_HILBERT_CURVE) - #include "../hilbert_curve.h" -#endif - -#include - -#define UBL_G29_P31 - -#if HAS_MARLINUI_MENU - - bool unified_bed_leveling::lcd_map_control = false; - - void unified_bed_leveling::steppers_were_disabled() { - if (lcd_map_control) { - lcd_map_control = false; - ui.defer_status_screen(false); - } - } - - void ubl_map_screen(); - -#endif - -#define SIZE_OF_LITTLE_RAISE 1 -#define BIG_RAISE_NOT_NEEDED 0 - -/** - * 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 G29 P2 C tells the Manual Probe subsystem to not use the current nozzle - * location in its search for the closest unmeasured Mesh Point. Instead, attempt to - * start at one end of the uprobed points and Continue sequentially. - * - * 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. - * - * 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. For delta - * printers only the areas where the probe and nozzle can both reach will 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 0), 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 Print the current Mesh as G-code that can be used to restore the mesh anytime. - * - * 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 - * 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) - * - * X # X Location for this command - * - * Y # Y Location for this command - * - * With UBL_DEVEL_DEBUGGING: - * - * K # Kompare Kompare current Mesh with stored Mesh #, replacing current Mesh with the result. - * This command literally performs a diff between two Meshes. - * - * Q-1 Dump EEPROM Dump the UBL contents stored in EEPROM as HEX format. Useful for developers to help - * verify correct operation of the UBL. - * - * W What? Display valuable UBL data. - * - * - * 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 required. - * - * When you do a G28 and G29 P1 to automatically build your first mesh, you are going to notice that - * UBL probes points increasingly further from the starting location. (The starting location defaults - * to the center of the bed.) In contrast, ABL and MBL follow a zigzag pattern. The spiral pattern is - * especially better for Delta printers, since it populates the center of the mesh first, allowing for - * a quicker test print to verify settings. You don't need to populate the entire mesh to use it. - * After all, you don't want to spend a lot of time generating a mesh only to realize the resolution - * or probe offsets are incorrect. Mesh-generation gathers points starting closest to the nozzle unless - * an (X,Y) coordinate pair is given. - * - * Unified Bed Leveling uses a lot of EEPROM storage to hold its data, and it takes some effort to get - * the mesh just right. To prevent this valuable data from being destroyed as the EEPROM structure - * evolves, UBL stores all mesh data at the end of EEPROM. - * - * UBL is founded on Edward Patel'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. - */ - -G29_parameters_t unified_bed_leveling::param; - -void unified_bed_leveling::G29() { - - bool probe_deployed = false; - if (G29_parse_parameters()) return; // Abort on parameter error - - const uint8_t p_val = parser.byteval('P'); - const bool may_move = p_val == 1 || p_val == 2 || p_val == 4 || parser.seen_test('J'); - #if HAS_MULTI_HOTEND - const uint8_t old_tool_index = active_extruder; - #endif - - // Check for commands that require the printer to be homed - if (may_move) { - planner.synchronize(); - // Send 'N' to force homing before G29 (internal only) - if (axes_should_home() || parser.seen_test('N')) gcode.home_all_axes(); - TERN_(HAS_MULTI_HOTEND, if (active_extruder != 0) tool_change(0, true)); - } - - // Invalidate one or more nearby mesh points, possibly all. - if (parser.seen('I')) { - uint8_t count = parser.has_value() ? parser.value_byte() : 1; - bool invalidate_all = count >= GRID_MAX_POINTS; - if (!invalidate_all) { - while (count--) { - if ((count & 0x0F) == 0x0F) idle(); - const mesh_index_pair closest = find_closest_mesh_point_of_type(REAL, param.XY_pos); - // No more REAL mesh points to invalidate? Assume the user meant - // to invalidate the ENTIRE mesh, which can't be done with - // find_closest_mesh_point (which only returns REAL points). - if (closest.pos.x < 0) { invalidate_all = true; break; } - z_values[closest.pos.x][closest.pos.y] = NAN; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(closest.pos, 0.0f)); - } - } - if (invalidate_all) { - invalidate(); - SERIAL_ECHOPGM("Entire Mesh"); - } - else - SERIAL_ECHOPGM("Locations"); - SERIAL_ECHOLNPGM(" invalidated.\n"); - } - - if (parser.seen('Q')) { - const int16_t test_pattern = parser.has_value() ? parser.value_int() : -99; - if (!WITHIN(test_pattern, TERN0(UBL_DEVEL_DEBUGGING, -1), 2)) { - SERIAL_ECHOLNPGM("?Invalid (Q) test pattern. (" TERN(UBL_DEVEL_DEBUGGING, "-1", "0") " to 2)\n"); - return; - } - SERIAL_ECHOLNPGM("Applying test pattern.\n"); - switch (test_pattern) { - - default: - case -1: TERN_(UBL_DEVEL_DEBUGGING, g29_eeprom_dump()); break; - - case 0: - GRID_LOOP(x, y) { // Create a bowl shape similar to a poorly-calibrated Delta - const float p1 = 0.5f * (GRID_MAX_POINTS_X) - x, - p2 = 0.5f * (GRID_MAX_POINTS_Y) - y; - z_values[x][y] += 2.0f * HYPOT(p1, p2); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - } - break; - - case 1: - LOOP_L_N(x, GRID_MAX_POINTS_X) { // Create a diagonal line several Mesh cells thick that is raised - const uint8_t x2 = x + (x < (GRID_MAX_POINTS_Y) - 1 ? 1 : -1); - z_values[x][x] += 9.999f; - z_values[x][x2] += 9.999f; // We want the altered line several mesh points thick - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(x, x, z_values[x][x]); - ExtUI::onMeshUpdate(x, (x2), z_values[x][x2]); - #endif - } - 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_test('C') ? param.C_constant : 9.99f; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - } - break; - } - } - - #if HAS_BED_PROBE - - if (parser.seen_test('J')) { - save_ubl_active_state_and_disable(); - tilt_mesh_based_on_probed_grid(param.J_grid_size == 0); // Zero size does 3-Point - restore_ubl_active_state_and_leave(); - #if ENABLED(UBL_G29_J_RECENTER) - do_blocking_move_to_xy(0.5f * ((MESH_MIN_X) + (MESH_MAX_X)), 0.5f * ((MESH_MIN_Y) + (MESH_MAX_Y))); - #endif - report_current_position(); - probe_deployed = true; - } - - #endif // HAS_BED_PROBE - - if (parser.seen_test('P')) { - if (WITHIN(param.P_phase, 0, 1) && storage_slot == -1) { - storage_slot = 0; - SERIAL_ECHOLNPGM("Default storage slot 0 selected."); - } - - switch (param.P_phase) { - case 0: - // - // Zero Mesh Data - // - reset(); - SERIAL_ECHOLNPGM("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_test('C')) { - invalidate(); - SERIAL_ECHOLNPGM("Mesh invalidated. Probing mesh."); - } - if (param.V_verbosity > 1) { - SERIAL_ECHOPGM("Probing around (", param.XY_pos.x); - SERIAL_CHAR(','); - SERIAL_DECIMAL(param.XY_pos.y); - SERIAL_ECHOLNPGM(").\n"); - } - probe_entire_mesh(param.XY_pos, parser.seen_test('T'), parser.seen_test('E'), parser.seen_test('U')); - - report_current_position(); - probe_deployed = true; - } break; - - #endif // HAS_BED_PROBE - - case 2: { - #if HAS_MARLINUI_MENU - // - // Manually Probe Mesh in areas that can't be reached by the probe - // - SERIAL_ECHOLNPGM("Manually probing unreachable points."); - do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); - - if (parser.seen_test('C') && !param.XY_seen) { - - /** - * 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. - */ - param.XY_pos.set( - #if IS_KINEMATIC - X_HOME_POS, Y_HOME_POS - #else - probe.offset_xy.x > 0 ? X_BED_SIZE : 0, - probe.offset_xy.y < 0 ? Y_BED_SIZE : 0 - #endif - ); - } - - if (parser.seen('B')) { - param.B_shim_thickness = parser.has_value() ? parser.value_float() : measure_business_card_thickness(); - if (ABS(param.B_shim_thickness) > 1.5f) { - SERIAL_ECHOLNPGM("?Error in Business Card measurement."); - return; - } - probe_deployed = true; - } - - if (!position_is_reachable(param.XY_pos)) { - SERIAL_ECHOLNPGM("XY outside printable radius."); - return; - } - - const float height = parser.floatval('H', Z_CLEARANCE_BETWEEN_PROBES); - manually_probe_remaining_mesh(param.XY_pos, height, param.B_shim_thickness, parser.seen_test('T')); - - SERIAL_ECHOLNPGM("G29 P2 finished."); - - report_current_position(); - - #else - - SERIAL_ECHOLNPGM("?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 (param.C_seen) { - if (param.R_repetition >= GRID_MAX_POINTS) { - set_all_mesh_points_to_value(param.C_constant); - } - else { - while (param.R_repetition--) { // this only populates reachable mesh points near - const mesh_index_pair closest = find_closest_mesh_point_of_type(INVALID, param.XY_pos); - const xy_int8_t &cpos = closest.pos; - if (cpos.x < 0) { - // No more REAL INVALID mesh points to populate, so we ASSUME - // user meant to populate ALL INVALID mesh points to value - GRID_LOOP(x, y) if (isnan(z_values[x][y])) z_values[x][y] = param.C_constant; - break; // No more invalid Mesh Points to populate - } - else { - z_values[cpos.x][cpos.y] = param.C_constant; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(cpos, param.C_constant)); - } - } - } - } - else { - const float cvf = parser.value_float(); - switch ((int)TRUNC(cvf * 10.0f) - 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.10f) * 100.0f, // 3.12345 -> 2.345 - weight_factor = weight_power ? POW(10.0f, 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 HAS_MARLINUI_MENU - fine_tune_mesh(param.XY_pos, parser.seen_test('T')); - #else - SERIAL_ECHOLNPGM("?P4 is only available when an LCD is present."); - return; - #endif - break; - - case 5: adjust_mesh_to_mean(param.C_seen, param.C_constant); break; - - case 6: shift_mesh_height(); break; - } - } - - #if ENABLED(UBL_DEVEL_DEBUGGING) - - // - // 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_test('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(); - - #endif // UBL_DEVEL_DEBUGGING - - - // - // Load a Mesh from the EEPROM - // - - if (parser.seen('L')) { // Load Current Mesh Data - param.KLS_storage_slot = parser.has_value() ? (int8_t)parser.value_int() : storage_slot; - - int16_t a = settings.calc_num_meshes(); - - if (!a) { - SERIAL_ECHOLNPGM("?EEPROM storage not available."); - return; - } - - if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); - return; - } - - settings.load_mesh(param.KLS_storage_slot); - storage_slot = param.KLS_storage_slot; - - SERIAL_ECHOLNPGM(STR_DONE); - } - - // - // Store a Mesh in the EEPROM - // - - if (parser.seen('S')) { // Store (or Save) Current Mesh Data - param.KLS_storage_slot = parser.has_value() ? (int8_t)parser.value_int() : storage_slot; - - if (param.KLS_storage_slot == -1) // Special case: 'Export' the mesh to the - return report_current_mesh(); // host so it can be saved in a file. - - int16_t a = settings.calc_num_meshes(); - - if (!a) { - SERIAL_ECHOLNPGM("?EEPROM storage not available."); - goto LEAVE; - } - - if (!WITHIN(param.KLS_storage_slot, 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); - goto LEAVE; - } - - settings.store_mesh(param.KLS_storage_slot); - storage_slot = param.KLS_storage_slot; - - SERIAL_ECHOLNPGM(STR_DONE); - } - - if (parser.seen_test('T')) - display_map(param.T_map_type); - - LEAVE: - - #if HAS_MARLINUI_MENU - ui.reset_alert_level(); - ui.quick_feedback(); - ui.reset_status(); - ui.release(); - #endif - - #ifdef Z_PROBE_END_SCRIPT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Probe End Script: ", Z_PROBE_END_SCRIPT); - if (probe_deployed) { - planner.synchronize(); - gcode.process_subcommands_now(F(Z_PROBE_END_SCRIPT)); - } - #else - UNUSED(probe_deployed); - #endif - - TERN_(HAS_MULTI_HOTEND, if (old_tool_index != 0) tool_change(old_tool_index)); - return; -} - -/** - * M420 C - * G29 P5 C : Adjust Mesh To Mean (and subtract the given offset). - * Find the mean average and shift the mesh to center on that value. - */ -void unified_bed_leveling::adjust_mesh_to_mean(const bool cflag, const_float_t offset) { - float sum = 0; - uint8_t n = 0; - GRID_LOOP(x, 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; - GRID_LOOP(x, y) - if (!isnan(z_values[x][y])) - sum_of_diff_squared += sq(z_values[x][y] - mean); - - SERIAL_ECHOLNPGM("# of samples: ", n); - SERIAL_ECHOLNPAIR_F("Mean Mesh Height: ", mean, 6); - - const float sigma = SQRT(sum_of_diff_squared / (n + 1)); - SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); - - if (cflag) - GRID_LOOP(x, y) - if (!isnan(z_values[x][y])) { - z_values[x][y] -= mean + offset; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - } -} - -/** - * G29 P6 C : Shift Mesh Height by a uniform constant. - */ -void unified_bed_leveling::shift_mesh_height() { - GRID_LOOP(x, y) - if (!isnan(z_values[x][y])) { - z_values[x][y] += param.C_constant; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - } -} - -#if HAS_BED_PROBE - /** - * G29 P1 T V : Probe Entire Mesh - * 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 xy_pos_t &nearby, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) { - probe.deploy(); // Deploy before ui.capture() to allow for PAUSE_BEFORE_DEPLOY_STOW - - TERN_(HAS_MARLINUI_MENU, ui.capture()); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); - TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart()); - - save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained - uint8_t count = GRID_MAX_POINTS; - - mesh_index_pair best; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_START)); - do { - if (do_ubl_mesh_map) display_map(param.T_map_type); - - const uint8_t point_num = (GRID_MAX_POINTS - count) + 1; - SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, "."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS))); - - #if HAS_MARLINUI_MENU - if (ui.button_pressed()) { - ui.quick_feedback(false); // Preserve button state for click-and-hold - SERIAL_ECHOLNPGM("\nMesh only partially populated.\n"); - ui.wait_for_release(); - ui.quick_feedback(); - ui.release(); - probe.stow(); // Release UI before stow to allow for PAUSE_BEFORE_DEPLOY_STOW - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); - return restore_ubl_active_state_and_leave(); - } - #endif - - best = do_furthest - ? find_furthest_invalid_mesh_point() - : find_closest_mesh_point_of_type(INVALID, nearby, true); - - if (best.pos.x >= 0) { // mesh point found and is reachable by probe - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_POINT_START)); - const float measured_z = probe.probe_at_point( - best.meshpos(), - stow_probe ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity - ); - z_values[best.pos.x][best.pos.y] = measured_z; - #if ENABLED(EXTENSIBLE_UI) - ExtUI::onMeshUpdate(best.pos, ExtUI::G29_POINT_FINISH); - ExtUI::onMeshUpdate(best.pos, measured_z); - #endif - } - SERIAL_FLUSH(); // Prevent host M105 buffer overrun. - - } while (best.pos.x >= 0 && --count); - - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_FINISH)); - - // Release UI during stow to allow for PAUSE_BEFORE_DEPLOY_STOW - TERN_(HAS_MARLINUI_MENU, ui.release()); - probe.stow(); - TERN_(HAS_MARLINUI_MENU, ui.capture()); - - probe.move_z_after_probing(); - - restore_ubl_active_state_and_leave(); - - do_blocking_move_to_xy( - constrain(nearby.x - probe.offset_xy.x, MESH_MIN_X, MESH_MAX_X), - constrain(nearby.y - probe.offset_xy.y, MESH_MIN_Y, MESH_MAX_Y) - ); - - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); - TERN_(DWIN_LCD_PROUI, DWIN_LevelingDone()); - } - -#endif // HAS_BED_PROBE - -void set_message_with_feedback(FSTR_P const fstr) { - #if HAS_MARLINUI_MENU - ui.set_status(fstr); - ui.quick_feedback(); - #else - UNUSED(fstr); - #endif -} - -#if HAS_MARLINUI_MENU - - typedef void (*clickFunc_t)(); - - bool _click_and_hold(const clickFunc_t func=nullptr) { - if (ui.button_pressed()) { - ui.quick_feedback(false); // Preserve button state for click-and-hold - const millis_t nxt = millis() + 1500UL; - while (ui.button_pressed()) { // Loop while the encoder is pressed. Uses hardware flag! - idle(); // idle, of course - if (ELAPSED(millis(), nxt)) { // After 1.5 seconds - ui.quick_feedback(); - if (func) (*func)(); - ui.wait_for_release(); - return true; - } - } - } - serial_delay(15); - return false; - } - - void unified_bed_leveling::move_z_with_encoder(const_float_t multiplier) { - ui.wait_for_release(); - while (!ui.button_pressed()) { - idle(); - gcode.reset_stepper_timeout(); // Keep steppers powered - if (encoder_diff) { - do_blocking_move_to_z(current_position.z + float(encoder_diff) * multiplier); - encoder_diff = 0; - } - } - } - - float unified_bed_leveling::measure_point_with_encoder() { - KEEPALIVE_STATE(PAUSED_FOR_USER); - const float z_step = 0.01f; - move_z_with_encoder(z_step); - return current_position.z; - } - - static void echo_and_take_a_measurement() { SERIAL_ECHOLNPGM(" and take a measurement."); } - - float unified_bed_leveling::measure_business_card_thickness() { - ui.capture(); - save_ubl_active_state_and_disable(); // Disable bed level correction for probing - - do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), MANUAL_PROBE_START_Z); - //, _MIN(planner.settings.max_feedrate_mm_s[X_AXIS], planner.settings.max_feedrate_mm_s[Y_AXIS]) * 0.5f); - planner.synchronize(); - - SERIAL_ECHOPGM("Place shim under nozzle"); - LCD_MESSAGE(MSG_UBL_BC_INSERT); - ui.return_to_status(); - echo_and_take_a_measurement(); - - const float z1 = measure_point_with_encoder(); - do_blocking_move_to_z(current_position.z + SIZE_OF_LITTLE_RAISE); - planner.synchronize(); - - SERIAL_ECHOPGM("Remove shim"); - LCD_MESSAGE(MSG_UBL_BC_REMOVE); - echo_and_take_a_measurement(); - - const float z2 = measure_point_with_encoder(); - do_blocking_move_to_z(current_position.z + Z_CLEARANCE_BETWEEN_PROBES); - - const float thickness = ABS(z1 - z2); - - if (param.V_verbosity > 1) { - SERIAL_ECHOPAIR_F("Business Card is ", thickness, 4); - SERIAL_ECHOLNPGM("mm thick."); - } - - restore_ubl_active_state_and_leave(); - - return thickness; - } - - /** - * G29 P2 : Manually Probe Remaining Mesh Points. - * Move to INVALID points and - * NOTE: Blocks the G-code queue and captures Marlin UI during use. - */ - void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const_float_t z_clearance, const_float_t thick, const bool do_ubl_mesh_map) { - ui.capture(); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); - - save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained - do_blocking_move_to_xy_z(current_position, z_clearance); - - ui.return_to_status(); - - mesh_index_pair location; - const xy_int8_t &lpos = location.pos; - do { - location = find_closest_mesh_point_of_type(INVALID, pos); - // It doesn't matter if the probe can't reach the NAN location. This is a manual probe. - if (!location.valid()) continue; - - const xyz_pos_t ppos = { get_mesh_x(lpos.x), get_mesh_y(lpos.y), z_clearance }; - - if (!position_is_reachable(ppos)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points) - - LCD_MESSAGE(MSG_UBL_MOVING_TO_NEXT); - - do_blocking_move_to(ppos); - do_z_clearance(z_clearance); - - KEEPALIVE_STATE(PAUSED_FOR_USER); - ui.capture(); - - if (do_ubl_mesh_map) display_map(param.T_map_type); // Show user where we're probing - - if (parser.seen_test('B')) { - SERIAL_ECHOPGM("Place Shim & Measure"); - LCD_MESSAGE(MSG_UBL_BC_INSERT); - } - else { - SERIAL_ECHOPGM("Measure"); - LCD_MESSAGE(MSG_UBL_BC_INSERT2); - } - - const float z_step = 0.01f; // 0.01mm per encoder tick, occasionally step - move_z_with_encoder(z_step); - - if (_click_and_hold([]{ - SERIAL_ECHOLNPGM("\nMesh only partially populated."); - do_z_clearance(Z_CLEARANCE_DEPLOY_PROBE); - })) return restore_ubl_active_state_and_leave(); - - // Store the Z position minus the shim height - z_values[lpos.x][lpos.y] = current_position.z - thick; - - // Tell the external UI to update - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, z_values[lpos.x][lpos.y])); - - if (param.V_verbosity > 2) - SERIAL_ECHOLNPAIR_F("Mesh Point Measured at: ", z_values[lpos.x][lpos.y], 6); - SERIAL_FLUSH(); // Prevent host M105 buffer overrun. - } while (location.valid()); - - if (do_ubl_mesh_map) display_map(param.T_map_type); // show user where we're probing - - restore_ubl_active_state_and_leave(); - do_blocking_move_to_xy_z(pos, Z_CLEARANCE_DEPLOY_PROBE); - - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); - } - - /** - * G29 P4 : Mesh Fine-Tuning. Go to point(s) and adjust values with the LCD. - * NOTE: Blocks the G-code queue and captures Marlin UI during use. - */ - void unified_bed_leveling::fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) { - if (!parser.seen_test('R')) // fine_tune_mesh() is special. If no repetition count flag is specified - param.R_repetition = 1; // do exactly one mesh location. Otherwise use what the parser decided. - - #if ENABLED(UBL_MESH_EDIT_MOVES_Z) - const float h_offset = parser.seenval('H') ? parser.value_linear_units() : MANUAL_PROBE_START_Z; - if (!WITHIN(h_offset, 0, 10)) { - SERIAL_ECHOLNPGM("Offset out of bounds. (0 to 10mm)\n"); - return; - } - #endif - - mesh_index_pair location; - - if (!position_is_reachable(pos)) { - SERIAL_ECHOLNPGM("(X,Y) outside printable radius."); - return; - } - - save_ubl_active_state_and_disable(); - - LCD_MESSAGE(MSG_UBL_FINE_TUNE_MESH); - ui.capture(); // Take over control of the LCD encoder - - do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance - - MeshFlags done_flags{0}; - const xy_int8_t &lpos = location.pos; - - #if IS_TFTGLCD_PANEL - ui.ubl_mesh_edit_start(0); // Change current screen before calling ui.ubl_plot - safe_delay(50); - #endif - - do { - location = find_closest_mesh_point_of_type(SET_IN_BITMAP, pos, false, &done_flags); - - if (lpos.x < 0) break; // Stop when there are no more reachable points - - done_flags.mark(lpos); // Mark this location as 'adjusted' so a new - // location is used on the next loop - const xyz_pos_t raw = { get_mesh_x(lpos.x), get_mesh_y(lpos.y), Z_CLEARANCE_BETWEEN_PROBES }; - - if (!position_is_reachable(raw)) break; // SHOULD NOT OCCUR (find_closest_mesh_point_of_type only returns reachable) - - do_blocking_move_to(raw); // Move the nozzle to the edit point with probe clearance - - TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset)); // Move Z to the given 'H' offset before editing - - KEEPALIVE_STATE(PAUSED_FOR_USER); - - if (do_ubl_mesh_map) display_map(param.T_map_type); // Display the current point - - #if IS_TFTGLCD_PANEL - ui.ubl_plot(lpos.x, lpos.y); // update plot screen - #endif - - ui.refresh(); - - float new_z = z_values[lpos.x][lpos.y]; - if (isnan(new_z)) new_z = 0; // Invalid points begin at 0 - new_z = FLOOR(new_z * 1000) * 0.001f; // Chop off digits after the 1000ths place - - ui.ubl_mesh_edit_start(new_z); - - SET_SOFT_ENDSTOP_LOOSE(true); - - do { - idle_no_sleep(); - new_z = ui.ubl_mesh_value(); - TERN_(UBL_MESH_EDIT_MOVES_Z, do_blocking_move_to_z(h_offset + new_z)); // Move the nozzle as the point is edited - SERIAL_FLUSH(); // Prevent host M105 buffer overrun. - } while (!ui.button_pressed()); - - SET_SOFT_ENDSTOP_LOOSE(false); - - if (!lcd_map_control) ui.return_to_status(); // Just editing a single point? Return to status - - // Button held down? Abort editing - if (_click_and_hold([]{ - ui.return_to_status(); - do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); - set_message_with_feedback(GET_TEXT_F(MSG_EDITING_STOPPED)); - })) break; - - // TODO: Disable leveling here so the Z value becomes the 'native' Z value. - - z_values[lpos.x][lpos.y] = new_z; // Save the updated Z value - - // TODO: Re-enable leveling here so Z is correctly based on the updated mesh. - - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, new_z)); - - serial_delay(20); // No switch noise - ui.refresh(); - - } while (lpos.x >= 0 && --param.R_repetition > 0); - - if (do_ubl_mesh_map) display_map(param.T_map_type); - restore_ubl_active_state_and_leave(); - - do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); - - LCD_MESSAGE(MSG_UBL_DONE_EDITING_MESH); - SERIAL_ECHOLNPGM("Done Editing Mesh"); - - if (lcd_map_control) - ui.goto_screen(ubl_map_screen); - else - ui.return_to_status(); - } - -#endif // HAS_MARLINUI_MENU - -/** - * Parse and validate most G29 parameters, store for use by G29 functions. - */ -bool unified_bed_leveling::G29_parse_parameters() { - bool err_flag = false; - - set_message_with_feedback(GET_TEXT_F(MSG_UBL_DOING_G29)); - - param.C_constant = 0; - param.R_repetition = 0; - - if (parser.seen('R')) { - param.R_repetition = parser.has_value() ? parser.value_byte() : GRID_MAX_POINTS; - NOMORE(param.R_repetition, GRID_MAX_POINTS); - if (param.R_repetition < 1) { - SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n"); - return UBL_ERR; - } - } - - param.V_verbosity = parser.byteval('V'); - if (!WITHIN(param.V_verbosity, 0, 4)) { - SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4).\n"); - err_flag = true; - } - - if (parser.seen('P')) { - const uint8_t pv = parser.value_byte(); - #if !HAS_BED_PROBE - if (pv == 1) { - SERIAL_ECHOLNPGM("G29 P1 requires a probe.\n"); - err_flag = true; - } - else - #endif - { - param.P_phase = pv; - if (!WITHIN(param.P_phase, 0, 6)) { - SERIAL_ECHOLNPGM("?(P)hase value invalid (0-6).\n"); - err_flag = true; - } - } - } - - if (parser.seen('J')) { - #if HAS_BED_PROBE - param.J_grid_size = parser.value_byte(); - if (param.J_grid_size && !WITHIN(param.J_grid_size, 2, 9)) { - SERIAL_ECHOLNPGM("?Invalid grid size (J) specified (2-9).\n"); - err_flag = true; - } - #else - SERIAL_ECHOLNPGM("G29 J action requires a probe.\n"); - err_flag = true; - #endif - } - - param.XY_seen.x = parser.seenval('X'); - float sx = param.XY_seen.x ? parser.value_float() : current_position.x; - param.XY_seen.y = parser.seenval('Y'); - float sy = param.XY_seen.y ? parser.value_float() : current_position.y; - - if (param.XY_seen.x != param.XY_seen.y) { - SERIAL_ECHOLNPGM("Both X & Y locations must be specified.\n"); - err_flag = true; - } - - // If X or Y are not valid, use center of the bed values - // (for UBL_HILBERT_CURVE default to lower-left corner instead) - if (!COORDINATE_OKAY(sx, X_MIN_BED, X_MAX_BED)) sx = TERN(UBL_HILBERT_CURVE, 0, X_CENTER); - if (!COORDINATE_OKAY(sy, Y_MIN_BED, Y_MAX_BED)) sy = TERN(UBL_HILBERT_CURVE, 0, Y_CENTER); - - if (err_flag) return UBL_ERR; - - param.XY_pos.set(sx, sy); - - /** - * 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_test('A')) { - if (parser.seen_test('D')) { - SERIAL_ECHOLNPGM("?Can't activate and deactivate at the same time.\n"); - return UBL_ERR; - } - set_bed_leveling_enabled(true); - report_state(); - } - else if (parser.seen_test('D')) { - set_bed_leveling_enabled(false); - report_state(); - } - - // Set global 'C' flag and its value - if ((param.C_seen = parser.seen('C'))) - param.C_constant = parser.value_float(); - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (parser.seenval('F')) { - const float fh = parser.value_float(); - if (!WITHIN(fh, 0, 100)) { - SERIAL_ECHOLNPGM("?(F)ade height for Bed Level Correction not plausible.\n"); - return UBL_ERR; - } - set_z_fade_height(fh); - } - #endif - - param.T_map_type = parser.byteval('T'); - if (!WITHIN(param.T_map_type, 0, 2)) { - SERIAL_ECHOLNPGM("Invalid map type.\n"); - return UBL_ERR; - } - return UBL_OK; -} - -static uint8_t ubl_state_at_invocation = 0; - -#if ENABLED(UBL_DEVEL_DEBUGGING) - static uint8_t ubl_state_recursion_chk = 0; -#endif - -void unified_bed_leveling::save_ubl_active_state_and_disable() { - #if ENABLED(UBL_DEVEL_DEBUGGING) - ubl_state_recursion_chk++; - if (ubl_state_recursion_chk != 1) { - SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row."); - set_message_with_feedback(GET_TEXT_F(MSG_UBL_SAVE_ERROR)); - return; - } - #endif - ubl_state_at_invocation = planner.leveling_active; - set_bed_leveling_enabled(false); -} - -void unified_bed_leveling::restore_ubl_active_state_and_leave() { - TERN_(HAS_MARLINUI_MENU, ui.release()); - #if ENABLED(UBL_DEVEL_DEBUGGING) - if (--ubl_state_recursion_chk) { - SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times."); - set_message_with_feedback(GET_TEXT_F(MSG_UBL_RESTORE_ERROR)); - return; - } - #endif - set_bed_leveling_enabled(ubl_state_at_invocation); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); -} - -mesh_index_pair unified_bed_leveling::find_furthest_invalid_mesh_point() { - - bool found_a_NAN = false, found_a_real = false; - - mesh_index_pair farthest { -1, -1, -99999.99 }; - - GRID_LOOP(i, j) { - if (!isnan(z_values[i][j])) continue; // Skip valid mesh points - - // Skip unreachable points - if (!probe.can_reach(get_mesh_x(i), get_mesh_y(j))) - continue; - - found_a_NAN = true; - - xy_int8_t nearby { -1, -1 }; - float d1, d2 = 99999.9f; - GRID_LOOP(k, l) { - if (isnan(z_values[k][l])) continue; - - found_a_real = true; - - // Add in a random weighting factor that scrambles the probing of the - // last half of the mesh (when every unprobed mesh point is one index - // from a probed location). - - d1 = HYPOT(i - k, j - l) + (1.0f / ((millis() % 47) + 13)); - - if (d1 < d2) { // Invalid mesh point (i,j) is closer to the defined point (k,l) - d2 = d1; - nearby.set(i, j); - } - } - - // - // At this point d2 should have the near defined mesh point to invalid mesh point (i,j) - // - - if (found_a_real && nearby.x >= 0 && d2 > farthest.distance) { - farthest.pos = nearby; // Found an invalid location farther from the defined mesh point - farthest.distance = d2; - } - } // GRID_LOOP - - if (!found_a_real && found_a_NAN) { // if the mesh is totally unpopulated, start the probing - farthest.pos.set((GRID_MAX_POINTS_X) / 2, (GRID_MAX_POINTS_Y) / 2); - farthest.distance = 1; - } - return farthest; -} - -#if ENABLED(UBL_HILBERT_CURVE) - - typedef struct { - MeshPointType type; - MeshFlags *done_flags; - bool probe_relative; - mesh_index_pair closest; - } find_closest_t; - - static bool test_func(uint8_t i, uint8_t j, void *data) { - find_closest_t *d = (find_closest_t*)data; - if ( d->type == CLOSEST || d->type == (isnan(bedlevel.z_values[i][j]) ? INVALID : REAL) - || (d->type == SET_IN_BITMAP && !d->done_flags->marked(i, j)) - ) { - // Found a Mesh Point of the specified type! - const xy_pos_t mpos = { bedlevel.get_mesh_x(i), bedlevel.get_mesh_y(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 (!(d->probe_relative ? probe.can_reach(mpos) : position_is_reachable(mpos))) - return false; - d->closest.pos.set(i, j); - return true; - } - return false; - } - -#endif - -mesh_index_pair unified_bed_leveling::find_closest_mesh_point_of_type(const MeshPointType type, const xy_pos_t &pos, const bool probe_relative/*=false*/, MeshFlags *done_flags/*=nullptr*/) { - - #if ENABLED(UBL_HILBERT_CURVE) - - find_closest_t d; - d.type = type; - d.done_flags = done_flags; - d.probe_relative = probe_relative; - d.closest.invalidate(); - hilbert_curve::search_from_closest(pos, test_func, &d); - return d.closest; - - #else - - mesh_index_pair closest; - closest.invalidate(); - closest.distance = -99999.9f; - - // Get the reference position, either nozzle or probe - const xy_pos_t ref = probe_relative ? pos + probe.offset_xy : pos; - - float best_so_far = 99999.99f; - - GRID_LOOP(i, j) { - if ( type == CLOSEST || type == (isnan(z_values[i][j]) ? INVALID : REAL) - || (type == SET_IN_BITMAP && !done_flags->marked(i, j)) - ) { - // Found a Mesh Point of the specified type! - const xy_pos_t mpos = { get_mesh_x(i), get_mesh_y(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_relative ? probe.can_reach(mpos) : position_is_reachable(mpos))) - continue; - - // Reachable. Check if it's the best_so_far location to the nozzle. - - const xy_pos_t diff = current_position - mpos; - const float distance = (ref - mpos).magnitude() + diff.magnitude() * 0.1f; - - // factor in the distance from the current location for the normal case - // so the nozzle isn't running all over the bed. - if (distance < best_so_far) { - best_so_far = distance; // Found a closer location with the desired value type. - closest.pos.set(i, j); - closest.distance = best_so_far; - } - } - } // GRID_LOOP - - return closest; - - #endif -} - -/** - * '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 float v = z_values[x][y]; - if (isnan(v)) { // A NAN... - const int8_t dx = x + xdir, dy = y + ydir; - const float v1 = z_values[dx][dy]; - if (!isnan(v1)) { // ...next to a pair of real values? - const float v2 = z_values[dx + xdir][dy + ydir]; - if (!isnan(v2)) { - z_values[x][y] = v1 < v2 ? v1 : v1 + v1 - v2; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - 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 }; - - LOOP_L_N(i, COUNT(info)) { - const smart_fill_info *f = (smart_fill_info*)pgm_read_ptr(&info[i]); - const int8_t sx = pgm_read_byte(&f->sx), sy = pgm_read_byte(&f->sy), - ex = pgm_read_byte(&f->ex), ey = pgm_read_byte(&f->ey); - 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 - - //#define VALIDATE_MESH_TILT - - #include "../../../libs/vector_3.h" - - void unified_bed_leveling::tilt_mesh_based_on_probed_grid(const bool do_3_pt_leveling) { - const float x_min = probe.min_x(), x_max = probe.max_x(), - y_min = probe.min_y(), y_max = probe.max_y(), - dx = (x_max - x_min) / (param.J_grid_size - 1), - dy = (y_max - y_min) / (param.J_grid_size - 1); - - xy_float_t points[3]; - probe.get_three_points(points); - - float measured_z; - bool abort_flag = false; - - #ifdef VALIDATE_MESH_TILT - float z1, z2, z3; // Needed for algorithm validation below - #endif - - struct linear_fit_data lsf_results; - incremental_LSF_reset(&lsf_results); - - if (do_3_pt_leveling) { - SERIAL_ECHOLNPGM("Tilting mesh (1/3)"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); - - measured_z = probe.probe_at_point(points[0], PROBE_PT_RAISE, param.V_verbosity); - if (isnan(measured_z)) - abort_flag = true; - else { - measured_z -= get_z_correction(points[0]); - #ifdef VALIDATE_MESH_TILT - z1 = measured_z; - #endif - if (param.V_verbosity > 3) { - serial_spaces(16); - SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); - } - incremental_LSF(&lsf_results, points[0], measured_z); - } - - if (!abort_flag) { - SERIAL_ECHOLNPGM("Tilting mesh (2/3)"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); - - measured_z = probe.probe_at_point(points[1], PROBE_PT_RAISE, param.V_verbosity); - #ifdef VALIDATE_MESH_TILT - z2 = measured_z; - #endif - if (isnan(measured_z)) - abort_flag = true; - else { - measured_z -= get_z_correction(points[1]); - if (param.V_verbosity > 3) { - serial_spaces(16); - SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); - } - incremental_LSF(&lsf_results, points[1], measured_z); - } - } - - if (!abort_flag) { - SERIAL_ECHOLNPGM("Tilting mesh (3/3)"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH))); - - measured_z = probe.probe_at_point(points[2], PROBE_PT_LAST_STOW, param.V_verbosity); - #ifdef VALIDATE_MESH_TILT - z3 = measured_z; - #endif - if (isnan(measured_z)) - abort_flag = true; - else { - measured_z -= get_z_correction(points[2]); - if (param.V_verbosity > 3) { - serial_spaces(16); - SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); - } - incremental_LSF(&lsf_results, points[2], measured_z); - } - } - - probe.stow(); - probe.move_z_after_probing(); - - if (abort_flag) { - SERIAL_ECHOLNPGM("?Error probing point. Aborting operation."); - return; - } - } - else { // !do_3_pt_leveling - - bool zig_zag = false; - - const uint16_t total_points = sq(param.J_grid_size); - uint16_t point_num = 1; - - xy_pos_t rpos; - LOOP_L_N(ix, param.J_grid_size) { - rpos.x = x_min + ix * dx; - LOOP_L_N(iy, param.J_grid_size) { - rpos.y = y_min + dy * (zig_zag ? param.J_grid_size - 1 - iy : iy); - - if (!abort_flag) { - SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n"); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points)); - - measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling - - abort_flag = isnan(measured_z); - - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (DEBUGGING(LEVELING)) { - const xy_pos_t lpos = rpos.asLogical(); - DEBUG_CHAR('('); - DEBUG_ECHO_F(rpos.x, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(rpos.y, 7); - DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(lpos.y, 7); - DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7); - DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7); - } - #endif - - measured_z -= get_z_correction(rpos) /* + probe.offset.z */ ; - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR_F(" final >>>---> ", measured_z, 7); - - if (param.V_verbosity > 3) { - serial_spaces(16); - SERIAL_ECHOLNPGM("Corrected_Z=", measured_z); - } - incremental_LSF(&lsf_results, rpos, measured_z); - } - - point_num++; - } - - zig_zag ^= true; - } - } - probe.stow(); - probe.move_z_after_probing(); - - if (abort_flag || finish_incremental_LSF(&lsf_results)) { - SERIAL_ECHOPGM("Could not complete LSF!"); - return; - } - - vector_3 normal = vector_3(lsf_results.A, lsf_results.B, 1).get_normal(); - - if (param.V_verbosity > 2) { - SERIAL_ECHOPAIR_F("bed plane normal = [", normal.x, 7); - SERIAL_CHAR(','); - SERIAL_ECHO_F(normal.y, 7); - SERIAL_CHAR(','); - SERIAL_ECHO_F(normal.z, 7); - SERIAL_ECHOLNPGM("]"); - } - - matrix_3x3 rotation = matrix_3x3::create_look_at(vector_3(lsf_results.A, lsf_results.B, 1)); - - GRID_LOOP(i, j) { - float mx = get_mesh_x(i), my = get_mesh_y(j), mz = z_values[i][j]; - - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("before rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOPGM("] ---> "); - DEBUG_DELAY(20); - } - - rotation.apply_rotation_xyz(mx, my, mz); - - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPAIR_F("after rotation = [", mx, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(my, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(mz, 7); - DEBUG_ECHOLNPGM("]"); - DEBUG_DELAY(20); - } - - z_values[i][j] = mz - lsf_results.D; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(i, j, z_values[i][j])); - } - - if (DEBUGGING(LEVELING)) { - rotation.debug(F("rotation matrix:\n")); - DEBUG_ECHOPAIR_F("LSF Results A=", lsf_results.A, 7); - DEBUG_ECHOPAIR_F(" B=", lsf_results.B, 7); - DEBUG_ECHOLNPAIR_F(" D=", lsf_results.D, 7); - DEBUG_DELAY(55); - - DEBUG_ECHOPAIR_F("bed plane normal = [", normal.x, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(normal.y, 7); - DEBUG_CHAR(','); - DEBUG_ECHO_F(normal.z, 7); - DEBUG_ECHOLNPGM("]"); - DEBUG_EOL(); - - /** - * Use the code below to check the validity of the mesh tilting algorithm. - * 3-Point Mesh Tilt uses the same algorithm as grid-based tilting, but only - * three points are used in the calculation. This guarantees that each probed point - * has an exact match when get_z_correction() for that location is calculated. - * The Z error between the probed point locations and the get_z_correction() - * numbers for those locations should be 0. - */ - #ifdef VALIDATE_MESH_TILT - auto d_from = []{ DEBUG_ECHOPGM("D from "); }; - auto normed = [&](const xy_pos_t &pos, const_float_t zadd) { - return normal.x * pos.x + normal.y * pos.y + zadd; - }; - auto debug_pt = [](FSTR_P const pre, const xy_pos_t &pos, const_float_t zadd) { - d_from(); SERIAL_ECHOF(pre); - DEBUG_ECHO_F(normed(pos, zadd), 6); - DEBUG_ECHOLNPAIR_F(" Z error = ", zadd - get_z_correction(pos), 6); - }; - debug_pt(F("1st point: "), probe_pt[0], normal.z * z1); - debug_pt(F("2nd point: "), probe_pt[1], normal.z * z2); - debug_pt(F("3rd point: "), probe_pt[2], normal.z * z3); - d_from(); DEBUG_ECHOPGM("safe home with Z="); - DEBUG_ECHOLNPAIR_F("0 : ", normed(safe_homing_xy, 0), 6); - d_from(); DEBUG_ECHOPGM("safe home with Z="); - DEBUG_ECHOLNPAIR_F("mesh value ", normed(safe_homing_xy, get_z_correction(safe_homing_xy)), 6); - DEBUG_ECHOPGM(" Z error = (", Z_SAFE_HOMING_X_POINT, ",", Z_SAFE_HOMING_Y_POINT); - DEBUG_ECHOLNPAIR_F(") = ", get_z_correction(safe_homing_xy), 6); - #endif - } // DEBUGGING(LEVELING) - - } - -#endif // HAS_BED_PROBE - -#if ENABLED(UBL_G29_P31) - void unified_bed_leveling::smart_fill_wlsf(const_float_t 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); - - GRID_LOOP(jx, jy) if (!isnan(z_values[jx][jy])) SBI(bitmap[jx], jy); - - xy_pos_t ppos; - LOOP_L_N(ix, GRID_MAX_POINTS_X) { - ppos.x = get_mesh_x(ix); - LOOP_L_N(iy, GRID_MAX_POINTS_Y) { - ppos.y = get_mesh_y(iy); - if (isnan(z_values[ix][iy])) { - // undefined mesh point at (ppos.x,ppos.y), compute weighted LSF from original valid mesh points. - incremental_LSF_reset(&lsf_results); - xy_pos_t rpos; - LOOP_L_N(jx, GRID_MAX_POINTS_X) { - rpos.x = get_mesh_x(jx); - LOOP_L_N(jy, GRID_MAX_POINTS_Y) { - if (TEST(bitmap[jx], jy)) { - rpos.y = get_mesh_y(jy); - const float rz = z_values[jx][jy], - w = 1.0f + weight_scaled / (rpos - ppos).magnitude(); - incremental_WLSF(&lsf_results, rpos, rz, w); - } - } - } - if (finish_incremental_LSF(&lsf_results)) { - SERIAL_ECHOLNPGM("Insufficient data"); - return; - } - const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y; - z_values[ix][iy] = ez; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, z_values[ix][iy])); - idle(); // housekeeping - } - } - } - - SERIAL_ECHOLNPGM("done"); - } -#endif // UBL_G29_P31 - -#if ENABLED(UBL_DEVEL_DEBUGGING) - /** - * 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 (storage_slot == -1) - SERIAL_ECHOPGM("No Mesh Loaded."); - else - SERIAL_ECHOPGM("Mesh ", storage_slot, " Loaded."); - SERIAL_EOL(); - serial_delay(50); - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - SERIAL_ECHOLNPAIR_F("Fade Height M420 Z", planner.z_fade_height, 4); - #endif - - adjust_mesh_to_mean(param.C_seen, param.C_constant); - - #if HAS_BED_PROBE - SERIAL_ECHOLNPAIR_F("Probe Offset M851 Z", probe.offset.z, 7); - #endif - - SERIAL_ECHOLNPGM("MESH_MIN_X " STRINGIFY(MESH_MIN_X) "=", MESH_MIN_X); serial_delay(50); - SERIAL_ECHOLNPGM("MESH_MIN_Y " STRINGIFY(MESH_MIN_Y) "=", MESH_MIN_Y); serial_delay(50); - SERIAL_ECHOLNPGM("MESH_MAX_X " STRINGIFY(MESH_MAX_X) "=", MESH_MAX_X); serial_delay(50); - SERIAL_ECHOLNPGM("MESH_MAX_Y " STRINGIFY(MESH_MAX_Y) "=", MESH_MAX_Y); serial_delay(50); - SERIAL_ECHOLNPGM("GRID_MAX_POINTS_X ", GRID_MAX_POINTS_X); serial_delay(50); - SERIAL_ECHOLNPGM("GRID_MAX_POINTS_Y ", GRID_MAX_POINTS_Y); serial_delay(50); - SERIAL_ECHOLNPGM("MESH_X_DIST ", MESH_X_DIST); - SERIAL_ECHOLNPGM("MESH_Y_DIST ", MESH_Y_DIST); serial_delay(50); - - SERIAL_ECHOPGM("X-Axis Mesh Points at: "); - LOOP_L_N(i, GRID_MAX_POINTS_X) { - SERIAL_ECHO_F(LOGICAL_X_POSITION(get_mesh_x(i)), 3); - SERIAL_ECHOPGM(" "); - serial_delay(25); - } - SERIAL_EOL(); - - SERIAL_ECHOPGM("Y-Axis Mesh Points at: "); - LOOP_L_N(i, GRID_MAX_POINTS_Y) { - SERIAL_ECHO_F(LOGICAL_Y_POSITION(get_mesh_y(i)), 3); - SERIAL_ECHOPGM(" "); - serial_delay(25); - } - SERIAL_EOL(); - - #if HAS_KILL - SERIAL_ECHOLNPGM("Kill pin on :", KILL_PIN, " state:", kill_state()); - #endif - - SERIAL_EOL(); - serial_delay(50); - - #if ENABLED(UBL_DEVEL_DEBUGGING) - SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk); - serial_delay(50); - - SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index())); - serial_delay(50); - - SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL(); - SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL(); - serial_delay(25); - - SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index()))); - serial_delay(50); - - SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n"); - serial_delay(25); - #endif // UBL_DEVEL_DEBUGGING - - if (!sanity_check()) { - echo_name(); - SERIAL_ECHOLNPGM(" 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() { - uint8_t cccc; - - SERIAL_ECHO_MSG("EEPROM Dump:"); - persistentStore.access_start(); - for (uint16_t i = 0; i < persistentStore.capacity(); i += 16) { - if (!(i & 0x3)) idle(); - print_hex_word(i); - SERIAL_ECHOPGM(": "); - for (uint16_t j = 0; j < 16; j++) { - persistentStore.read_data(i + j, &cccc, sizeof(uint8_t)); - print_hex_byte(cccc); - SERIAL_CHAR(' '); - } - SERIAL_EOL(); - } - SERIAL_EOL(); - persistentStore.access_finish(); - } - - /** - * 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() { - const int16_t a = settings.calc_num_meshes(); - - if (!a) { - SERIAL_ECHOLNPGM("?EEPROM storage not available."); - return; - } - - if (!parser.has_value() || !WITHIN(parser.value_int(), 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot.\n?Use 0 to ", a - 1); - return; - } - - param.KLS_storage_slot = (int8_t)parser.value_int(); - - float tmp_z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - settings.load_mesh(param.KLS_storage_slot, &tmp_z_values); - - SERIAL_ECHOLNPGM("Subtracting mesh in slot ", param.KLS_storage_slot, " from current mesh."); - - GRID_LOOP(x, y) { - z_values[x][y] -= tmp_z_values[x][y]; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, z_values[x][y])); - } - } - -#endif // UBL_DEVEL_DEBUGGING - -#endif // AUTO_BED_LEVELING_UBL diff --git a/src/feature/bedlevel/ubl/ubl_motion.cpp b/src/feature/bedlevel/ubl/ubl_motion.cpp deleted file mode 100644 index 18110c6..0000000 --- a/src/feature/bedlevel/ubl/ubl_motion.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - -#include "../bedlevel.h" -#include "../../../module/planner.h" -#include "../../../module/motion.h" - -#if ENABLED(DELTA) - #include "../../../module/delta.h" -#endif - -#include "../../../MarlinCore.h" -#include - -//#define DEBUG_UBL_MOTION -#define DEBUG_OUT ENABLED(DEBUG_UBL_MOTION) -#include "../../../core/debug_out.h" - -#if !UBL_SEGMENTED - - // TODO: The first and last parts of a move might result in very short segment(s) - // after getting split on the cell boundary, so moves like that should not - // get split. This will be most common for moves that start/end near the - // corners of cells. To fix the issue, simply check if the start/end of the line - // is very close to a cell boundary in advance and don't split the line there. - - void unified_bed_leveling::line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const 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 - */ - #if HAS_POSITION_MODIFIERS - xyze_pos_t start = current_position, end = destination; - planner.apply_modifiers(start); - planner.apply_modifiers(end); - #else - const xyze_pos_t &start = current_position, &end = destination; - #endif - - const xy_int8_t istart = cell_indexes(start), iend = cell_indexes(end); - - // A move within the same cell needs no splitting - if (istart == iend) { - - FINAL_MOVE: - - // When UBL_Z_RAISE_WHEN_OFF_MESH is disabled Z correction is extrapolated from the edge of the mesh - #ifdef UBL_Z_RAISE_WHEN_OFF_MESH - // For a move off the UBL mesh, use a constant Z raise - if (!cell_index_x_valid(end.x) || !cell_index_y_valid(end.y)) { - - // Note: There is no Z Correction in this case. We are off the mesh and don't know what - // a reasonable correction would be, UBL_Z_RAISE_WHEN_OFF_MESH will be used instead of - // a calculated (Bi-Linear interpolation) correction. - - end.z += UBL_Z_RAISE_WHEN_OFF_MESH; - planner.buffer_segment(end, scaled_fr_mm_s, extruder); - current_position = destination; - return; - } - #endif - - // The distance is always MESH_X_DIST so multiply by the constant reciprocal. - const float xratio = (end.x - get_mesh_x(iend.x)) * RECIPROCAL(MESH_X_DIST), - yratio = (end.y - get_mesh_y(iend.y)) * RECIPROCAL(MESH_Y_DIST), - z1 = z_values[iend.x][iend.y ] + xratio * (z_values[iend.x + 1][iend.y ] - z_values[iend.x][iend.y ]), - z2 = z_values[iend.x][iend.y + 1] + xratio * (z_values[iend.x + 1][iend.y + 1] - z_values[iend.x][iend.y + 1]); - - // X cell-fraction done. Interpolate the two Z offsets with the Y fraction for the final Z offset. - const float z0 = (z1 + (z2 - z1) * yratio) * planner.fade_scaling_factor_for_z(end.z); - - // Undefined parts of the Mesh in z_values[][] are NAN. - // Replace NAN corrections with 0.0 to prevent NAN propagation. - if (!isnan(z0)) end.z += z0; - planner.buffer_segment(end, scaled_fr_mm_s, extruder); - current_position = destination; - return; - } - - /** - * Past this point the move is known to cross one or more mesh lines. Check for the most common - * case - crossing only one X or Y line - after details are worked out to reduce computation. - */ - - const xy_float_t dist = end - start; - const xy_bool_t neg { dist.x < 0, dist.y < 0 }; - const xy_int8_t ineg { int8_t(neg.x), int8_t(neg.y) }; - const xy_float_t sign { neg.x ? -1.0f : 1.0f, neg.y ? -1.0f : 1.0f }; - const xy_int8_t iadd { int8_t(iend.x == istart.x ? 0 : sign.x), int8_t(iend.y == istart.y ? 0 : sign.y) }; - - /** - * Compute the extruder scaling factor for each partial move, checking for - * zero-length moves that would result in an infinite scaling factor. - * A float divide is required for this, but then it just multiplies. - * Also select a scaling factor based on the larger of the X and Y - * components. The larger of the two is used to preserve precision. - */ - - const xy_float_t ad = sign * dist; - const bool use_x_dist = ad.x > ad.y; - - float on_axis_distance = use_x_dist ? dist.x : dist.y; - - const float z_normalized_dist = (end.z - start.z) / on_axis_distance; // Allow divide by zero - #if HAS_EXTRUDERS - const float e_normalized_dist = (end.e - start.e) / on_axis_distance; - const bool inf_normalized_flag = isinf(e_normalized_dist); - #endif - - xy_int8_t icell = istart; - - const float ratio = dist.y / dist.x, // Allow divide by zero - c = start.y - ratio * start.x; - - const bool inf_ratio_flag = isinf(ratio); - - xyze_pos_t dest; // Stores XYZE for segmented moves - - /** - * Handle vertical lines that stay within one column. - * These need not be perfectly vertical. - */ - if (iadd.x == 0) { // Vertical line? - icell.y += ineg.y; // Line going down? Just go to the bottom. - while (icell.y != iend.y + ineg.y) { - icell.y += iadd.y; - const float next_mesh_line_y = get_mesh_y(icell.y); - - /** - * Skip the calculations for an infinite slope. - * For others the next X is the same so this can continue. - * Calculate X at the next Y mesh line. - */ - dest.x = inf_ratio_flag ? start.x : (next_mesh_line_y - c) / ratio; - - float z0 = z_correction_for_x_on_horizontal_mesh_line(dest.x, icell.x, icell.y) - * planner.fade_scaling_factor_for_z(end.z); - - // Undefined parts of the Mesh in z_values[][] are NAN. - // Replace NAN corrections with 0.0 to prevent NAN propagation. - if (isnan(z0)) z0 = 0.0; - - dest.y = get_mesh_y(icell.y); - - /** - * Without this check, it's possible to generate a zero length move, as in the case where - * the line is heading down, starting exactly on a mesh line boundary. Since this is rare - * it might be fine to remove this check and let planner.buffer_segment() filter it out. - */ - if (dest.y != start.y) { - if (!inf_normalized_flag) { // fall-through faster than branch - on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; - TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); - dest.z = start.z + on_axis_distance * z_normalized_dist; - } - else { - TERN_(HAS_EXTRUDERS, dest.e = end.e); - dest.z = end.z; - } - - dest.z += z0; - planner.buffer_segment(dest, scaled_fr_mm_s, extruder); - - } - else - DEBUG_ECHOLNPGM("[ubl] skip Y segment"); - } - - // At the final destination? Usually not, but when on a Y Mesh Line it's completed. - if (xy_pos_t(current_position) != xy_pos_t(end)) - goto FINAL_MOVE; - - current_position = destination; - return; - } - - /** - * Handle horizontal lines that stay within one row. - * These need not be perfectly horizontal. - */ - if (iadd.y == 0) { // Horizontal line? - icell.x += ineg.x; // Heading left? Just go to the left edge of the cell for the first move. - - while (icell.x != iend.x + ineg.x) { - icell.x += iadd.x; - dest.x = get_mesh_x(icell.x); - dest.y = ratio * dest.x + c; // Calculate Y at the next X mesh line - - float z0 = z_correction_for_y_on_vertical_mesh_line(dest.y, icell.x, icell.y) - * planner.fade_scaling_factor_for_z(end.z); - - // Undefined parts of the Mesh in z_values[][] are NAN. - // Replace NAN corrections with 0.0 to prevent NAN propagation. - if (isnan(z0)) z0 = 0.0; - - /** - * Without this check, it's possible to generate a zero length move, as in the case where - * the line is heading left, starting exactly on a mesh line boundary. Since this is rare - * it might be fine to remove this check and let planner.buffer_segment() filter it out. - */ - if (dest.x != start.x) { - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; - TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); // Based on X or Y because the move is horizontal - dest.z = start.z + on_axis_distance * z_normalized_dist; - } - else { - TERN_(HAS_EXTRUDERS, dest.e = end.e); - dest.z = end.z; - } - - dest.z += z0; - if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break; - - } - else - DEBUG_ECHOLNPGM("[ubl] skip Y segment"); - } - - if (xy_pos_t(current_position) != xy_pos_t(end)) - goto FINAL_MOVE; - - current_position = destination; - return; - } - - /** - * Generic case of a line crossing both X and Y Mesh lines. - */ - - xy_int8_t cnt = (istart - iend).ABS(); - - icell += ineg; - - while (cnt) { - - const float next_mesh_line_x = get_mesh_x(icell.x + iadd.x), - next_mesh_line_y = get_mesh_y(icell.y + iadd.y); - - dest.y = ratio * next_mesh_line_x + c; // Calculate Y at the next X mesh line - dest.x = (next_mesh_line_y - c) / ratio; // Calculate X at the next Y mesh line - // (No need to worry about ratio == 0. - // In that case, it was already detected - // as a vertical line move above.) - - if (neg.x == (dest.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(dest.x, icell.x - ineg.x, icell.y + iadd.y) - * planner.fade_scaling_factor_for_z(end.z); - - // Undefined parts of the Mesh in z_values[][] are NAN. - // Replace NAN corrections with 0.0 to prevent NAN propagation. - if (isnan(z0)) z0 = 0.0; - - dest.y = next_mesh_line_y; - - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; - TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); - dest.z = start.z + on_axis_distance * z_normalized_dist; - } - else { - TERN_(HAS_EXTRUDERS, dest.e = end.e); - dest.z = end.z; - } - - dest.z += z0; - if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break; - - icell.y += iadd.y; - cnt.y--; - } - else { - // Yes! Crossing a X Mesh Line next - float z0 = z_correction_for_y_on_vertical_mesh_line(dest.y, icell.x + iadd.x, icell.y - ineg.y) - * planner.fade_scaling_factor_for_z(end.z); - - // Undefined parts of the Mesh in z_values[][] are NAN. - // Replace NAN corrections with 0.0 to prevent NAN propagation. - if (isnan(z0)) z0 = 0.0; - - dest.x = next_mesh_line_x; - - if (!inf_normalized_flag) { - on_axis_distance = use_x_dist ? dest.x - start.x : dest.y - start.y; - TERN_(HAS_EXTRUDERS, dest.e = start.e + on_axis_distance * e_normalized_dist); - dest.z = start.z + on_axis_distance * z_normalized_dist; - } - else { - TERN_(HAS_EXTRUDERS, dest.e = end.e); - dest.z = end.z; - } - - dest.z += z0; - if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break; - - icell.x += iadd.x; - cnt.x--; - } - - if (cnt.x < 0 || cnt.y < 0) break; // Too far! Exit the loop and go to FINAL_MOVE - } - - if (xy_pos_t(current_position) != xy_pos_t(end)) - goto FINAL_MOVE; - - current_position = destination; - } - -#else // UBL_SEGMENTED - - #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) - #elif ENABLED(POLARGRAPH) - #define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DELTA_SEGMENTS_PER_SECOND) - #else // CARTESIAN - #ifdef LEVELED_SEGMENT_LENGTH - #define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH - #else - #define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation) - #endif - #endif - - /** - * Prepare a segmented linear move for DELTA/SCARA/CARTESIAN with UBL and FADE semantics. - * This calls planner.buffer_segment multiple times for small incremental moves. - * Returns true if did NOT move, false if moved (requires current_position update). - */ - - bool __O2 unified_bed_leveling::line_to_destination_segmented(const_feedRate_t scaled_fr_mm_s) { - - if (!position_is_reachable(destination)) // fail if moving outside reachable boundary - return true; // did not move, so current_position still accurate - - const xyze_pos_t total = destination - current_position; - - const float cart_xy_mm_2 = HYPOT2(total.x, total.y), - cart_xy_mm = SQRT(cart_xy_mm_2); // Total XY distance - - #if IS_KINEMATIC - const float seconds = cart_xy_mm / scaled_fr_mm_s; // Duration of XY move at requested rate - uint16_t segments = LROUND(segments_per_second * seconds), // Preferred number of segments for distance @ feedrate - seglimit = LROUND(cart_xy_mm * RECIPROCAL(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 = LROUND(cart_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Cartesian fixed segment length - #endif - - NOLESS(segments, 1U); // Must have at least one segment - const float inv_segments = 1.0f / segments; // Reciprocal to save calculation - - // Add hints to help optimize the move - PlannerHints hints(SQRT(cart_xy_mm_2 + sq(total.z)) * inv_segments); // Length of each segment - #if ENABLED(SCARA_FEEDRATE_SCALING) - hints.inv_duration = scaled_fr_mm_s / hints.millimeters; - #endif - - xyze_float_t diff = total * inv_segments; - - // Note that E segment distance could vary slightly as z mesh height - // changes for each segment, but small enough to ignore. - - xyze_pos_t raw = current_position; - - // Just do plain segmentation if UBL is inactive or the target is above the fade height - if (!planner.leveling_active || !planner.leveling_active_at_z(destination.z)) { - while (--segments) { - raw += diff; - planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, hints); - } - planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, hints); - return false; // Did not set current from destination - } - - // Otherwise perform per-segment leveling - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - const float fade_scaling_factor = planner.fade_scaling_factor_for_z(destination.z); - #endif - - // Move to first segment destination - raw += diff; - - 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. - - xy_int8_t icell = { - int8_t((raw.x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST)), - int8_t((raw.y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST)) - }; - LIMIT(icell.x, 0, GRID_MAX_CELLS_X); - LIMIT(icell.y, 0, GRID_MAX_CELLS_Y); - - float z_x0y0 = z_values[icell.x ][icell.y ], // z at lower left corner - z_x1y0 = z_values[icell.x+1][icell.y ], // z at upper left corner - z_x0y1 = z_values[icell.x ][icell.y+1], // z at lower right corner - z_x1y1 = z_values[icell.x+1][icell.y+1]; // z at upper right corner - - if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_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 - - const xy_pos_t pos = { get_mesh_x(icell.x), get_mesh_y(icell.y) }; - xy_pos_t cell = raw - pos; - - const float z_xmy0 = (z_x1y0 - z_x0y0) * RECIPROCAL(MESH_X_DIST), // z slope per x along y0 (lower left to lower right) - z_xmy1 = (z_x1y1 - z_x0y1) * RECIPROCAL(MESH_X_DIST); // z slope per x along y1 (upper left to upper right) - - float z_cxy0 = z_x0y0 + z_xmy0 * cell.x; // z height along y0 at cell.x (changes for each cell.x in cell) - - const float z_cxy1 = z_x0y1 + z_xmy1 * cell.x, // z height along y1 at cell.x - z_cxyd = z_cxy1 - z_cxy0; // z height difference along cell.x from y0 to y1 - - float z_cxym = z_cxyd * RECIPROCAL(MESH_Y_DIST); // z slope per y along cell.x from pos.y to y1 (changes for each cell.x in cell) - - // float z_cxcy = z_cxy0 + z_cxym * cell.y; // interpolated mesh z height along cell.x at cell.y (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 cell.x within the cell, and - // each change by a constant for fixed segment lengths. - - const float z_sxy0 = z_xmy0 * diff.x, // per-segment adjustment to z_cxy0 - z_sxym = (z_xmy1 - z_xmy0) * RECIPROCAL(MESH_Y_DIST) * diff.x; // per-segment adjustment to z_cxym - - for (;;) { // for all segments within this mesh cell - - if (--segments == 0) raw = destination; // if this is last segment, use destination for exact - - const float z_cxcy = (z_cxy0 + z_cxym * cell.y) // interpolated mesh z height along cell.x at cell.y - TERN_(ENABLE_LEVELING_FADE_HEIGHT, * fade_scaling_factor); // apply fade factor to interpolated height - - const float oldz = raw.z; raw.z += z_cxcy; - planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, hints); - raw.z = oldz; - - if (segments == 0) // done with last segment - return false; // didn't set current from destination - - raw += diff; - cell += diff; - - if (!WITHIN(cell.x, 0, MESH_X_DIST) || !WITHIN(cell.y, 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 - - return false; // caller will update current_position - } - -#endif // UBL_SEGMENTED - -#endif // AUTO_BED_LEVELING_UBL diff --git a/src/feature/binary_stream.cpp b/src/feature/binary_stream.cpp deleted file mode 100644 index 81e1103..0000000 --- a/src/feature/binary_stream.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(BINARY_FILE_TRANSFER) - -#include "../sd/cardreader.h" -#include "binary_stream.h" - -char* SDFileTransferProtocol::Packet::Open::data = nullptr; -size_t SDFileTransferProtocol::data_waiting, SDFileTransferProtocol::transfer_timeout, SDFileTransferProtocol::idle_timeout; -bool SDFileTransferProtocol::transfer_active, SDFileTransferProtocol::dummy_transfer, SDFileTransferProtocol::compression; - -BinaryStream binaryStream[NUM_SERIAL]; - -#endif diff --git a/src/feature/binary_stream.h b/src/feature/binary_stream.h deleted file mode 100644 index 417e39c..0000000 --- a/src/feature/binary_stream.h +++ /dev/null @@ -1,456 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#define BINARY_STREAM_COMPRESSION -#if ENABLED(BINARY_STREAM_COMPRESSION) - #include "../libs/heatshrink/heatshrink_decoder.h" - // STM32 (and others?) require a word-aligned buffer for SD card transfers via DMA - static __attribute__((aligned(sizeof(size_t)))) uint8_t decode_buffer[512] = {}; - static heatshrink_decoder hsd; -#endif - -inline bool bs_serial_data_available(const serial_index_t index) { - return SERIAL_IMPL.available(index); -} - -inline int bs_read_serial(const serial_index_t index) { - return SERIAL_IMPL.read(index); -} - -class SDFileTransferProtocol { -private: - struct Packet { - struct [[gnu::packed]] Open { - static bool validate(char *buffer, size_t length) { - return (length > sizeof(Open) && buffer[length - 1] == '\0'); - } - static Open& decode(char *buffer) { - data = &buffer[2]; - return *reinterpret_cast(buffer); - } - bool compression_enabled() { return compression & 0x1; } - bool dummy_transfer() { return dummy & 0x1; } - static char* filename() { return data; } - private: - uint8_t dummy, compression; - static char* data; // variable length strings complicate things - }; - }; - - static bool file_open(char *filename) { - if (!dummy_transfer) { - card.mount(); - card.openFileWrite(filename); - if (!card.isFileOpen()) return false; - } - transfer_active = true; - data_waiting = 0; - TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_reset(&hsd)); - return true; - } - - static bool file_write(char *buffer, const size_t length) { - #if ENABLED(BINARY_STREAM_COMPRESSION) - if (compression) { - size_t total_processed = 0, processed_count = 0; - HSD_poll_res presult; - - while (total_processed < length) { - heatshrink_decoder_sink(&hsd, reinterpret_cast(&buffer[total_processed]), length - total_processed, &processed_count); - total_processed += processed_count; - do { - presult = heatshrink_decoder_poll(&hsd, &decode_buffer[data_waiting], sizeof(decode_buffer) - data_waiting, &processed_count); - data_waiting += processed_count; - if (data_waiting == sizeof(decode_buffer)) { - if (!dummy_transfer) - if (card.write(decode_buffer, data_waiting) < 0) { - return false; - } - data_waiting = 0; - } - } while (presult == HSDR_POLL_MORE); - } - return true; - } - #endif - return (dummy_transfer || card.write(buffer, length) >= 0); - } - - static bool file_close() { - if (!dummy_transfer) { - #if ENABLED(BINARY_STREAM_COMPRESSION) - // flush any buffered data - if (data_waiting) { - if (card.write(decode_buffer, data_waiting) < 0) return false; - data_waiting = 0; - } - #endif - card.closefile(); - card.release(); - } - TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_finish(&hsd)); - transfer_active = false; - return true; - } - - static void transfer_abort() { - if (!dummy_transfer) { - card.closefile(); - card.removeFile(card.filename); - card.release(); - TERN_(BINARY_STREAM_COMPRESSION, heatshrink_decoder_finish(&hsd)); - } - transfer_active = false; - return; - } - - enum class FileTransfer : uint8_t { QUERY, OPEN, CLOSE, WRITE, ABORT }; - - static size_t data_waiting, transfer_timeout, idle_timeout; - static bool transfer_active, dummy_transfer, compression; - -public: - - static void idle() { - // If a transfer is interrupted and a file is left open, abort it after TIMEOUT ms - const millis_t ms = millis(); - if (transfer_active && ELAPSED(ms, idle_timeout)) { - idle_timeout = ms + IDLE_PERIOD; - if (ELAPSED(ms, transfer_timeout)) transfer_abort(); - } - } - - static void process(uint8_t packet_type, char *buffer, const uint16_t length) { - transfer_timeout = millis() + TIMEOUT; - switch (static_cast(packet_type)) { - case FileTransfer::QUERY: - SERIAL_ECHOPGM("PFT:version:", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH); - #if ENABLED(BINARY_STREAM_COMPRESSION) - SERIAL_ECHOLNPGM(":compression:heatshrink,", HEATSHRINK_STATIC_WINDOW_BITS, ",", HEATSHRINK_STATIC_LOOKAHEAD_BITS); - #else - SERIAL_ECHOLNPGM(":compression:none"); - #endif - break; - case FileTransfer::OPEN: - if (transfer_active) - SERIAL_ECHOLNPGM("PFT:busy"); - else { - if (Packet::Open::validate(buffer, length)) { - auto packet = Packet::Open::decode(buffer); - compression = packet.compression_enabled(); - dummy_transfer = packet.dummy_transfer(); - if (file_open(packet.filename())) { - SERIAL_ECHOLNPGM("PFT:success"); - break; - } - } - SERIAL_ECHOLNPGM("PFT:fail"); - } - break; - case FileTransfer::CLOSE: - if (transfer_active) { - if (file_close()) - SERIAL_ECHOLNPGM("PFT:success"); - else - SERIAL_ECHOLNPGM("PFT:ioerror"); - } - else SERIAL_ECHOLNPGM("PFT:invalid"); - break; - case FileTransfer::WRITE: - if (!transfer_active) - SERIAL_ECHOLNPGM("PFT:invalid"); - else if (!file_write(buffer, length)) - SERIAL_ECHOLNPGM("PFT:ioerror"); - break; - case FileTransfer::ABORT: - transfer_abort(); - SERIAL_ECHOLNPGM("PFT:success"); - break; - default: - SERIAL_ECHOLNPGM("PTF:invalid"); - break; - } - } - - static const uint16_t VERSION_MAJOR = 0, VERSION_MINOR = 1, VERSION_PATCH = 0, TIMEOUT = 10000, IDLE_PERIOD = 1000; -}; - -class BinaryStream { -public: - enum class Protocol : uint8_t { CONTROL, FILE_TRANSFER }; - - enum class ProtocolControl : uint8_t { SYNC = 1, CLOSE }; - - enum class StreamState : uint8_t { PACKET_RESET, PACKET_WAIT, PACKET_HEADER, PACKET_DATA, PACKET_FOOTER, - PACKET_PROCESS, PACKET_RESEND, PACKET_TIMEOUT, PACKET_ERROR }; - - struct Packet { // 10 byte protocol overhead, ascii with checksum and line number has a minimum of 7 increasing with line - - union Header { - static constexpr uint16_t HEADER_TOKEN = 0xB5AD; - struct [[gnu::packed]] { - uint16_t token; // packet start token - uint8_t sync; // stream sync, resend id and packet loss detection - uint8_t meta; // 4 bit protocol, - // 4 bit packet type - uint16_t size; // data length - uint16_t checksum; // header checksum - }; - uint8_t protocol() { return (meta >> 4) & 0xF; } - uint8_t type() { return meta & 0xF; } - void reset() { token = 0; sync = 0; meta = 0; size = 0; checksum = 0; } - uint8_t data[2]; - }; - - union Footer { - struct [[gnu::packed]] { - uint16_t checksum; // full packet checksum - }; - void reset() { checksum = 0; } - uint8_t data[1]; - }; - - Header header; - Footer footer; - uint32_t bytes_received; - uint16_t checksum, header_checksum; - millis_t timeout; - char* buffer; - - void reset() { - header.reset(); - footer.reset(); - bytes_received = 0; - checksum = 0; - header_checksum = 0; - timeout = millis() + PACKET_MAX_WAIT; - buffer = nullptr; - } - } packet{}; - - void reset() { - sync = 0; - packet_retries = 0; - buffer_next_index = 0; - } - - // fletchers 16 checksum - uint32_t checksum(uint32_t cs, uint8_t value) { - uint16_t cs_low = (((cs & 0xFF) + value) % 255); - return ((((cs >> 8) + cs_low) % 255) << 8) | cs_low; - } - - // read the next byte from the data stream keeping track of - // whether the stream times out from data starvation - // takes the data variable by reference in order to return status - bool stream_read(uint8_t& data) { - if (stream_state != StreamState::PACKET_WAIT && ELAPSED(millis(), packet.timeout)) { - stream_state = StreamState::PACKET_TIMEOUT; - return false; - } - if (!bs_serial_data_available(card.transfer_port_index)) return false; - data = bs_read_serial(card.transfer_port_index); - packet.timeout = millis() + PACKET_MAX_WAIT; - return true; - } - - template - void receive(char (&buffer)[buffer_size]) { - uint8_t data = 0; - millis_t transfer_window = millis() + RX_TIMESLICE; - - #if ENABLED(SDSUPPORT) - PORT_REDIRECT(SERIAL_PORTMASK(card.transfer_port_index)); - #endif - - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Warray-bounds" - - while (PENDING(millis(), transfer_window)) { - switch (stream_state) { - /** - * Data stream packet handling - */ - case StreamState::PACKET_RESET: - packet.reset(); - stream_state = StreamState::PACKET_WAIT; - case StreamState::PACKET_WAIT: - if (!stream_read(data)) { idle(); return; } // no active packet so don't wait - packet.header.data[1] = data; - if (packet.header.token == packet.header.HEADER_TOKEN) { - packet.bytes_received = 2; - stream_state = StreamState::PACKET_HEADER; - } - else { - // stream corruption drop data - packet.header.data[0] = data; - } - break; - case StreamState::PACKET_HEADER: - if (!stream_read(data)) break; - - packet.header.data[packet.bytes_received++] = data; - packet.checksum = checksum(packet.checksum, data); - - // header checksum calculation can't contain the checksum - if (packet.bytes_received == sizeof(Packet::header) - 2) - packet.header_checksum = packet.checksum; - - if (packet.bytes_received == sizeof(Packet::header)) { - if (packet.header.checksum == packet.header_checksum) { - // The SYNC control packet is a special case in that it doesn't require the stream sync to be correct - if (static_cast(packet.header.protocol()) == Protocol::CONTROL && static_cast(packet.header.type()) == ProtocolControl::SYNC) { - SERIAL_ECHOLNPGM("ss", sync, ",", buffer_size, ",", VERSION_MAJOR, ".", VERSION_MINOR, ".", VERSION_PATCH); - stream_state = StreamState::PACKET_RESET; - break; - } - if (packet.header.sync == sync) { - buffer_next_index = 0; - packet.bytes_received = 0; - if (packet.header.size) { - stream_state = StreamState::PACKET_DATA; - packet.buffer = static_cast(&buffer[0]); // multipacket buffering not implemented, always allocate whole buffer to packet - } - else - stream_state = StreamState::PACKET_PROCESS; - } - else if (packet.header.sync == sync - 1) { // ok response must have been lost - SERIAL_ECHOLNPGM("ok", packet.header.sync); // transmit valid packet received and drop the payload - stream_state = StreamState::PACKET_RESET; - } - else if (packet_retries) { - stream_state = StreamState::PACKET_RESET; // could be packets already buffered on flow controlled connections, drop them without ack - } - else { - SERIAL_ECHO_MSG("Datastream packet out of order"); - stream_state = StreamState::PACKET_RESEND; - } - } - else { - SERIAL_ECHO_MSG("Packet header(", packet.header.sync, "?) corrupt"); - stream_state = StreamState::PACKET_RESEND; - } - } - break; - case StreamState::PACKET_DATA: - if (!stream_read(data)) break; - - if (buffer_next_index < buffer_size) - packet.buffer[buffer_next_index] = data; - else { - SERIAL_ECHO_MSG("Datastream packet data buffer overrun"); - stream_state = StreamState::PACKET_ERROR; - break; - } - - packet.checksum = checksum(packet.checksum, data); - packet.bytes_received++; - buffer_next_index++; - - if (packet.bytes_received == packet.header.size) { - stream_state = StreamState::PACKET_FOOTER; - packet.bytes_received = 0; - } - break; - case StreamState::PACKET_FOOTER: - if (!stream_read(data)) break; - - packet.footer.data[packet.bytes_received++] = data; - if (packet.bytes_received == sizeof(Packet::footer)) { - if (packet.footer.checksum == packet.checksum) { - stream_state = StreamState::PACKET_PROCESS; - } - else { - SERIAL_ECHO_MSG("Packet(", packet.header.sync, ") payload corrupt"); - stream_state = StreamState::PACKET_RESEND; - } - } - break; - case StreamState::PACKET_PROCESS: - sync++; - packet_retries = 0; - bytes_received += packet.header.size; - - SERIAL_ECHOLNPGM("ok", packet.header.sync); // transmit valid packet received - dispatch(); - stream_state = StreamState::PACKET_RESET; - break; - case StreamState::PACKET_RESEND: - if (packet_retries < MAX_RETRIES || MAX_RETRIES == 0) { - packet_retries++; - stream_state = StreamState::PACKET_RESET; - SERIAL_ECHO_MSG("Resend request ", packet_retries); - SERIAL_ECHOLNPGM("rs", sync); - } - else - stream_state = StreamState::PACKET_ERROR; - break; - case StreamState::PACKET_TIMEOUT: - SERIAL_ECHO_MSG("Datastream timeout"); - stream_state = StreamState::PACKET_RESEND; - break; - case StreamState::PACKET_ERROR: - SERIAL_ECHOLNPGM("fe", packet.header.sync); - reset(); // reset everything, resync required - stream_state = StreamState::PACKET_RESET; - break; - } - } - - #pragma GCC diagnostic pop - } - - void dispatch() { - switch (static_cast(packet.header.protocol())) { - case Protocol::CONTROL: - switch (static_cast(packet.header.type())) { - case ProtocolControl::CLOSE: // revert back to ASCII mode - card.flag.binary_mode = false; - break; - default: - SERIAL_ECHO_MSG("Unknown BinaryProtocolControl Packet"); - } - break; - case Protocol::FILE_TRANSFER: - SDFileTransferProtocol::process(packet.header.type(), packet.buffer, packet.header.size); // send user data to be processed - break; - default: - SERIAL_ECHO_MSG("Unsupported Binary Protocol"); - } - } - - void idle() { - // Some Protocols may need periodic updates without new data - SDFileTransferProtocol::idle(); - } - - static const uint16_t PACKET_MAX_WAIT = 500, RX_TIMESLICE = 20, MAX_RETRIES = 0, VERSION_MAJOR = 0, VERSION_MINOR = 1, VERSION_PATCH = 0; - uint8_t packet_retries, sync; - uint16_t buffer_next_index; - uint32_t bytes_received; - StreamState stream_state = StreamState::PACKET_RESET; -}; - -extern BinaryStream binaryStream[NUM_SERIAL]; diff --git a/src/feature/bltouch.cpp b/src/feature/bltouch.cpp deleted file mode 100644 index 10d3131..0000000 --- a/src/feature/bltouch.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(BLTOUCH) - -#include "bltouch.h" - -BLTouch bltouch; - -bool BLTouch::od_5v_mode; // Initialized by settings.load, 0 = Open Drain; 1 = 5V Drain -#ifdef BLTOUCH_HS_MODE - bool BLTouch::high_speed_mode; // Initialized by settings.load, 0 = Low Speed; 1 = High Speed -#else - constexpr bool BLTouch::high_speed_mode; -#endif - -#include "../module/servo.h" -#include "../module/probe.h" - -void stop(); - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../core/debug_out.h" - -bool BLTouch::command(const BLTCommand cmd, const millis_t &ms) { - if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("BLTouch Command :", cmd); - servo[Z_PROBE_SERVO_NR].move(cmd); - safe_delay(_MAX(ms, (uint32_t)BLTOUCH_DELAY)); // BLTOUCH_DELAY is also the *minimum* delay - return triggered(); -} - -// Init the class and device. Call from setup(). -void BLTouch::init(const bool set_voltage/*=false*/) { - // Voltage Setting (if enabled). At every Marlin initialization: - // BLTOUCH < V3.0 and clones: This will be ignored by the probe - // BLTOUCH V3.0: SET_5V_MODE or SET_OD_MODE (if enabled). - // OD_MODE is the default on power on, but setting it does not hurt - // This mode will stay active until manual SET_OD_MODE or power cycle - // BLTOUCH V3.1: SET_5V_MODE or SET_OD_MODE (if enabled). - // At power on, the probe will default to the eeprom settings configured by the user - _reset(); - _stow(); - - #if ENABLED(BLTOUCH_FORCE_MODE_SET) - - constexpr bool should_set = true; - - #else - - #ifdef DEBUG_OUT - if (DEBUGGING(LEVELING)) { - PGMSTR(mode0, "OD"); - PGMSTR(mode1, "5V"); - DEBUG_ECHOPGM("BLTouch Mode: "); - DEBUG_ECHOPGM_P(bltouch.od_5v_mode ? mode1 : mode0); - DEBUG_ECHOLNPGM(" (Default " TERN(BLTOUCH_SET_5V_MODE, "5V", "OD") ")"); - } - #endif - - const bool should_set = od_5v_mode != ENABLED(BLTOUCH_SET_5V_MODE); - - #endif - - if (should_set && set_voltage) - mode_conv_proc(ENABLED(BLTOUCH_SET_5V_MODE)); -} - -void BLTouch::clear() { - _reset(); // RESET or RESET_SW will clear an alarm condition but... - // ...it will not clear a triggered condition in SW mode when the pin is currently up - // ANTClabs <-- CODE ERROR - _stow(); // STOW will pull up the pin and clear any triggered condition unless it fails, don't care - _deploy(); // DEPLOY to test the probe. Could fail, don't care - _stow(); // STOW to be ready for meaningful work. Could fail, don't care -} - -bool BLTouch::triggered() { return PROBE_TRIGGERED(); } - -bool BLTouch::deploy_proc() { - // Do a DEPLOY - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch DEPLOY requested"); - - // Attempt to DEPLOY, wait for DEPLOY_DELAY or ALARM - if (_deploy_query_alarm()) { - // The deploy might have failed or the probe is already triggered (nozzle too low?) - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch ALARM or TRIGGER after DEPLOY, recovering"); - - clear(); // Get the probe into start condition - - // Last attempt to DEPLOY - if (_deploy_query_alarm()) { - // The deploy might have failed or the probe is actually triggered (nozzle too low?) again - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Deploy Failed"); - probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart - return true; // Tell our caller we goofed in case he cares to know - } - } - - // One of the recommended ANTClabs ways to probe, using SW MODE - TERN_(BLTOUCH_FORCE_SW_MODE, _set_SW_mode()); - - // Now the probe is ready to issue a 10ms pulse when the pin goes up. - // The trigger STOW (see motion.cpp for example) will pull up the probes pin as soon as the pulse - // is registered. - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("bltouch.deploy_proc() end"); - - return false; // report success to caller -} - -bool BLTouch::stow_proc() { - // Do a STOW - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch STOW requested"); - - // A STOW will clear a triggered condition in the probe (10ms pulse). - // At the moment that we come in here, we might (pulse) or will (SW mode) see the trigger on the pin. - // So even though we know a STOW will be ignored if an ALARM condition is active, we will STOW. - // Note: If the probe is deployed AND in an ALARM condition, this STOW will not pull up the pin - // and the ALARM condition will still be there. --> ANTClabs should change this behavior maybe - - // Attempt to STOW, wait for STOW_DELAY or ALARM - if (_stow_query_alarm()) { - // The stow might have failed - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch ALARM or TRIGGER after STOW, recovering"); - - _reset(); // This RESET will then also pull up the pin. If it doesn't - // work and the pin is still down, there will no longer be - // an ALARM condition though. - // But one more STOW will catch that - // Last attempt to STOW - if (_stow_query_alarm()) { // so if there is now STILL an ALARM condition: - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Stow Failed"); - probe.probe_error_stop(); // Something is wrong, needs action, but not too bad, allow restart - return true; // Tell our caller we goofed in case he cares to know - } - } - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("bltouch.stow_proc() end"); - - return false; // report success to caller -} - -bool BLTouch::status_proc() { - /** - * Return a TRUE for "YES, it is DEPLOYED" - * This function will ensure switch state is reset after execution - */ - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch STATUS requested"); - - _set_SW_mode(); // Incidentally, _set_SW_mode() will also RESET any active alarm - const bool tr = triggered(); // If triggered in SW mode, the pin is up, it is STOWED - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch is ", tr); - - if (tr) _stow(); else _deploy(); // Turn off SW mode, reset any trigger, honor pin state - return !tr; -} - -void BLTouch::mode_conv_proc(const bool M5V) { - /** - * BLTOUCH pre V3.0 and clones: No reaction at all to this sequence apart from a DEPLOY -> STOW - * BLTOUCH V3.0: This will set the mode (twice) and sadly, a STOW is needed at the end, because of the deploy - * BLTOUCH V3.1: This will set the mode and store it in the eeprom. The STOW is not needed but does not hurt - */ - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("BLTouch Set Mode - ", M5V); - _deploy(); - if (M5V) _set_5V_mode(); else _set_OD_mode(); - _mode_store(); - if (M5V) _set_5V_mode(); else _set_OD_mode(); - _stow(); - od_5v_mode = M5V; -} - -#endif // BLTOUCH diff --git a/src/feature/bltouch.h b/src/feature/bltouch.h deleted file mode 100644 index fa857bb..0000000 --- a/src/feature/bltouch.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -// BLTouch commands are sent as servo angles -typedef unsigned char BLTCommand; - -#define STOW_ALARM true -#define BLTOUCH_DEPLOY 10 -#define BLTOUCH_STOW 90 -#define BLTOUCH_SW_MODE 60 -#define BLTOUCH_SELFTEST 120 -#define BLTOUCH_MODE_STORE 130 -#define BLTOUCH_5V_MODE 140 -#define BLTOUCH_OD_MODE 150 -#define BLTOUCH_RESET 160 - -/** - * The following commands require different minimum delays. - * - * 500ms required for a reliable Reset. - * - * 750ms required for Deploy/Stow, otherwise the alarm state - * will not be seen until the following move command. - */ - -#ifndef BLTOUCH_SET5V_DELAY - #define BLTOUCH_SET5V_DELAY 150 -#endif -#ifndef BLTOUCH_SETOD_DELAY - #define BLTOUCH_SETOD_DELAY 150 -#endif -#ifndef BLTOUCH_MODE_STORE_DELAY - #define BLTOUCH_MODE_STORE_DELAY 150 -#endif -#ifndef BLTOUCH_DEPLOY_DELAY - #define BLTOUCH_DEPLOY_DELAY 750 -#endif -#ifndef BLTOUCH_STOW_DELAY - #define BLTOUCH_STOW_DELAY 750 -#endif -#ifndef BLTOUCH_RESET_DELAY - #define BLTOUCH_RESET_DELAY 500 -#endif - -class BLTouch { -public: - - static void init(const bool set_voltage=false); - static bool od_5v_mode; // Initialized by settings.load, 0 = Open Drain; 1 = 5V Drain - - #ifdef BLTOUCH_HS_MODE - static bool high_speed_mode; // Initialized by settings.load, 0 = Low Speed; 1 = High Speed - #else - static constexpr bool high_speed_mode = false; - #endif - - static float z_extra_clearance() { return high_speed_mode ? 7 : 0; } - - // DEPLOY and STOW are wrapped for error handling - these are used by homing and by probing - static bool deploy() { return deploy_proc(); } - static bool stow() { return stow_proc(); } - static bool status() { return status_proc(); } - - // Native BLTouch commands ("Underscore"...), used in lcd menus and internally - static void _reset() { command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY); } - - static void _selftest() { command(BLTOUCH_SELFTEST, BLTOUCH_DELAY); } - - static void _set_SW_mode() { command(BLTOUCH_SW_MODE, BLTOUCH_DELAY); } - static void _reset_SW_mode() { if (triggered()) _stow(); else _deploy(); } - - static void _set_5V_mode() { command(BLTOUCH_5V_MODE, BLTOUCH_SET5V_DELAY); } - static void _set_OD_mode() { command(BLTOUCH_OD_MODE, BLTOUCH_SETOD_DELAY); } - static void _mode_store() { command(BLTOUCH_MODE_STORE, BLTOUCH_MODE_STORE_DELAY); } - - static void _deploy() { command(BLTOUCH_DEPLOY, BLTOUCH_DEPLOY_DELAY); } - static void _stow() { command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY); } - - static void mode_conv_5V() { mode_conv_proc(true); } - static void mode_conv_OD() { mode_conv_proc(false); } - - static bool triggered(); - -private: - static bool _deploy_query_alarm() { return command(BLTOUCH_DEPLOY, BLTOUCH_DEPLOY_DELAY); } - static bool _stow_query_alarm() { return command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY) == STOW_ALARM; } - - static void clear(); - static bool command(const BLTCommand cmd, const millis_t &ms); - static bool deploy_proc(); - static bool stow_proc(); - static bool status_proc(); - static void mode_conv_proc(const bool M5V); -}; - -extern BLTouch bltouch; diff --git a/src/feature/cancel_object.cpp b/src/feature/cancel_object.cpp deleted file mode 100644 index bffd2bb..0000000 --- a/src/feature/cancel_object.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(CANCEL_OBJECTS) - -#include "cancel_object.h" -#include "../gcode/gcode.h" -#include "../lcd/marlinui.h" - -CancelObject cancelable; - -int8_t CancelObject::object_count, // = 0 - CancelObject::active_object = -1; -uint32_t CancelObject::canceled; // = 0x0000 -bool CancelObject::skipping; // = false - -void CancelObject::set_active_object(const int8_t obj) { - active_object = obj; - if (WITHIN(obj, 0, 31)) { - if (obj >= object_count) object_count = obj + 1; - skipping = TEST(canceled, obj); - } - else - skipping = false; - - #if BOTH(HAS_STATUS_MESSAGE, CANCEL_OBJECTS_REPORTING) - if (active_object >= 0) - ui.status_printf(0, F(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object)); - else - ui.reset_status(); - #endif -} - -void CancelObject::cancel_object(const int8_t obj) { - if (WITHIN(obj, 0, 31)) { - SBI(canceled, obj); - if (obj == active_object) skipping = true; - } -} - -void CancelObject::uncancel_object(const int8_t obj) { - if (WITHIN(obj, 0, 31)) { - CBI(canceled, obj); - if (obj == active_object) skipping = false; - } -} - -void CancelObject::report() { - if (active_object >= 0) - SERIAL_ECHO_MSG("Active Object: ", active_object); - - if (canceled) { - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Canceled:"); - for (int i = 0; i < object_count; i++) - if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); } - SERIAL_EOL(); - } -} - -#endif // CANCEL_OBJECTS diff --git a/src/feature/cancel_object.h b/src/feature/cancel_object.h deleted file mode 100644 index 62548a3..0000000 --- a/src/feature/cancel_object.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include - -class CancelObject { -public: - static bool skipping; - static int8_t object_count, active_object; - static uint32_t canceled; - static void set_active_object(const int8_t obj); - static void cancel_object(const int8_t obj); - static void uncancel_object(const int8_t obj); - static void report(); - static bool is_canceled(const int8_t obj) { return TEST(canceled, obj); } - static void clear_active_object() { set_active_object(-1); } - static void cancel_active_object() { cancel_object(active_object); } - static void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); } -}; - -extern CancelObject cancelable; diff --git a/src/feature/caselight.cpp b/src/feature/caselight.cpp deleted file mode 100644 index eb580a6..0000000 --- a/src/feature/caselight.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(CASE_LIGHT_ENABLE) - -#include "caselight.h" - -CaseLight caselight; - -#if CASELIGHT_USES_BRIGHTNESS && !defined(CASE_LIGHT_DEFAULT_BRIGHTNESS) - #define CASE_LIGHT_DEFAULT_BRIGHTNESS 0 // For use on PWM pin as non-PWM just sets a default -#endif - -#if CASELIGHT_USES_BRIGHTNESS - uint8_t CaseLight::brightness = CASE_LIGHT_DEFAULT_BRIGHTNESS; -#endif - -bool CaseLight::on = CASE_LIGHT_DEFAULT_ON; - -#if CASE_LIGHT_IS_COLOR_LED - constexpr uint8_t init_case_light[] = CASE_LIGHT_DEFAULT_COLOR; - LEDColor CaseLight::color = { init_case_light[0], init_case_light[1], init_case_light[2] OPTARG(HAS_WHITE_LED, init_case_light[3]) }; -#endif - -void CaseLight::update(const bool sflag) { - #if CASELIGHT_USES_BRIGHTNESS - /** - * The brightness_sav (and sflag) is needed because ARM chips ignore - * a "WRITE(CASE_LIGHT_PIN,x)" command to the pins that are directly - * controlled by the PWM module. In order to turn them off the brightness - * level needs to be set to OFF. Since we can't use the PWM register to - * save the last brightness level we need a variable to save it. - */ - static uint8_t brightness_sav; // Save brightness info for restore on "M355 S1" - - if (on || !sflag) - brightness_sav = brightness; // Save brightness except for M355 S0 - if (sflag && on) - brightness = brightness_sav; // Restore last brightness for M355 S1 - - const uint8_t i = on ? brightness : 0, n10ct = ENABLED(INVERT_CASE_LIGHT) ? 255 - i : i; - UNUSED(n10ct); - #endif - - #if CASE_LIGHT_IS_COLOR_LED - #if ENABLED(CASE_LIGHT_USE_NEOPIXEL) - if (on) - // Use current color of (NeoPixel) leds and new brightness level - leds.set_color(LEDColor(leds.color.r, leds.color.g, leds.color.b OPTARG(HAS_WHITE_LED, leds.color.w) OPTARG(NEOPIXEL_LED, n10ct))); - else - // Switch off leds - leds.set_off(); - #else - // Use CaseLight color (CASE_LIGHT_DEFAULT_COLOR) and new brightness level - leds.set_color(LEDColor(color.r, color.g, color.b OPTARG(HAS_WHITE_LED, color.w) OPTARG(NEOPIXEL_LED, n10ct))); - #endif - #else // !CASE_LIGHT_IS_COLOR_LED - - #if CASELIGHT_USES_BRIGHTNESS - if (pin_is_pwm()) - hal.set_pwm_duty(pin_t(CASE_LIGHT_PIN), ( - #if CASE_LIGHT_MAX_PWM == 255 - n10ct - #else - map(n10ct, 0, 255, 0, CASE_LIGHT_MAX_PWM) - #endif - )); - else - #endif - { - const bool s = on ? TERN(INVERT_CASE_LIGHT, LOW, HIGH) : TERN(INVERT_CASE_LIGHT, HIGH, LOW); - WRITE(CASE_LIGHT_PIN, s ? HIGH : LOW); - } - - #endif // !CASE_LIGHT_IS_COLOR_LED - - #if ENABLED(CASE_LIGHT_USE_RGB_LED) - if (leds.lights_on) leds.update(); else leds.set_off(); - #endif -} - -#endif // CASE_LIGHT_ENABLE diff --git a/src/feature/caselight.h b/src/feature/caselight.h deleted file mode 100644 index 17e1222..0000000 --- a/src/feature/caselight.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#if CASE_LIGHT_IS_COLOR_LED - #include "leds/leds.h" // for LEDColor -#endif - -class CaseLight { -public: - static bool on; - #if ENABLED(CASELIGHT_USES_BRIGHTNESS) - static uint8_t brightness; - #endif - - static bool pin_is_pwm() { return TERN0(NEED_CASE_LIGHT_PIN, PWM_PIN(CASE_LIGHT_PIN)); } - static bool has_brightness() { return TERN0(CASELIGHT_USES_BRIGHTNESS, TERN(CASE_LIGHT_USE_NEOPIXEL, true, pin_is_pwm())); } - - static void init() { - #if NEED_CASE_LIGHT_PIN - if (pin_is_pwm()) SET_PWM(CASE_LIGHT_PIN); else SET_OUTPUT(CASE_LIGHT_PIN); - #endif - update_brightness(); - } - - static void update(const bool sflag); - static void update_brightness() { update(false); } - static void update_enabled() { update(true); } - - #if ENABLED(CASE_LIGHT_IS_COLOR_LED) - private: - static LEDColor color; - #endif -}; - -extern CaseLight caselight; diff --git a/src/feature/closedloop.cpp b/src/feature/closedloop.cpp deleted file mode 100644 index 1b9f711..0000000 --- a/src/feature/closedloop.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - -#if !PIN_EXISTS(CLOSED_LOOP_ENABLE) || !PIN_EXISTS(CLOSED_LOOP_MOVE_COMPLETE) - #error "CLOSED_LOOP_ENABLE_PIN and CLOSED_LOOP_MOVE_COMPLETE_PIN are required for EXTERNAL_CLOSED_LOOP_CONTROLLER." -#endif - -#include "closedloop.h" - -ClosedLoop closedloop; - -void ClosedLoop::init() { - OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, LOW); - SET_INPUT_PULLUP(CLOSED_LOOP_MOVE_COMPLETE_PIN); -} - -void ClosedLoop::set(const byte val) { - OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, val); -} - -#endif // EXTERNAL_CLOSED_LOOP_CONTROLLER diff --git a/src/feature/closedloop.h b/src/feature/closedloop.h deleted file mode 100644 index e03400c..0000000 --- a/src/feature/closedloop.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -class ClosedLoop { -public: - static void init(); - static void set(const byte val); -}; - -extern ClosedLoop closedloop; - -#define CLOSED_LOOP_WAITING() (READ(CLOSED_LOOP_ENABLE_PIN) && !READ(CLOSED_LOOP_MOVE_COMPLETE_PIN)) diff --git a/src/feature/controllerfan.cpp b/src/feature/controllerfan.cpp deleted file mode 100644 index f42bf52..0000000 --- a/src/feature/controllerfan.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(USE_CONTROLLER_FAN) - -#include "controllerfan.h" -#include "../module/stepper.h" -#include "../module/temperature.h" - -ControllerFan controllerFan; - -uint8_t ControllerFan::speed; - -#if ENABLED(CONTROLLER_FAN_EDITABLE) - controllerFan_settings_t ControllerFan::settings; // {0} - #else - const controllerFan_settings_t &ControllerFan::settings = controllerFan_defaults; -#endif - -void ControllerFan::setup() { - SET_OUTPUT(CONTROLLER_FAN_PIN); - init(); -} - -void ControllerFan::set_fan_speed(const uint8_t s) { - speed = s < (CONTROLLERFAN_SPEED_MIN) ? 0 : s; // Fan OFF below minimum -} - -void ControllerFan::update() { - static millis_t lastMotorOn = 0, // Last time a motor was turned on - nextMotorCheck = 0; // Last time the state was checked - const millis_t ms = millis(); - if (ELAPSED(ms, nextMotorCheck)) { - nextMotorCheck = ms + 2500UL; // Not a time critical function, so only check every 2.5s - - // If any triggers for the controller fan are true... - // - At least one stepper driver is enabled - // - The heated bed is enabled - // - TEMP_SENSOR_BOARD is reporting >= CONTROLLER_FAN_MIN_BOARD_TEMP - const ena_mask_t axis_mask = TERN(CONTROLLER_FAN_USE_Z_ONLY, _BV(Z_AXIS), (ena_mask_t)~TERN0(CONTROLLER_FAN_IGNORE_Z, _BV(Z_AXIS))); - if ( (stepper.axis_enabled.bits & axis_mask) - || TERN0(HAS_HEATED_BED, thermalManager.temp_bed.soft_pwm_amount > 0) - || TERN0(HAS_CONTROLLER_FAN_MIN_BOARD_TEMP, thermalManager.wholeDegBoard() >= CONTROLLER_FAN_MIN_BOARD_TEMP) - ) lastMotorOn = ms; //... set time to NOW so the fan will turn on - - // Fan Settings. Set fan > 0: - // - If AutoMode is on and steppers have been enabled for CONTROLLERFAN_IDLE_TIME seconds. - // - If System is on idle and idle fan speed settings is activated. - set_fan_speed( - settings.auto_mode && lastMotorOn && PENDING(ms, lastMotorOn + SEC_TO_MS(settings.duration)) - ? settings.active_speed : settings.idle_speed - ); - - #if ENABLED(FAN_SOFT_PWM) - thermalManager.soft_pwm_controller_speed = speed; - #else - if (PWM_PIN(CONTROLLER_FAN_PIN)) - hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed); - else - WRITE(CONTROLLER_FAN_PIN, speed > 0); - #endif - } -} - -#endif // USE_CONTROLLER_FAN diff --git a/src/feature/controllerfan.h b/src/feature/controllerfan.h deleted file mode 100644 index 55eb235..0000000 --- a/src/feature/controllerfan.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -typedef struct { - uint8_t active_speed, // 0-255 (fullspeed); Speed with enabled stepper motors - idle_speed; // 0-255 (fullspeed); Speed after idle period with all motors are disabled - uint16_t duration; // Duration in seconds for the fan to run after all motors are disabled - bool auto_mode; // Default true -} controllerFan_settings_t; - -#ifndef CONTROLLERFAN_SPEED_ACTIVE - #define CONTROLLERFAN_SPEED_ACTIVE 255 -#endif -#ifndef CONTROLLERFAN_SPEED_IDLE - #define CONTROLLERFAN_SPEED_IDLE 0 -#endif -#ifndef CONTROLLERFAN_IDLE_TIME - #define CONTROLLERFAN_IDLE_TIME 60 -#endif - -static constexpr controllerFan_settings_t controllerFan_defaults = { - CONTROLLERFAN_SPEED_ACTIVE, - CONTROLLERFAN_SPEED_IDLE, - CONTROLLERFAN_IDLE_TIME, - true -}; - -#if ENABLED(USE_CONTROLLER_FAN) - -class ControllerFan { - private: - static uint8_t speed; - static void set_fan_speed(const uint8_t s); - - public: - #if ENABLED(CONTROLLER_FAN_EDITABLE) - static controllerFan_settings_t settings; - #else - static const controllerFan_settings_t &settings; - #endif - static bool state() { return speed > 0; } - static void init() { reset(); } - static void reset() { TERN_(CONTROLLER_FAN_EDITABLE, settings = controllerFan_defaults); } - static void setup(); - static void update(); -}; - -extern ControllerFan controllerFan; - -#endif diff --git a/src/feature/cooler.cpp b/src/feature/cooler.cpp deleted file mode 100644 index e0f9977..0000000 --- a/src/feature/cooler.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if EITHER(HAS_COOLER, LASER_COOLANT_FLOW_METER) - -#include "cooler.h" -Cooler cooler; - -#if HAS_COOLER - uint8_t Cooler::mode = 0; - uint16_t Cooler::capacity; - uint16_t Cooler::load; - bool Cooler::enabled = false; -#endif - -#if ENABLED(LASER_COOLANT_FLOW_METER) - bool Cooler::flowmeter = false; - millis_t Cooler::flowmeter_next_ms; // = 0 - volatile uint16_t Cooler::flowpulses; - float Cooler::flowrate; - #if ENABLED(FLOWMETER_SAFETY) - bool Cooler::flowsafety_enabled = true; - bool Cooler::flowfault = false; - #endif -#endif - -#endif // HAS_COOLER || LASER_COOLANT_FLOW_METER diff --git a/src/feature/cooler.h b/src/feature/cooler.h deleted file mode 100644 index 9891514..0000000 --- a/src/feature/cooler.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -#ifndef FLOWMETER_PPL - #define FLOWMETER_PPL 5880 // Pulses per liter -#endif -#ifndef FLOWMETER_INTERVAL - #define FLOWMETER_INTERVAL 1000 // milliseconds -#endif - -// Cooling device - -class Cooler { -public: - static uint16_t capacity; // Cooling capacity in watts - static uint16_t load; // Cooling load in watts - - static bool enabled; - static void enable() { enabled = true; } - static void disable() { enabled = false; } - static void toggle() { enabled = !enabled; } - - static uint8_t mode; // 0 = CO2 Liquid cooling, 1 = Laser Diode TEC Heatsink Cooling - static void set_mode(const uint8_t m) { mode = m; } - - #if ENABLED(LASER_COOLANT_FLOW_METER) - static float flowrate; // Flow meter reading in liters-per-minute. - static bool flowmeter; // Flag to monitor the flow - static volatile uint16_t flowpulses; // Flowmeter IRQ pulse count - static millis_t flowmeter_next_ms; // Next time at which to calculate flow - - static void set_flowmeter(const bool sflag) { - if (flowmeter != sflag) { - flowmeter = sflag; - if (sflag) { - flowpulses = 0; - flowmeter_next_ms = millis() + FLOWMETER_INTERVAL; - } - } - } - - // To calculate flow we only need to count pulses - static void flowmeter_ISR() { flowpulses++; } - - // Enable / Disable the flow meter interrupt - static void flowmeter_interrupt_enable() { - attachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN), flowmeter_ISR, RISING); - } - static void flowmeter_interrupt_disable() { - detachInterrupt(digitalPinToInterrupt(FLOWMETER_PIN)); - } - - // Enable / Disable the flow meter interrupt - static void flowmeter_enable() { set_flowmeter(true); flowpulses = 0; flowmeter_interrupt_enable(); } - static void flowmeter_disable() { set_flowmeter(false); flowmeter_interrupt_disable(); flowpulses = 0; } - - // Get the total flow (in liters per minute) since the last reading - static void calc_flowrate() { - // flowrate = (litres) * (seconds) = litres per minute - flowrate = (flowpulses / (float)FLOWMETER_PPL) * ((1000.0f / (float)FLOWMETER_INTERVAL) * 60.0f); - flowpulses = 0; - } - - // Userland task to update the flow meter - static void flowmeter_task(const millis_t ms=millis()) { - if (!flowmeter) // !! The flow meter must always be on !! - flowmeter_enable(); // Init and prime - if (ELAPSED(ms, flowmeter_next_ms)) { - calc_flowrate(); - flowmeter_next_ms = ms + FLOWMETER_INTERVAL; - } - } - - #if ENABLED(FLOWMETER_SAFETY) - static bool flowfault; // Flag that the cooler is in a fault state - static bool flowsafety_enabled; // Flag to disable the cutter if flow rate is too low - static void flowsafety_toggle() { flowsafety_enabled = !flowsafety_enabled; } - static bool check_flow_too_low() { - const bool too_low = flowsafety_enabled && flowrate < (FLOWMETER_MIN_LITERS_PER_MINUTE); - flowfault = too_low; - return too_low; - } - #endif - #endif -}; - -extern Cooler cooler; diff --git a/src/feature/dac/dac_dac084s085.cpp b/src/feature/dac/dac_dac084s085.cpp deleted file mode 100644 index 772bb68..0000000 --- a/src/feature/dac/dac_dac084s085.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************** - * - * External DAC for Alligator Board - * - ****************************************************************/ - -#include "../../inc/MarlinConfig.h" - -#if MB(ALLIGATOR) - -#include "dac_dac084s085.h" - -#include "../../MarlinCore.h" -#include "../../HAL/shared/Delay.h" - -dac084s085::dac084s085() { } - -void dac084s085::begin() { - uint8_t externalDac_buf[] = { 0x20, 0x00 }; // all off - - // All SPI chip-select HIGH - SET_OUTPUT(DAC0_SYNC_PIN); - #if HAS_MULTI_EXTRUDER - SET_OUTPUT(DAC1_SYNC_PIN); - #endif - cshigh(); - spiBegin(); - - //init onboard DAC - DELAY_US(2); - WRITE(DAC0_SYNC_PIN, LOW); - DELAY_US(2); - WRITE(DAC0_SYNC_PIN, HIGH); - DELAY_US(2); - WRITE(DAC0_SYNC_PIN, LOW); - - spiSend(SPI_CHAN_DAC, externalDac_buf, COUNT(externalDac_buf)); - WRITE(DAC0_SYNC_PIN, HIGH); - - #if HAS_MULTI_EXTRUDER - //init Piggy DAC - DELAY_US(2); - WRITE(DAC1_SYNC_PIN, LOW); - DELAY_US(2); - WRITE(DAC1_SYNC_PIN, HIGH); - DELAY_US(2); - WRITE(DAC1_SYNC_PIN, LOW); - - spiSend(SPI_CHAN_DAC, externalDac_buf, COUNT(externalDac_buf)); - WRITE(DAC1_SYNC_PIN, HIGH); - #endif - - return; -} - -void dac084s085::setValue(const uint8_t channel, const uint8_t value) { - if (channel >= 7) return; // max channel (X,Y,Z,E0,E1,E2,E3) - - const uint8_t externalDac_buf[] = { - 0x10 | ((channel > 3 ? 7 : 3) - channel << 6) | (value >> 4), - 0x00 | (value << 4) - }; - - // All SPI chip-select HIGH - cshigh(); - - if (channel > 3) { // DAC Piggy E1,E2,E3 - WRITE(DAC1_SYNC_PIN, LOW); - DELAY_US(2); - WRITE(DAC1_SYNC_PIN, HIGH); - DELAY_US(2); - WRITE(DAC1_SYNC_PIN, LOW); - } - else { // DAC onboard X,Y,Z,E0 - WRITE(DAC0_SYNC_PIN, LOW); - DELAY_US(2); - WRITE(DAC0_SYNC_PIN, HIGH); - DELAY_US(2); - WRITE(DAC0_SYNC_PIN, LOW); - } - - DELAY_US(2); - spiSend(SPI_CHAN_DAC, externalDac_buf, COUNT(externalDac_buf)); -} - -void dac084s085::cshigh() { - WRITE(DAC0_SYNC_PIN, HIGH); - #if HAS_MULTI_EXTRUDER - WRITE(DAC1_SYNC_PIN, HIGH); - #endif - WRITE(SPI_EEPROM1_CS_PIN, HIGH); - WRITE(SPI_EEPROM2_CS_PIN, HIGH); - WRITE(SPI_FLASH_CS_PIN, HIGH); - WRITE(SD_SS_PIN, HIGH); -} - -#endif // MB(ALLIGATOR) diff --git a/src/feature/dac/dac_dac084s085.h b/src/feature/dac/dac_dac084s085.h deleted file mode 100644 index 5be0129..0000000 --- a/src/feature/dac/dac_dac084s085.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -class dac084s085 { - public: - dac084s085(); - static void begin(); - static void setValue(const uint8_t channel, const uint8_t value); - private: - static void cshigh(); -}; diff --git a/src/feature/dac/dac_mcp4728.cpp b/src/feature/dac/dac_mcp4728.cpp deleted file mode 100644 index 6f5a9ee..0000000 --- a/src/feature/dac/dac_mcp4728.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * mcp4728.cpp - Arduino library for MicroChip MCP4728 I2C D/A converter - * - * For implementation details, please take a look at the datasheet: - * https://ww1.microchip.com/downloads/en/DeviceDoc/22187a.pdf - * - * For discussion and feedback, please go to: - * https://forum.arduino.cc/index.php/topic,51842.0.html - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_MOTOR_CURRENT_DAC - -#include "dac_mcp4728.h" - -MCP4728 mcp4728; - -xyze_uint_t dac_values; - -/** - * Begin I2C, get current values (input register and eeprom) of mcp4728 - */ -void MCP4728::init() { - Wire.begin(); - Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24)); - while (Wire.available()) { - char deviceID = Wire.read(), - hiByte = Wire.read(), - loByte = Wire.read(); - - if (!(deviceID & 0x08)) - dac_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(const uint8_t channel, const uint16_t value) { - dac_values[channel] = value; - return fastWrite(); -} - -/** - * Write all input resistor values to EEPROM using SequentialWrite 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(I2C_ADDRESS(DAC_DEV_ADDRESS)); - Wire.write(SEQWRITE); - LOOP_LOGICAL_AXES(i) { - Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(dac_values[i])); - Wire.write(lowByte(dac_values[i])); - } - return Wire.endTransmission(); -} - -/** - * Write Voltage reference setting to all input registers - */ -uint8_t MCP4728::setVref_all(const uint8_t value) { - Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); - Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); - return Wire.endTransmission(); -} -/** - * Write Gain setting to all input registers - */ -uint8_t MCP4728::setGain_all(const uint8_t value) { - Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); - Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); - return Wire.endTransmission(); -} - -/** - * Return Input Register value - */ -uint16_t MCP4728::getValue(const uint8_t channel) { return dac_values[channel]; } - -#if 0 -/** - * Steph: Might be useful in the future - * Return Vout - */ -uint16_t MCP4728::getVout(const uint8_t channel) { - const uint32_t vref = 2048, - vOut = (vref * dac_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; - return _MIN(vOut, defaultVDD); -} -#endif - -/** - * Returns DAC values as a 0-100 percentage of drive strength - */ -uint8_t MCP4728::getDrvPct(const uint8_t channel) { return uint8_t(100.0 * dac_values[channel] / (DAC_STEPPER_MAX) + 0.5); } - -/** - * Receives all Drive strengths as 0-100 percent values, updates - * DAC Values array and calls fastwrite to update the DAC. - */ -void MCP4728::setDrvPct(xyze_uint_t &pct) { - dac_values = pct * (DAC_STEPPER_MAX) * 0.01f; - fastWrite(); -} - -/** - * FastWrite input register values - All DAC output update. refer to DATASHEET 5.6.1 - * DAC Input and PowerDown bits update. - * No EEPROM update - */ -uint8_t MCP4728::fastWrite() { - Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); - LOOP_LOGICAL_AXES(i) { - Wire.write(highByte(dac_values[i])); - Wire.write(lowByte(dac_values[i])); - } - return Wire.endTransmission(); -} - -/** - * Common function for simple general commands - */ -uint8_t MCP4728::simpleCommand(const byte simpleCommand) { - Wire.beginTransmission(I2C_ADDRESS(GENERALCALL)); - Wire.write(simpleCommand); - return Wire.endTransmission(); -} - -#endif // HAS_MOTOR_CURRENT_DAC diff --git a/src/feature/dac/dac_mcp4728.h b/src/feature/dac/dac_mcp4728.h deleted file mode 100644 index 3a7d5f1..0000000 --- a/src/feature/dac/dac_mcp4728.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Arduino library for MicroChip MCP4728 I2C D/A converter. - */ - -#include "../../core/types.h" - -#include - -/** - * The following three macros are only used in this piece of code related to mcp4728. - * They are defined in the standard Arduino framework but could be undefined in 32 bits Arduino frameworks. - * (For instance not defined in Arduino lpc176x framework) - * So we have to define them if needed. - */ -#ifndef word - #define word(h, l) ((uint8_t) ((h << 8) | l)) -#endif - -#ifndef lowByte - #define lowByte(w) ((uint8_t) ((w) & 0xFF)) -#endif - -#ifndef highByte - #define highByte(w) ((uint8_t) ((w) >> 8)) -#endif - -#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) - -class MCP4728 { -public: - static void init(); - static uint8_t analogWrite(const uint8_t channel, const uint16_t value); - static uint8_t eepromWrite(); - static uint8_t setVref_all(const uint8_t value); - static uint8_t setGain_all(const uint8_t value); - static uint16_t getValue(const uint8_t channel); - static uint8_t fastWrite(); - static uint8_t simpleCommand(const byte simpleCommand); - static uint8_t getDrvPct(const uint8_t channel); - static void setDrvPct(xyze_uint_t &pct); -}; - -extern MCP4728 mcp4728; diff --git a/src/feature/dac/stepper_dac.cpp b/src/feature/dac/stepper_dac.cpp deleted file mode 100644 index f5664bc..0000000 --- a/src/feature/dac/stepper_dac.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * stepper_dac.cpp - To set stepper current via DAC - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_MOTOR_CURRENT_DAC - -#include "stepper_dac.h" - -bool dac_present = false; -constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER; -xyze_uint_t dac_channel_pct = DAC_MOTOR_CURRENT_DEFAULT; - -StepperDAC stepper_dac; - -int StepperDAC::init() { - #if PIN_EXISTS(DAC_DISABLE) - OUT_WRITE(DAC_DISABLE_PIN, LOW); // set pin low to enable DAC - #endif - - mcp4728.init(); - - 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 StepperDAC::set_current_value(const uint8_t channel, uint16_t val) { - if (!(dac_present && channel < LOGICAL_AXES)) return; - - NOMORE(val, uint16_t(DAC_STEPPER_MAX)); - - mcp4728.analogWrite(dac_order[channel], val); - mcp4728.simpleCommand(UPDATE); -} - -void StepperDAC::set_current_percent(const uint8_t channel, float val) { - set_current_value(channel, _MIN(val, 100.0f) * (DAC_STEPPER_MAX) / 100.0f); -} - -static float dac_perc(int8_t n) { return mcp4728.getDrvPct(dac_order[n]); } -static float dac_amps(int8_t n) { return mcp4728.getValue(dac_order[n]) * 0.125 * RECIPROCAL(DAC_STEPPER_SENSE * 1000); } - -uint8_t StepperDAC::get_current_percent(const AxisEnum axis) { return mcp4728.getDrvPct(dac_order[axis]); } -void StepperDAC::set_current_percents(xyze_uint8_t &pct) { - LOOP_LOGICAL_AXES(i) dac_channel_pct[i] = pct[dac_order[i]]; - mcp4728.setDrvPct(dac_channel_pct); -} - -void StepperDAC::print_values() { - if (!dac_present) return; - SERIAL_ECHO_MSG("Stepper current values in % (Amps):"); - SERIAL_ECHO_START(); - LOOP_LOGICAL_AXES(a) { - SERIAL_CHAR(' ', IAXIS_CHAR(a), ':'); - SERIAL_ECHO(dac_perc(a)); - SERIAL_ECHOPGM_P(PSTR(" ("), dac_amps(AxisEnum(a)), PSTR(")")); - } - #if HAS_EXTRUDERS - SERIAL_ECHOLNPGM_P(SP_E_LBL, dac_perc(E_AXIS), PSTR(" ("), dac_amps(E_AXIS), PSTR(")")); - #endif -} - -void StepperDAC::commit_eeprom() { - if (!dac_present) return; - mcp4728.eepromWrite(); -} - -#endif // HAS_MOTOR_CURRENT_DAC diff --git a/src/feature/dac/stepper_dac.h b/src/feature/dac/stepper_dac.h deleted file mode 100644 index 26a0f2f..0000000 --- a/src/feature/dac/stepper_dac.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * stepper_dac.h - To set stepper current via DAC - */ - -#include "dac_mcp4728.h" - -class StepperDAC { -public: - static int init(); - static void set_current_percent(const uint8_t channel, float val); - static void set_current_value(const uint8_t channel, uint16_t val); - static void print_values(); - static void commit_eeprom(); - static uint8_t get_current_percent(const AxisEnum axis); - static void set_current_percents(xyze_uint8_t &pct); -}; - -extern StepperDAC stepper_dac; diff --git a/src/feature/digipot/digipot.h b/src/feature/digipot/digipot.h deleted file mode 100644 index 3fbd1f3..0000000 --- a/src/feature/digipot/digipot.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -// -// Header for MCP4018 and MCP4451 current control i2c devices -// -class DigipotI2C { -public: - static void init(); - static void set_current(const uint8_t channel, const float current); -}; - -extern DigipotI2C digipot_i2c; diff --git a/src/feature/digipot/digipot_mcp4018.cpp b/src/feature/digipot/digipot_mcp4018.cpp deleted file mode 100644 index 3f2ecbf..0000000 --- a/src/feature/digipot/digipot_mcp4018.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DIGIPOT_MCP4018) - -#include "digipot.h" - -#include -#include // https://github.com/felias-fogg/SlowSoftI2CMaster - -// Settings for the I2C based DIGIPOT (MCP4018) based on WT150 - -#ifndef DIGIPOT_A4988_Rsx - #define DIGIPOT_A4988_Rsx 0.250 -#endif -#ifndef DIGIPOT_A4988_Vrefmax - #define DIGIPOT_A4988_Vrefmax 1.666 -#endif -#define DIGIPOT_MCP4018_MAX_VALUE 127 - -#define DIGIPOT_A4988_Itripmax(Vref) ((Vref) / (8.0 * DIGIPOT_A4988_Rsx)) - -#define DIGIPOT_A4988_FACTOR ((DIGIPOT_MCP4018_MAX_VALUE) / DIGIPOT_A4988_Itripmax(DIGIPOT_A4988_Vrefmax)) -#define DIGIPOT_A4988_MAX_CURRENT 2.0 - -static byte current_to_wiper(const float current) { - const int16_t value = TERN(DIGIPOT_USE_RAW_VALUES, current, CEIL(current * DIGIPOT_A4988_FACTOR)); - return byte(constrain(value, 0, DIGIPOT_MCP4018_MAX_VALUE)); -} - -static SlowSoftI2CMaster pots[DIGIPOT_I2C_NUM_CHANNELS] = { - SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_X, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 1 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_Y, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 2 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_Z, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 3 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E0, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 4 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E1, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 5 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E2, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 6 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E3, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #if DIGIPOT_I2C_NUM_CHANNELS > 7 - , SlowSoftI2CMaster(DIGIPOTS_I2C_SDA_E4, DIGIPOTS_I2C_SCL, ENABLED(DIGIPOT_ENABLE_I2C_PULLUPS)) - #endif - #endif - #endif - #endif - #endif - #endif - #endif -}; - -static void digipot_i2c_send(const uint8_t channel, const byte v) { - if (WITHIN(channel, 0, DIGIPOT_I2C_NUM_CHANNELS - 1)) { - pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS_A) << 1) | I2C_WRITE); - pots[channel].i2c_write(v); - pots[channel].i2c_stop(); - } -} - -// This is for the MCP4018 I2C based digipot -void DigipotI2C::set_current(const uint8_t channel, const float current) { - const float ival = _MIN(_MAX(current, 0), float(DIGIPOT_MCP4018_MAX_VALUE)); - digipot_i2c_send(channel, current_to_wiper(ival)); -} - -void DigipotI2C::init() { - LOOP_L_N(i, DIGIPOT_I2C_NUM_CHANNELS) pots[i].i2c_init(); - - // Init currents according to Configuration_adv.h - static const float digipot_motor_current[] PROGMEM = - #if ENABLED(DIGIPOT_USE_RAW_VALUES) - DIGIPOT_MOTOR_CURRENT - #else - DIGIPOT_I2C_MOTOR_CURRENTS - #endif - ; - LOOP_L_N(i, COUNT(digipot_motor_current)) - set_current(i, pgm_read_float(&digipot_motor_current[i])); -} - -DigipotI2C digipot_i2c; - -#endif // DIGIPOT_MCP4018 diff --git a/src/feature/digipot/digipot_mcp4451.cpp b/src/feature/digipot/digipot_mcp4451.cpp deleted file mode 100644 index ba5ecda..0000000 --- a/src/feature/digipot/digipot_mcp4451.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DIGIPOT_MCP4451) - -#include "digipot.h" - -#include -#include - -#if MB(MKS_SBASE) - #include "digipot_mcp4451_I2C_routines.h" -#endif - -// Settings for the I2C based DIGIPOT (MCP4451) on Azteeg X3 Pro -#if MB(5DPRINT) - #define DIGIPOT_I2C_FACTOR 117.96f - #define DIGIPOT_I2C_MAX_CURRENT 1.736f -#elif MB(AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI) - #define DIGIPOT_I2C_FACTOR 113.5f - #define DIGIPOT_I2C_MAX_CURRENT 2.0f -#elif MB(AZTEEG_X5_GT) - #define DIGIPOT_I2C_FACTOR 51.0f - #define DIGIPOT_I2C_MAX_CURRENT 3.0f -#else - #define DIGIPOT_I2C_FACTOR 106.7f - #define DIGIPOT_I2C_MAX_CURRENT 2.5f -#endif - -static byte current_to_wiper(const float current) { - return byte(TERN(DIGIPOT_USE_RAW_VALUES, current, CEIL(DIGIPOT_I2C_FACTOR * current))); -} - -static void digipot_i2c_send(const byte addr, const byte a, const byte b) { - #if MB(MKS_SBASE) - digipot_mcp4451_start(addr); - digipot_mcp4451_send_byte(a); - digipot_mcp4451_send_byte(b); - #else - Wire.beginTransmission(I2C_ADDRESS(addr)); - Wire.write(a); - Wire.write(b); - Wire.endTransmission(); - #endif -} - -// This is for the MCP4451 I2C based digipot -void DigipotI2C::set_current(const uint8_t channel, const float current) { - // These addresses are specific to Azteeg X3 Pro, can be set to others. - // In this case first digipot is at address A0=0, A1=0, second one is at A0=0, A1=1 - const byte addr = channel < 4 ? DIGIPOT_I2C_ADDRESS_A : DIGIPOT_I2C_ADDRESS_B; // channel 0-3 vs 4-7 - - // Initial setup - digipot_i2c_send(addr, 0x40, 0xFF); - digipot_i2c_send(addr, 0xA0, 0xFF); - - // Set actual wiper value - byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 }; - digipot_i2c_send(addr, addresses[channel & 0x3], current_to_wiper(_MIN(float(_MAX(current, 0)), DIGIPOT_I2C_MAX_CURRENT))); -} - -void DigipotI2C::init() { - #if MB(MKS_SBASE) - configure_i2c(16); // Set clock_option to 16 ensure I2C is initialized at 400kHz - #else - Wire.begin(); - #endif - // Set up initial currents as defined in Configuration_adv.h - static const float digipot_motor_current[] PROGMEM = - #if ENABLED(DIGIPOT_USE_RAW_VALUES) - DIGIPOT_MOTOR_CURRENT - #else - DIGIPOT_I2C_MOTOR_CURRENTS - #endif - ; - LOOP_L_N(i, COUNT(digipot_motor_current)) - set_current(i, pgm_read_float(&digipot_motor_current[i])); -} - -DigipotI2C digipot_i2c; - -#endif // DIGIPOT_MCP4451 diff --git a/src/feature/direct_stepping.cpp b/src/feature/direct_stepping.cpp deleted file mode 100644 index 13cf71e..0000000 --- a/src/feature/direct_stepping.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(DIRECT_STEPPING) - -#include "direct_stepping.h" - -#include "../MarlinCore.h" - -#define CHECK_PAGE(I, R) do{ \ - if (I >= sizeof(page_states) / sizeof(page_states[0])) { \ - fatal_error = true; \ - return R; \ - } \ -}while(0) - -#define CHECK_PAGE_STATE(I, R, S) do { \ - CHECK_PAGE(I, R); \ - if (page_states[I] != S) { \ - fatal_error = true; \ - return R; \ - } \ -}while(0) - -namespace DirectStepping { - - template - State SerialPageManager::state; - - template - volatile bool SerialPageManager::fatal_error; - - template - volatile PageState SerialPageManager::page_states[Cfg::PAGE_COUNT]; - - template - volatile bool SerialPageManager::page_states_dirty; - - template - uint8_t SerialPageManager::pages[Cfg::PAGE_COUNT][Cfg::PAGE_SIZE]; - - template - uint8_t SerialPageManager::checksum; - - template - typename Cfg::write_byte_idx_t SerialPageManager::write_byte_idx; - - template - typename Cfg::page_idx_t SerialPageManager::write_page_idx; - - template - typename Cfg::write_byte_idx_t SerialPageManager::write_page_size; - - template - void SerialPageManager::init() { - for (int i = 0 ; i < Cfg::PAGE_COUNT ; i++) - page_states[i] = PageState::FREE; - - fatal_error = false; - state = State::NEWLINE; - - page_states_dirty = false; - - SERIAL_ECHOLNPGM("pages_ready"); - } - - template - FORCE_INLINE bool SerialPageManager::maybe_store_rxd_char(uint8_t c) { - switch (state) { - default: - case State::MONITOR: - switch (c) { - case '\n': - case '\r': - state = State::NEWLINE; - default: - return false; - } - case State::NEWLINE: - switch (c) { - case Cfg::CONTROL_CHAR: - state = State::ADDRESS; - return true; - case '\n': - case '\r': - state = State::NEWLINE; - return false; - default: - state = State::MONITOR; - return false; - } - case State::ADDRESS: - //TODO: 16 bit address, State::ADDRESS2 - write_page_idx = c; - write_byte_idx = 0; - checksum = 0; - - CHECK_PAGE(write_page_idx, true); - - if (page_states[write_page_idx] == PageState::FAIL) { - // Special case for fail - state = State::UNFAIL; - return true; - } - - set_page_state(write_page_idx, PageState::WRITING); - - state = Cfg::DIRECTIONAL ? State::COLLECT : State::SIZE; - - return true; - case State::SIZE: - // Zero means full page size - write_page_size = c; - state = State::COLLECT; - return true; - case State::COLLECT: - pages[write_page_idx][write_byte_idx++] = c; - checksum ^= c; - - // check if still collecting - if (Cfg::PAGE_SIZE == 256) { - // special case for 8-bit, check if rolled back to 0 - if (Cfg::DIRECTIONAL || !write_page_size) { // full 256 bytes - if (write_byte_idx) return true; - } - else if (write_byte_idx < write_page_size) - return true; - } - else if (Cfg::DIRECTIONAL) { - if (write_byte_idx != Cfg::PAGE_SIZE) - return true; - } - else if (write_byte_idx < write_page_size) - return true; - - state = State::CHECKSUM; - return true; - case State::CHECKSUM: { - const PageState page_state = (checksum == c) ? PageState::OK : PageState::FAIL; - set_page_state(write_page_idx, page_state); - state = State::MONITOR; - return true; - } - case State::UNFAIL: - if (c == 0) - set_page_state(write_page_idx, PageState::FREE); - else - fatal_error = true; - state = State::MONITOR; - return true; - } - } - - template - void SerialPageManager::write_responses() { - if (fatal_error) { - kill(GET_TEXT_F(MSG_BAD_PAGE)); - return; - } - - if (!page_states_dirty) return; - page_states_dirty = false; - - SERIAL_CHAR(Cfg::CONTROL_CHAR); - constexpr int state_bits = 2; - constexpr int n_bytes = Cfg::PAGE_COUNT >> state_bits; - volatile uint8_t bits_b[n_bytes] = { 0 }; - - for (page_idx_t i = 0 ; i < Cfg::PAGE_COUNT ; i++) { - bits_b[i >> state_bits] |= page_states[i] << ((i * state_bits) & 0x7); - } - - uint8_t crc = 0; - for (uint8_t i = 0 ; i < n_bytes ; i++) { - crc ^= bits_b[i]; - SERIAL_CHAR(bits_b[i]); - } - - SERIAL_CHAR(crc); - SERIAL_EOL(); - } - - template - FORCE_INLINE void SerialPageManager::set_page_state(const page_idx_t page_idx, const PageState page_state) { - CHECK_PAGE(page_idx,); - - page_states[page_idx] = page_state; - page_states_dirty = true; - } - - template <> - FORCE_INLINE uint8_t *PageManager::get_page(const page_idx_t page_idx) { - CHECK_PAGE(page_idx, nullptr); - - return pages[page_idx]; - } - - template <> - FORCE_INLINE void PageManager::free_page(const page_idx_t page_idx) { - set_page_state(page_idx, PageState::FREE); - } - -}; - -DirectStepping::PageManager page_manager; - -const uint8_t segment_table[DirectStepping::Config::NUM_SEGMENTS][DirectStepping::Config::SEGMENT_STEPS] PROGMEM = { - - #if STEPPER_PAGE_FORMAT == SP_4x4D_128 - - { 1, 1, 1, 1, 1, 1, 1 }, // 0 = -7 - { 1, 1, 1, 0, 1, 1, 1 }, // 1 = -6 - { 1, 1, 1, 0, 1, 0, 1 }, // 2 = -5 - { 1, 1, 0, 1, 0, 1, 0 }, // 3 = -4 - { 1, 1, 0, 0, 1, 0, 0 }, // 4 = -3 - { 0, 0, 1, 0, 0, 0, 1 }, // 5 = -2 - { 0, 0, 0, 1, 0, 0, 0 }, // 6 = -1 - { 0, 0, 0, 0, 0, 0, 0 }, // 7 = 0 - { 0, 0, 0, 1, 0, 0, 0 }, // 8 = 1 - { 0, 0, 1, 0, 0, 0, 1 }, // 9 = 2 - { 1, 1, 0, 0, 1, 0, 0 }, // 10 = 3 - { 1, 1, 0, 1, 0, 1, 0 }, // 11 = 4 - { 1, 1, 1, 0, 1, 0, 1 }, // 12 = 5 - { 1, 1, 1, 0, 1, 1, 1 }, // 13 = 6 - { 1, 1, 1, 1, 1, 1, 1 }, // 14 = 7 - { 0 } - - #elif STEPPER_PAGE_FORMAT == SP_4x2_256 - - { 0, 0, 0 }, // 0 - { 0, 1, 0 }, // 1 - { 1, 0, 1 }, // 2 - { 1, 1, 1 }, // 3 - - #elif STEPPER_PAGE_FORMAT == SP_4x1_512 - - {0} // Uncompressed format, table not used - - #endif - -}; - -#endif // DIRECT_STEPPING diff --git a/src/feature/direct_stepping.h b/src/feature/direct_stepping.h deleted file mode 100644 index 9623102..0000000 --- a/src/feature/direct_stepping.h +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -namespace DirectStepping { - - enum State : char { - MONITOR, NEWLINE, ADDRESS, SIZE, COLLECT, CHECKSUM, UNFAIL - }; - - enum PageState : uint8_t { - FREE, WRITING, OK, FAIL - }; - - // Static state used for stepping through direct stepping pages - struct page_step_state_t { - // Current page - uint8_t *page; - // Current segment - uint16_t segment_idx; - // Current steps within segment - uint8_t segment_steps; - // Segment delta - xyze_uint8_t sd; - // Block delta - xyze_int_t bd; - }; - - template - class SerialPageManager { - public: - - typedef typename Cfg::page_idx_t page_idx_t; - - static bool maybe_store_rxd_char(uint8_t c); - static void write_responses(); - - // common methods for page managers - static void init(); - static uint8_t *get_page(const page_idx_t page_idx); - static void free_page(const page_idx_t page_idx); - - protected: - - typedef typename Cfg::write_byte_idx_t write_byte_idx_t; - - static State state; - static volatile bool fatal_error; - - static volatile PageState page_states[Cfg::PAGE_COUNT]; - static volatile bool page_states_dirty; - - static uint8_t pages[Cfg::PAGE_COUNT][Cfg::PAGE_SIZE]; - static uint8_t checksum; - static write_byte_idx_t write_byte_idx; - static page_idx_t write_page_idx; - static write_byte_idx_t write_page_size; - - static void set_page_state(const page_idx_t page_idx, const PageState page_state); - }; - - template struct TypeSelector { typedef T type;} ; - template struct TypeSelector { typedef F type; }; - - template - struct config_t { - static constexpr char CONTROL_CHAR = '!'; - - static constexpr int PAGE_COUNT = num_pages; - static constexpr int AXIS_COUNT = num_axes; - static constexpr int BITS_SEGMENT = bits_segment; - static constexpr int DIRECTIONAL = dir ? 1 : 0; - static constexpr int SEGMENTS = segments; - - static constexpr int NUM_SEGMENTS = _BV(BITS_SEGMENT); - static constexpr int SEGMENT_STEPS = _BV(BITS_SEGMENT - DIRECTIONAL) - 1; - static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS; - static constexpr int PAGE_SIZE = (AXIS_COUNT * BITS_SEGMENT * SEGMENTS) / 8; - - typedef typename TypeSelector<(PAGE_SIZE>256), uint16_t, uint8_t>::type write_byte_idx_t; - typedef typename TypeSelector<(PAGE_COUNT>256), uint16_t, uint8_t>::type page_idx_t; - }; - - template - using SP_4x4D_128 = config_t; - - template - using SP_4x2_256 = config_t; - - template - using SP_4x1_512 = config_t; - - // configured types - typedef STEPPER_PAGE_FORMAT Config; - - template class PAGE_MANAGER; - typedef PAGE_MANAGER PageManager; -}; - -#define SP_4x4D_128 1 -//#define SP_4x4_128 2 -//#define SP_4x2D_256 3 -#define SP_4x2_256 4 -#define SP_4x1_512 5 - -typedef typename DirectStepping::Config::page_idx_t page_idx_t; - -// TODO: use config -typedef DirectStepping::page_step_state_t page_step_state_t; - -extern const uint8_t segment_table[DirectStepping::Config::NUM_SEGMENTS][DirectStepping::Config::SEGMENT_STEPS]; -extern DirectStepping::PageManager page_manager; diff --git a/src/feature/e_parser.cpp b/src/feature/e_parser.cpp deleted file mode 100644 index d98afcf..0000000 --- a/src/feature/e_parser.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * e_parser.cpp - Intercept special commands directly in the serial stream - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - -#include "e_parser.h" - -// Static data members -bool EmergencyParser::killed_by_M112, // = false - EmergencyParser::quickstop_by_M410, - EmergencyParser::enabled; - -#if ENABLED(HOST_PROMPT_SUPPORT) - uint8_t EmergencyParser::M876_reason; // = 0 -#endif - -// Global instance -EmergencyParser emergency_parser; - -#endif // EMERGENCY_PARSER diff --git a/src/feature/e_parser.h b/src/feature/e_parser.h deleted file mode 100644 index fda1ba1..0000000 --- a/src/feature/e_parser.h +++ /dev/null @@ -1,225 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * e_parser.h - Intercept special commands directly in the serial stream - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(HOST_PROMPT_SUPPORT) - #include "host_actions.h" -#endif - -// External references -extern bool wait_for_user, wait_for_heatup; - -#if ENABLED(REALTIME_REPORTING_COMMANDS) - // From motion.h, which cannot be included here - void report_current_position_moving(); - void quickpause_stepper(); - void quickresume_stepper(); -#endif - -#if ENABLED(SOFT_RESET_VIA_SERIAL) - void HAL_reboot(); -#endif - -class EmergencyParser { - -public: - - // Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000 - enum State : uint8_t { - EP_RESET, - EP_N, - EP_M, - EP_M1, - EP_M10, EP_M108, - EP_M11, EP_M112, - EP_M4, EP_M41, EP_M410, - #if ENABLED(HOST_PROMPT_SUPPORT) - EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN, - #endif - #if ENABLED(REALTIME_REPORTING_COMMANDS) - EP_S, EP_S0, EP_S00, EP_GRBL_STATUS, - EP_R, EP_R0, EP_R00, EP_GRBL_RESUME, - EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE, - #endif - #if ENABLED(SOFT_RESET_VIA_SERIAL) - EP_ctrl, - EP_K, EP_KI, EP_KIL, EP_KILL, - #endif - EP_IGNORE // to '\n' - }; - - static bool killed_by_M112; - static bool quickstop_by_M410; - - #if ENABLED(HOST_PROMPT_SUPPORT) - static uint8_t M876_reason; - #endif - - EmergencyParser() { enable(); } - - FORCE_INLINE static void enable() { enabled = true; } - FORCE_INLINE static void disable() { enabled = false; } - - FORCE_INLINE static void update(State &state, const uint8_t c) { - switch (state) { - case EP_RESET: - switch (c) { - case ' ': case '\n': case '\r': break; - case 'N': state = EP_N; break; - case 'M': state = EP_M; break; - #if ENABLED(REALTIME_REPORTING_COMMANDS) - case 'S': state = EP_S; break; - case 'P': state = EP_P; break; - case 'R': state = EP_R; break; - #endif - #if ENABLED(SOFT_RESET_VIA_SERIAL) - case '^': state = EP_ctrl; break; - case 'K': state = EP_K; break; - #endif - default: state = EP_IGNORE; - } - break; - - case EP_N: - switch (c) { - case '0' ... '9': - case '-': case ' ': break; - case 'M': state = EP_M; break; - #if ENABLED(REALTIME_REPORTING_COMMANDS) - case 'S': state = EP_S; break; - case 'P': state = EP_P; break; - case 'R': state = EP_R; break; - #endif - default: state = EP_IGNORE; - } - break; - - #if ENABLED(REALTIME_REPORTING_COMMANDS) - case EP_S: state = (c == '0') ? EP_S0 : EP_IGNORE; break; - case EP_S0: state = (c == '0') ? EP_S00 : EP_IGNORE; break; - case EP_S00: state = (c == '0') ? EP_GRBL_STATUS : EP_IGNORE; break; - - case EP_R: state = (c == '0') ? EP_R0 : EP_IGNORE; break; - case EP_R0: state = (c == '0') ? EP_R00 : EP_IGNORE; break; - case EP_R00: state = (c == '0') ? EP_GRBL_RESUME : EP_IGNORE; break; - - case EP_P: state = (c == '0') ? EP_P0 : EP_IGNORE; break; - case EP_P0: state = (c == '0') ? EP_P00 : EP_IGNORE; break; - case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE : EP_IGNORE; break; - #endif - - #if ENABLED(SOFT_RESET_VIA_SERIAL) - case EP_ctrl: state = (c == 'X') ? EP_KILL : EP_IGNORE; break; - case EP_K: state = (c == 'I') ? EP_KI : EP_IGNORE; break; - case EP_KI: state = (c == 'L') ? EP_KIL : EP_IGNORE; break; - case EP_KIL: state = (c == 'L') ? EP_KILL : EP_IGNORE; break; - #endif - - case EP_M: - switch (c) { - case ' ': break; - case '1': state = EP_M1; break; - case '4': state = EP_M4; break; - #if ENABLED(HOST_PROMPT_SUPPORT) - case '8': state = EP_M8; break; - #endif - default: state = EP_IGNORE; - } - break; - - case EP_M1: - switch (c) { - case '0': state = EP_M10; break; - case '1': state = EP_M11; break; - default: state = EP_IGNORE; - } - break; - - case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break; - case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break; - case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break; - case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break; - - #if ENABLED(HOST_PROMPT_SUPPORT) - - case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break; - case EP_M87: state = (c == '6') ? EP_M876 : EP_IGNORE; break; - - case EP_M876: - switch (c) { - case ' ': break; - case 'S': state = EP_M876S; break; - default: state = EP_IGNORE; break; - } - break; - - case EP_M876S: - switch (c) { - case ' ': break; - case '0' ... '9': - state = EP_M876SN; - M876_reason = uint8_t(c - '0'); - break; - } - break; - - #endif - - case EP_IGNORE: - if (ISEOL(c)) state = EP_RESET; - break; - - default: - if (ISEOL(c)) { - if (enabled) switch (state) { - case EP_M108: wait_for_user = wait_for_heatup = false; break; - case EP_M112: killed_by_M112 = true; break; - case EP_M410: quickstop_by_M410 = true; break; - #if ENABLED(HOST_PROMPT_SUPPORT) - case EP_M876SN: hostui.handle_response(M876_reason); break; - #endif - #if ENABLED(REALTIME_REPORTING_COMMANDS) - case EP_GRBL_STATUS: report_current_position_moving(); break; - case EP_GRBL_PAUSE: quickpause_stepper(); break; - case EP_GRBL_RESUME: quickresume_stepper(); break; - #endif - #if ENABLED(SOFT_RESET_VIA_SERIAL) - case EP_KILL: HAL_reboot(); break; - #endif - default: break; - } - state = EP_RESET; - } - } - } - -private: - static bool enabled; -}; - -extern EmergencyParser emergency_parser; diff --git a/src/feature/easythreed_ui.cpp b/src/feature/easythreed_ui.cpp deleted file mode 100644 index b15daff..0000000 --- a/src/feature/easythreed_ui.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(EASYTHREED_UI) - -#include "easythreed_ui.h" -#include "pause.h" -#include "../module/temperature.h" -#include "../module/printcounter.h" -#include "../sd/cardreader.h" -#include "../gcode/queue.h" -#include "../module/motion.h" -#include "../module/planner.h" -#include "../MarlinCore.h" - -EasythreedUI easythreed_ui; - -#define BTN_DEBOUNCE_MS 20 - -void EasythreedUI::init() { - SET_INPUT_PULLUP(BTN_HOME); SET_OUTPUT(BTN_HOME_GND); - SET_INPUT_PULLUP(BTN_FEED); SET_OUTPUT(BTN_FEED_GND); - SET_INPUT_PULLUP(BTN_RETRACT); SET_OUTPUT(BTN_RETRACT_GND); - SET_INPUT_PULLUP(BTN_PRINT); - SET_OUTPUT(EASYTHREED_LED_PIN); -} - -void EasythreedUI::run() { - blinkLED(); - loadButton(); - printButton(); -} - -enum LEDInterval : uint16_t { - LED_OFF = 0, - LED_ON = 4000, - LED_BLINK_0 = 2500, - LED_BLINK_1 = 1500, - LED_BLINK_2 = 1000, - LED_BLINK_3 = 800, - LED_BLINK_4 = 500, - LED_BLINK_5 = 300, - LED_BLINK_6 = 150, - LED_BLINK_7 = 50 -}; - -uint16_t blink_interval_ms = LED_ON; // Status LED on Start button - -void EasythreedUI::blinkLED() { - static millis_t prev_blink_interval_ms = 0, blink_start_ms = 0; - - if (blink_interval_ms == LED_OFF) { WRITE(EASYTHREED_LED_PIN, HIGH); return; } // OFF - if (blink_interval_ms >= LED_ON) { WRITE(EASYTHREED_LED_PIN, LOW); return; } // ON - - const millis_t ms = millis(); - if (prev_blink_interval_ms != blink_interval_ms) { - prev_blink_interval_ms = blink_interval_ms; - blink_start_ms = ms; - } - if (PENDING(ms, blink_start_ms + blink_interval_ms)) - WRITE(EASYTHREED_LED_PIN, LOW); - else if (PENDING(ms, blink_start_ms + 2 * blink_interval_ms)) - WRITE(EASYTHREED_LED_PIN, HIGH); - else - blink_start_ms = ms; -} - -// -// Filament Load/Unload Button -// Load/Unload buttons are a 3 position switch with a common center ground. -// -void EasythreedUI::loadButton() { - if (printingIsActive()) return; - - enum FilamentStatus : uint8_t { FS_IDLE, FS_PRESS, FS_CHECK, FS_PROCEED }; - static uint8_t filament_status = FS_IDLE; - static millis_t filament_time = 0; - - switch (filament_status) { - - case FS_IDLE: - if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) { // If feed/retract switch is toggled... - filament_status++; // ...proceed to next test. - filament_time = millis(); - } - break; - - case FS_PRESS: - if (ELAPSED(millis(), filament_time + BTN_DEBOUNCE_MS)) { // After a short debounce delay... - if (!READ(BTN_RETRACT) || !READ(BTN_FEED)) { // ...if switch still toggled... - thermalManager.setTargetHotend(EXTRUDE_MINTEMP + 10, 0); // Start heating up - blink_interval_ms = LED_BLINK_7; // Set the LED to blink fast - filament_status++; - } - else - filament_status = FS_IDLE; // Switch not toggled long enough - } - break; - - case FS_CHECK: - if (READ(BTN_RETRACT) && READ(BTN_FEED)) { // Switch in center position (stop) - blink_interval_ms = LED_ON; // LED on steady - filament_status = FS_IDLE; - thermalManager.disable_all_heaters(); - } - else if (thermalManager.hotEnoughToExtrude(0)) { // Is the hotend hot enough to move material? - filament_status++; // Proceed to feed / retract. - blink_interval_ms = LED_BLINK_5; // Blink ~3 times per second - } - break; - - case FS_PROCEED: { - // Feed or Retract just once. Hard abort all moves and return to idle on swicth release. - static bool flag = false; - if (READ(BTN_RETRACT) && READ(BTN_FEED)) { // Switch in center position (stop) - flag = false; // Restore flag to false - filament_status = FS_IDLE; // Go back to idle state - quickstop_stepper(); // Hard-stop all the steppers ... now! - thermalManager.disable_all_heaters(); // And disable all the heaters - blink_interval_ms = LED_ON; - } - else if (!flag) { - flag = true; - queue.inject(!READ(BTN_RETRACT) ? F("G91\nG0 E10 F180\nG0 E-120 F180\nM104 S0") : F("G91\nG0 E100 F120\nM104 S0")); - } - } break; - } - -} - -#if HAS_STEPPER_RESET - void disableStepperDrivers(); -#endif - -// -// Print Start/Pause/Resume Button -// -void EasythreedUI::printButton() { - enum KeyStatus : uint8_t { KS_IDLE, KS_PRESS, KS_PROCEED }; - static uint8_t key_status = KS_IDLE; - static millis_t key_time = 0; - - enum PrintFlag : uint8_t { PF_START, PF_PAUSE, PF_RESUME }; - static PrintFlag print_key_flag = PF_START; - - const millis_t ms = millis(); - - switch (key_status) { - case KS_IDLE: - if (!READ(BTN_PRINT)) { // Print/Pause/Resume button pressed? - key_time = ms; // Save start time - key_status++; // Go to debounce test - } - break; - - case KS_PRESS: - if (ELAPSED(ms, key_time + BTN_DEBOUNCE_MS)) // Wait for debounce interval to expire - key_status = READ(BTN_PRINT) ? KS_IDLE : KS_PROCEED; // Proceed if still pressed - break; - - case KS_PROCEED: - if (!READ(BTN_PRINT)) break; // Wait for the button to be released - key_status = KS_IDLE; // Ready for the next press - if (PENDING(ms, key_time + 1200 - BTN_DEBOUNCE_MS)) { // Register a press < 1.2 seconds - switch (print_key_flag) { - case PF_START: { // The "Print" button starts an SD card print - if (printingIsActive()) break; // Already printing? (find another line that checks for 'is planner doing anything else right now?') - blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals - print_key_flag = PF_PAUSE; // The "Print" button now pauses the print - card.mount(); // Force SD card to mount - now! - if (!card.isMounted) { // Failed to mount? - blink_interval_ms = LED_OFF; // Turn off LED - print_key_flag = PF_START; - return; // Bail out - } - card.ls(); // List all files to serial output - const uint16_t filecnt = card.countFilesInWorkDir(); // Count printable files in cwd - if (filecnt == 0) return; // None are printable? - card.selectFileByIndex(filecnt); // Select the last file according to current sort options - card.openAndPrintFile(card.filename); // Start printing it - break; - } - case PF_PAUSE: { // Pause printing (not currently firing) - if (!printingIsActive()) break; - blink_interval_ms = LED_ON; // Set indicator to steady ON - queue.inject(F("M25")); // Queue Pause - print_key_flag = PF_RESUME; // The "Print" button now resumes the print - break; - } - case PF_RESUME: { // Resume printing - if (printingIsActive()) break; - blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals - queue.inject(F("M24")); // Queue resume - print_key_flag = PF_PAUSE; // The "Print" button now pauses the print - break; - } - } - } - else { // Register a longer press - if (print_key_flag == PF_START && !printingIsActive()) { // While not printing, this moves Z up 10mm - blink_interval_ms = LED_ON; - queue.inject(F("G91\nG0 Z10 F600\nG90")); // Raise Z soon after returning to main loop - } - else { // While printing, cancel print - card.abortFilePrintSoon(); // There is a delay while the current steps play out - blink_interval_ms = LED_OFF; // Turn off LED - } - planner.synchronize(); // Wait for commands already in the planner to finish - TERN_(HAS_STEPPER_RESET, disableStepperDrivers()); // Disable all steppers - now! - print_key_flag = PF_START; // The "Print" button now starts a new print - } - break; - } -} -#endif // EASYTHREED_UI diff --git a/src/feature/easythreed_ui.h b/src/feature/easythreed_ui.h deleted file mode 100644 index af9ad2d..0000000 --- a/src/feature/easythreed_ui.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -class EasythreedUI { - public: - static void init(); - static void run(); - - private: - static void blinkLED(); - static void loadButton(); - static void printButton(); -}; - -extern EasythreedUI easythreed_ui; diff --git a/src/feature/encoder_i2c.cpp b/src/feature/encoder_i2c.cpp deleted file mode 100644 index 092ce0f..0000000 --- a/src/feature/encoder_i2c.cpp +++ /dev/null @@ -1,1128 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -//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 "../inc/MarlinConfig.h" - -#if ENABLED(I2C_POSITION_ENCODERS) - -#include "encoder_i2c.h" - -#include "../module/stepper.h" -#include "../gcode/parser.h" - -#include "../feature/babystep.h" - -#include - -I2CPositionEncodersMgr I2CPEM; - -void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) { - encoderAxis = axis; - i2cAddress = address; - - initialized = true; - - SERIAL_ECHOLNPGM("Setting up encoder on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " axis, addr = ", address); - - position = get_position(); -} - -void I2CPositionEncoder::update() { - if (!initialized || !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_ECHOLNPGM("Fault detected on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " 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 0 - // 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_ECHOLNPGM("Untrusted encoder module on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " axis has been fault-free for set duration, reinstating error correction."); - - //the encoder likely lost its place when the error occurred, so we'll reset and use the printer's - //idea of where it the axis is to re-initialize - const float pos = planner.get_axis_position_mm(encoderAxis); - int32_t positionInTicks = pos * get_ticks_unit(); - - //shift position from previous to current position - zeroOffset -= (positionInTicks - get_position()); - - #ifdef I2CPE_DEBUG - SERIAL_ECHOLNPGM("Current position is ", pos); - SERIAL_ECHOLNPGM("Position in encoder ticks is ", positionInTicks); - SERIAL_ECHOLNPGM("New zero-offset of ", zeroOffset); - SERIAL_ECHOPGM("New position reads as ", get_position()); - SERIAL_CHAR('('); - SERIAL_DECIMAL(mm_from_count(get_position())); - SERIAL_ECHOLNPGM(")"); - #endif - } - #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_ECHOLNPGM("Axis error steps: ", error); - - #ifdef I2CPE_ERR_THRESH_ABORT - if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.settings.axis_steps_per_mm[encoderAxis]) { - //kill(F("Significant Error")); - SERIAL_ECHOLNPGM("Axis error over threshold, aborting!", 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 (ABS(error) > threshold * planner.settings.axis_steps_per_mm[encoderAxis] - && diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) - && ABS(error) < 2000 - ) { // Check for persistent error (skip) - errPrst[errPrstIdx++] = error; // Error must persist for I2CPE_ERR_PRST_ARRAY_SIZE error cycles. This also serves to improve the average accuracy - if (errPrstIdx >= I2CPE_ERR_PRST_ARRAY_SIZE) { - float sumP = 0; - LOOP_L_N(i, I2CPE_ERR_PRST_ARRAY_SIZE) sumP += errPrst[i]; - const int32_t errorP = int32_t(sumP * RECIPROCAL(I2CPE_ERR_PRST_ARRAY_SIZE)); - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" : CORRECT ERR ", errorP * planner.mm_per_step[encoderAxis], "mm"); - babystep.add_steps(encoderAxis, -LROUND(errorP)); - errPrstIdx = 0; - } - } - else - errPrstIdx = 0; - } - #else - if (ABS(error) > threshold * planner.settings.axis_steps_per_mm[encoderAxis]) { - //SERIAL_ECHOLN(error); - //SERIAL_ECHOLN(position); - babystep.add_steps(encoderAxis, -LROUND(error / 2)); - } - #endif - - if (ABS(error) > I2CPE_ERR_CNT_THRESH * planner.settings.axis_steps_per_mm[encoderAxis]) { - const millis_t ms = millis(); - if (ELAPSED(ms, nextErrorCountTime)) { - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" : LARGE ERR ", error, "; 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 = true; - - #ifdef I2CPE_DEBUG - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" axis encoder homed, offset of ", zeroOffset, " ticks."); - #endif - } -} - -void I2CPositionEncoder::set_unhomed() { - zeroOffset = 0; - homed = trusted = false; - - #ifdef I2CPE_DEBUG - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" axis encoder unhomed."); - #endif -} - -bool I2CPositionEncoder::passes_test(const bool report) { - if (report) { - if (H != I2CPE_MAG_SIG_GOOD) SERIAL_ECHOPGM("Warning. "); - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - serial_ternary(H == I2CPE_MAG_SIG_BAD, F(" axis "), F("magnetic strip "), F("encoder ")); - switch (H) { - case I2CPE_MAG_SIG_GOOD: - case I2CPE_MAG_SIG_MID: - SERIAL_ECHO_TERNARY(H == I2CPE_MAG_SIG_GOOD, "passes test; field strength ", "good", "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) { - const float target = planner.get_axis_position_mm(encoderAxis), - actual = mm_from_count(position), - diff = actual - target, - error = ABS(diff) > 10000 ? 0 : diff; // Huge error is a bad reading - - if (report) { - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" axis target=", target, "mm; actual=", actual, "mm; err=", error, "mm"); - } - - return error; -} - -int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) { - if (!active) { - if (report) { - SERIAL_CHAR(AXIS_CHAR(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.settings.axis_steps_per_mm[encoderAxis]; - - //convert both 'ticks' into same units / base - encoderCountInStepperTicksScaled = LROUND((stepperTicksPerUnit * encoderTicks) / encoderTicksPerUnit); - - const int32_t target = stepper.position(encoderAxis); - int32_t error = encoderCountInStepperTicksScaled - target; - - //suppress discontinuities (might be caused by bad I2C readings...?) - const bool suppressOutput = (ABS(error - errorPrev) > 100); - - errorPrev = error; - - if (report) { - SERIAL_CHAR(AXIS_CHAR(encoderAxis)); - SERIAL_ECHOLNPGM(" axis target=", target, "; actual=", encoderCountInStepperTicksScaled, "; err=", error); - } - - if (suppressOutput) { - if (report) SERIAL_ECHOLNPGM("!Discontinuity. Suppressing error."); - error = 0; - } - - return error; -} - -int32_t I2CPositionEncoder::get_raw_count() { - uint8_t index = 0; - i2cLong encoderCount; - - encoderCount.val = 0x00; - - if (Wire.requestFrom(I2C_ADDRESS(i2cAddress), uint8_t(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; - - const float startPosition = soft_endstop.min[encoderAxis] + 10, - endPosition = soft_endstop.max[encoderAxis] - 10; - const feedRate_t fr_mm_s = FLOOR(homing_feedrate(encoderAxis)); - - ec = false; - - xyze_pos_t startCoord, endCoord; - LOOP_NUM_AXES(a) { - startCoord[a] = planner.get_axis_position_mm((AxisEnum)a); - endCoord[a] = planner.get_axis_position_mm((AxisEnum)a); - } - startCoord[encoderAxis] = startPosition; - endCoord[encoderAxis] = endPosition; - - planner.synchronize(); - - #if HAS_EXTRUDERS - startCoord.e = planner.get_axis_position_mm(E_AXIS); - planner.buffer_line(startCoord, fr_mm_s, 0); - planner.synchronize(); - #endif - - // 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 - TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS)); - planner.buffer_line(endCoord, fr_mm_s, 0); - planner.synchronize(); - } - - return trusted; -} - -void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) { - if (type != I2CPE_ENC_TYPE_LINEAR) { - SERIAL_ECHOLNPGM("Steps/mm calibration requires linear encoder."); - return; - } - - if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) { - SERIAL_ECHOLNPGM("Steps/mm calibration not supported for this axis."); - return; - } - - float old_steps_mm, new_steps_mm, - startDistance, endDistance, - travelDistance, travelledDistance, total = 0; - - int32_t startCount, stopCount; - - const feedRate_t fr_mm_s = homing_feedrate(encoderAxis); - - bool oldec = ec; - ec = false; - - startDistance = 20; - endDistance = soft_endstop.max[encoderAxis] - 20; - travelDistance = endDistance - startDistance; - - xyze_pos_t startCoord, endCoord; - LOOP_NUM_AXES(a) { - startCoord[a] = planner.get_axis_position_mm((AxisEnum)a); - endCoord[a] = planner.get_axis_position_mm((AxisEnum)a); - } - startCoord[encoderAxis] = startDistance; - endCoord[encoderAxis] = endDistance; - - planner.synchronize(); - - LOOP_L_N(i, iter) { - TERN_(HAS_EXTRUDERS, startCoord.e = planner.get_axis_position_mm(E_AXIS)); - planner.buffer_line(startCoord, fr_mm_s, 0); - planner.synchronize(); - - delay(250); - startCount = get_position(); - - //do_blocking_move_to(endCoord); - - TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS)); - planner.buffer_line(endCoord, fr_mm_s, 0); - planner.synchronize(); - - //Read encoder distance - delay(250); - stopCount = get_position(); - - travelledDistance = mm_from_count(ABS(stopCount - startCount)); - - SERIAL_ECHOLNPGM("Attempted travel: ", travelDistance, "mm"); - SERIAL_ECHOLNPGM(" Actual travel: ", travelledDistance, "mm"); - - //Calculate new axis steps per unit - old_steps_mm = planner.settings.axis_steps_per_mm[encoderAxis]; - new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance; - - SERIAL_ECHOLNPGM("Old steps/mm: ", old_steps_mm); - SERIAL_ECHOLNPGM("New steps/mm: ", new_steps_mm); - - //Save new value - planner.settings.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 - const float tempCoord = startCoord[encoderAxis]; - startCoord[encoderAxis] = endCoord[encoderAxis]; - endCoord[encoderAxis] = tempCoord; - } - } - - if (iter > 1) { - total /= (float)iter; - SERIAL_ECHOLNPGM("Average steps/mm: ", total); - } - - ec = oldec; - - SERIAL_ECHOLNPGM("Calculated steps/mm set. Use M500 to save to EEPROM."); -} - -void I2CPositionEncoder::reset() { - Wire.beginTransmission(I2C_ADDRESS(i2cAddress)); - Wire.write(I2CPE_RESET_COUNT); - Wire.endTransmission(); - - TERN_(I2CPE_ERR_ROLLING_AVERAGE, ZERO(err)); -} - - -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(ENABLED(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)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_1_AXIS == E_AXIS) encoders[i].set_homed()); - #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(ENABLED(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)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_2_AXIS == E_AXIS) encoders[i].set_homed()); - #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(ENABLED(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)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_3_AXIS == E_AXIS) encoders[i].set_homed()); - #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(ENABLED(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)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_4_AXIS == E_AXIS) encoders[i].set_homed()); - #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(ENABLED(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)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_5_AXIS == E_AXIS) encoders[i].set_homed()); - #endif - - #if I2CPE_ENCODER_CNT > 5 - i++; - - encoders[i].init(I2CPE_ENC_6_ADDR, I2CPE_ENC_6_AXIS); - - #ifdef I2CPE_ENC_6_TYPE - encoders[i].set_type(I2CPE_ENC_6_TYPE); - #endif - #ifdef I2CPE_ENC_6_TICKS_UNIT - encoders[i].set_ticks_unit(I2CPE_ENC_6_TICKS_UNIT); - #endif - #ifdef I2CPE_ENC_6_TICKS_REV - encoders[i].set_stepper_ticks(I2CPE_ENC_6_TICKS_REV); - #endif - #ifdef I2CPE_ENC_6_INVERT - encoders[i].set_inverted(ENABLED(I2CPE_ENC_6_INVERT)); - #endif - #ifdef I2CPE_ENC_6_EC_METHOD - encoders[i].set_ec_method(I2CPE_ENC_6_EC_METHOD); - #endif - #ifdef I2CPE_ENC_6_EC_THRESH - encoders[i].set_ec_threshold(I2CPE_ENC_6_EC_THRESH); - #endif - - encoders[i].set_active(encoders[i].passes_test(true)); - - TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_6_AXIS == E_AXIS) encoders[i].set_homed()); - #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_CHAR(AXIS_CHAR(encoders[idx).get_axis()], ' '); - - 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(I2C_ADDRESS(newaddr)); - if (!Wire.endTransmission()) { - SERIAL_ECHOLNPGM("?There is already a device with that address on the I2C bus! (", newaddr, ")"); - return; - } - - // Now check that we can find the module on the oldaddr address - Wire.beginTransmission(I2C_ADDRESS(oldaddr)); - if (Wire.endTransmission()) { - SERIAL_ECHOLNPGM("?No module detected at this address! (", oldaddr, ")"); - return; - } - - SERIAL_ECHOLNPGM("Module found at ", oldaddr, ", changing address to ", newaddr); - - // Change the modules address - Wire.beginTransmission(I2C_ADDRESS(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(I2C_ADDRESS(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 initialization on power-up, before the address change). - const int8_t idx = idx_from_addr(newaddr); - if (idx >= 0 && !encoders[idx].get_active()) { - SERIAL_CHAR(AXIS_CHAR(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(I2C_ADDRESS(address)); - if (Wire.endTransmission()) { - SERIAL_ECHOLNPGM("?No module detected at this address! (", address, ")"); - return; - } - - SERIAL_ECHOLNPGM("Requesting version info from module at address ", address, ":"); - - Wire.beginTransmission(I2C_ADDRESS(address)); - Wire.write(I2CPE_SET_REPORT_MODE); - Wire.write(I2CPE_REPORT_VERSION); - Wire.endTransmission(); - - // Read value - if (Wire.requestFrom(I2C_ADDRESS(address), uint8_t(32))) { - char c; - while (Wire.available() > 0 && (c = (char)Wire.read()) > 0) - SERIAL_CHAR(c); - SERIAL_EOL(); - } - - // Set module back to normal (distance) mode - Wire.beginTransmission(I2C_ADDRESS(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_ECHOLNPGM("?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_ECHOLNPGM("?Address out of range. [30-200]"); - return I2CPE_PARSE_ERR; - } - - I2CPE_idx = idx_from_addr(I2CPE_addr); - if (I2CPE_idx >= I2CPE_ENCODER_CNT) { - SERIAL_ECHOLNPGM("?No device with this address!"); - return I2CPE_PARSE_ERR; - } - } - else if (parser.seenval('I')) { - - if (!parser.has_value()) { - SERIAL_ECHOLNPGM("?I seen, but no index specified! [0-", I2CPE_ENCODER_CNT - 1, "]"); - return I2CPE_PARSE_ERR; - } - - I2CPE_idx = parser.value_byte(); - if (I2CPE_idx >= I2CPE_ENCODER_CNT) { - SERIAL_ECHOLNPGM("?Index out of range. [0-", I2CPE_ENCODER_CNT - 1, "]"); - 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_test('U'), hasO = parser.seen_test('O'); - - if (I2CPE_idx == 0xFF) { - LOOP_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen_test(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_ECHOLNPGM("?S seen, but no address specified! [30-200]"); - return; - } - - newAddress = parser.value_byte(); - if (!WITHIN(newAddress, 30, 200)) { - SERIAL_ECHOLNPGM("?New address out of range. [30-200]"); - return; - } - } - else if (!I2CPE_anyaxis) { - SERIAL_ECHOLNPGM("?You must specify S or [XYZE]."); - return; - } - else { - if (parser.seen_test('X')) newAddress = I2CPE_PRESET_ADDR_X; - else if (parser.seen_test('Y')) newAddress = I2CPE_PRESET_ADDR_Y; - else if (parser.seen_test('Z')) newAddress = I2CPE_PRESET_ADDR_Z; - else if (parser.seen_test('E')) newAddress = I2CPE_PRESET_ADDR_E; - else return; - } - - SERIAL_ECHOLNPGM("Changing module at address ", I2CPE_addr, " 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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_test('R'); - - if (I2CPE_idx == 0xFF) { - LOOP_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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_LOGICAL_AXES(i) { - if (!I2CPE_anyaxis || parser.seen(AXIS_CHAR(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/src/feature/encoder_i2c.h b/src/feature/encoder_i2c.h deleted file mode 100644 index f25fe2e..0000000 --- a/src/feature/encoder_i2c.h +++ /dev/null @@ -1,320 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#include "../module/planner.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 - #define I2CPE_ERR_PRST_ARRAY_SIZE 10 -#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) - -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, - initialized = false, - active = false, - invert = false, - ec = true; - - int32_t zeroOffset = 0, - lastPosition = 0, - position; - - millis_t lastPositionTime = 0, - nextErrorCountTime = 0, - lastErrorTime; - - #if ENABLED(I2CPE_ERR_ROLLING_AVERAGE) - uint8_t errIdx = 0, errPrstIdx = 0; - int err[I2CPE_ERR_ARRAY_SIZE] = { 0 }, - errPrst[I2CPE_ERR_PRST_ARRAY_SIZE] = { 0 }; - #endif - - public: - void init(const uint8_t address, const AxisEnum axis); - void reset(); - - void update(); - - void set_homed(); - void set_unhomed(); - - 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.settings.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; } - - 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(); - - FORCE_INLINE int get_error_count() { 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() { 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_t 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.settings.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; } -}; - -class I2CPositionEncodersMgr { - private: - static bool I2CPE_anyaxis; - static uint8_t I2CPE_addr, I2CPE_idx; - - public: - - static void init(); - - // consider only updating one endoder per call / tick if encoders become too time intensive - static void update() { 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 unhomed(const AxisEnum axis) { - LOOP_PE(i) - if (encoders[i].get_axis() == axis) encoders[i].set_unhomed(); - } - - 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_ECHOLNPGM("Encoder ", idx, ": "); - 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_ECHOLNPGM("Error count on ", AS_CHAR(AXIS_CHAR(axis)), " 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_ECHOLNPGM("Error count on ", AS_CHAR(AXIS_CHAR(axis)), " 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_ECHOPGM("Error correction on ", AS_CHAR(AXIS_CHAR(axis))); - SERIAL_ECHO_TERNARY(encoders[idx].get_ec_enabled(), " axis is ", "en", "dis", "abled.\n"); - } - - static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) { - CHECK_IDX(); - encoders[idx].set_ec_threshold(newThreshold); - SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(AXIS_CHAR(axis)), " axis set to ", newThreshold, "mm."); - } - - static void get_ec_threshold(const int8_t idx, const AxisEnum axis) { - CHECK_IDX(); - const float threshold = encoders[idx].get_ec_threshold(); - SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(AXIS_CHAR(axis)), " axis is ", threshold, "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; diff --git a/src/feature/ethernet.cpp b/src/feature/ethernet.cpp deleted file mode 100644 index c5bfa93..0000000 --- a/src/feature/ethernet.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if HAS_ETHERNET - -#include "ethernet.h" -#include "../core/serial.h" - -#define DEBUG_OUT ENABLED(DEBUG_ETHERNET) -#include "../core/debug_out.h" - -bool MarlinEthernet::hardware_enabled, // = false - MarlinEthernet::have_telnet_client; // = false - -IPAddress MarlinEthernet::ip, - MarlinEthernet::myDns, - MarlinEthernet::gateway, - MarlinEthernet::subnet; - -EthernetClient MarlinEthernet::telnetClient; // connected client - -MarlinEthernet ethernet; - -EthernetServer server(23); // telnet server - -enum linkStates { UNLINKED, LINKING, LINKED, CONNECTING, CONNECTED, NO_HARDWARE } linkState; - -#ifdef __IMXRT1062__ - - static void teensyMAC(uint8_t * const mac) { - const uint32_t m1 = HW_OCOTP_MAC1, m2 = HW_OCOTP_MAC0; - mac[0] = m1 >> 8; - mac[1] = m1 >> 0; - mac[2] = m2 >> 24; - mac[3] = m2 >> 16; - mac[4] = m2 >> 8; - mac[5] = m2 >> 0; - } - -#else - - byte mac[] = MAC_ADDRESS; - -#endif - -void ethernet_cable_error() { SERIAL_ERROR_MSG("Ethernet cable is not connected."); } - -void MarlinEthernet::init() { - if (!hardware_enabled) return; - - SERIAL_ECHO_MSG("Starting network..."); - - // Init the Ethernet device - #ifdef __IMXRT1062__ - uint8_t mac[6]; - teensyMAC(mac); - #endif - - if (!ip) { - Ethernet.begin(mac); // use DHCP - } - else { - if (!gateway) { - gateway = ip; - gateway[3] = 1; - myDns = gateway; - subnet = IPAddress(255,255,255,0); - } - if (!myDns) myDns = gateway; - if (!subnet) subnet = IPAddress(255,255,255,0); - Ethernet.begin(mac, ip, myDns, gateway, subnet); - } - - // Check for Ethernet hardware present - if (Ethernet.hardwareStatus() == EthernetNoHardware) { - SERIAL_ERROR_MSG("No Ethernet hardware found."); - linkState = NO_HARDWARE; - return; - } - - linkState = UNLINKED; - - if (Ethernet.linkStatus() == LinkOFF) - ethernet_cable_error(); -} - -void MarlinEthernet::check() { - if (!hardware_enabled) return; - - switch (linkState) { - case NO_HARDWARE: - break; - - case UNLINKED: - if (Ethernet.linkStatus() == LinkOFF) break; - - SERIAL_ECHOLNPGM("Ethernet cable connected"); - server.begin(); - linkState = LINKING; - break; - - case LINKING: - if (!Ethernet.localIP()) break; - - SERIAL_ECHOPGM("Successfully started telnet server with IP "); - MYSERIAL1.println(Ethernet.localIP()); - - linkState = LINKED; - break; - - case LINKED: - if (Ethernet.linkStatus() == LinkOFF) { - ethernet_cable_error(); - linkState = UNLINKED; - break; - } - telnetClient = server.accept(); - if (telnetClient) linkState = CONNECTING; - break; - - case CONNECTING: - telnetClient.println("Marlin " SHORT_BUILD_VERSION); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) - telnetClient.println( - " Last Updated: " STRING_DISTRIBUTION_DATE - " | Author: " STRING_CONFIG_H_AUTHOR - ); - #endif - telnetClient.println(" Compiled: " __DATE__); - - SERIAL_ECHOLNPGM("Client connected"); - have_telnet_client = true; - linkState = CONNECTED; - break; - - case CONNECTED: - if (telnetClient && !telnetClient.connected()) { - SERIAL_ECHOLNPGM("Client disconnected"); - telnetClient.stop(); - have_telnet_client = false; - linkState = LINKED; - } - if (Ethernet.linkStatus() == LinkOFF) { - ethernet_cable_error(); - if (telnetClient) telnetClient.stop(); - linkState = UNLINKED; - } - break; - - default: break; - } -} - -#endif // HAS_ETHERNET diff --git a/src/feature/ethernet.h b/src/feature/ethernet.h deleted file mode 100644 index 70a58ef..0000000 --- a/src/feature/ethernet.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#ifdef __IMXRT1062__ - #include -#endif - -// Teensy 4.1 uses internal MAC Address - -class MarlinEthernet { - public: - static bool hardware_enabled, have_telnet_client; - static IPAddress ip, myDns, gateway, subnet; - static EthernetClient telnetClient; - static void init(); - static void check(); -}; - -extern MarlinEthernet ethernet; diff --git a/src/feature/fancheck.cpp b/src/feature/fancheck.cpp deleted file mode 100644 index 126b79b..0000000 --- a/src/feature/fancheck.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * fancheck.cpp - fan tachometer check - */ - -#include "../inc/MarlinConfig.h" - -#if HAS_FANCHECK - -#include "fancheck.h" -#include "../module/temperature.h" - -#if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 && DISABLED(FOURWIRES_FANS) - bool FanCheck::measuring = false; -#endif -Flags FanCheck::tacho_state; -uint16_t FanCheck::edge_counter[TACHO_COUNT]; -uint8_t FanCheck::rps[TACHO_COUNT]; -FanCheck::TachoError FanCheck::error = FanCheck::TachoError::NONE; -bool FanCheck::enabled; - -void FanCheck::init() { - #define _TACHINIT(N) TERN(E##N##_FAN_TACHO_PULLUP, SET_INPUT_PULLUP, TERN(E##N##_FAN_TACHO_PULLDOWN, SET_INPUT_PULLDOWN, SET_INPUT))(E##N##_FAN_TACHO_PIN) - #if HAS_E0_FAN_TACHO - _TACHINIT(0); - #endif - #if HAS_E1_FAN_TACHO - _TACHINIT(1); - #endif - #if HAS_E2_FAN_TACHO - _TACHINIT(2); - #endif - #if HAS_E3_FAN_TACHO - _TACHINIT(3); - #endif - #if HAS_E4_FAN_TACHO - _TACHINIT(4); - #endif - #if HAS_E5_FAN_TACHO - _TACHINIT(5); - #endif - #if HAS_E6_FAN_TACHO - _TACHINIT(6); - #endif - #if HAS_E7_FAN_TACHO - _TACHINIT(7); - #endif -} - -void FanCheck::update_tachometers() { - bool status; - - #define _TACHO_CASE(N) case N: status = READ(E##N##_FAN_TACHO_PIN); break; - LOOP_L_N(f, TACHO_COUNT) { - switch (f) { - #if HAS_E0_FAN_TACHO - _TACHO_CASE(0) - #endif - #if HAS_E1_FAN_TACHO - _TACHO_CASE(1) - #endif - #if HAS_E2_FAN_TACHO - _TACHO_CASE(2) - #endif - #if HAS_E3_FAN_TACHO - _TACHO_CASE(3) - #endif - #if HAS_E4_FAN_TACHO - _TACHO_CASE(4) - #endif - #if HAS_E5_FAN_TACHO - _TACHO_CASE(5) - #endif - #if HAS_E6_FAN_TACHO - _TACHO_CASE(6) - #endif - #if HAS_E7_FAN_TACHO - _TACHO_CASE(7) - #endif - default: continue; - } - - if (status != tacho_state[f]) { - if (measuring) ++edge_counter[f]; - tacho_state.set(f, status); - } - } -} - -void FanCheck::compute_speed(uint16_t elapsedTime) { - static uint8_t errors_count[TACHO_COUNT]; - static uint8_t fan_reported_errors_msk = 0; - - uint8_t fan_error_msk = 0; - LOOP_L_N(f, TACHO_COUNT) { - switch (f) { - TERN_(HAS_E0_FAN_TACHO, case 0:) - TERN_(HAS_E1_FAN_TACHO, case 1:) - TERN_(HAS_E2_FAN_TACHO, case 2:) - TERN_(HAS_E3_FAN_TACHO, case 3:) - TERN_(HAS_E4_FAN_TACHO, case 4:) - TERN_(HAS_E5_FAN_TACHO, case 5:) - TERN_(HAS_E6_FAN_TACHO, case 6:) - TERN_(HAS_E7_FAN_TACHO, case 7:) - // Compute fan speed - rps[f] = edge_counter[f] * float(250) / elapsedTime; - edge_counter[f] = 0; - - // Check fan speed - constexpr int8_t max_extruder_fan_errors = TERN(HAS_PWMFANCHECK, 10000, 5000) / Temperature::fan_update_interval_ms; - - if (rps[f] >= 20 || TERN0(HAS_AUTO_FAN, thermalManager.autofan_speed[f] == 0)) - errors_count[f] = 0; - else if (errors_count[f] < max_extruder_fan_errors) - ++errors_count[f]; - else if (enabled) - SBI(fan_error_msk, f); - break; - } - } - - // Drop the error when all fans are ok - if (!fan_error_msk && error == TachoError::REPORTED) error = TachoError::FIXED; - - if (error == TachoError::FIXED && !printJobOngoing() && !printingIsPaused()) { - error = TachoError::NONE; // if the issue has been fixed while the printer is idle, reenable immediately - ui.reset_alert_level(); - } - - if (fan_error_msk & ~fan_reported_errors_msk) { - // Handle new faults only - LOOP_L_N(f, TACHO_COUNT) if (TEST(fan_error_msk, f)) report_speed_error(f); - } - fan_reported_errors_msk = fan_error_msk; -} - -void FanCheck::report_speed_error(uint8_t fan) { - if (printJobOngoing()) { - if (error == TachoError::NONE) { - if (thermalManager.degTargetHotend(fan) != 0) { - kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT)); - error = TachoError::REPORTED; - } - else - error = TachoError::DETECTED; // Plans error for next processed command - } - } - else if (!printingIsPaused()) { - thermalManager.setTargetHotend(0, fan); // Always disable heating - if (error == TachoError::NONE) error = TachoError::REPORTED; - } - - SERIAL_ERROR_MSG(STR_ERR_FANSPEED, fan); - LCD_ALERTMESSAGE(MSG_FAN_SPEED_FAULT); -} - -void FanCheck::print_fan_states() { - LOOP_L_N(s, 2) { - LOOP_L_N(f, TACHO_COUNT) { - switch (f) { - TERN_(HAS_E0_FAN_TACHO, case 0:) - TERN_(HAS_E1_FAN_TACHO, case 1:) - TERN_(HAS_E2_FAN_TACHO, case 2:) - TERN_(HAS_E3_FAN_TACHO, case 3:) - TERN_(HAS_E4_FAN_TACHO, case 4:) - TERN_(HAS_E5_FAN_TACHO, case 5:) - TERN_(HAS_E6_FAN_TACHO, case 6:) - TERN_(HAS_E7_FAN_TACHO, case 7:) - SERIAL_ECHOPGM("E", f); - if (s == 0) - SERIAL_ECHOPGM(":", 60 * rps[f], " RPM "); - else - SERIAL_ECHOPGM("@:", TERN(HAS_AUTO_FAN, thermalManager.autofan_speed[f], 255), " "); - break; - } - } - } - SERIAL_EOL(); -} - -#if ENABLED(AUTO_REPORT_FANS) - AutoReporter FanCheck::auto_reporter; - void FanCheck::AutoReportFan::report() { print_fan_states(); } -#endif - -#endif // HAS_FANCHECK diff --git a/src/feature/fancheck.h b/src/feature/fancheck.h deleted file mode 100644 index b13a34f..0000000 --- a/src/feature/fancheck.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#if HAS_FANCHECK - -#include "../MarlinCore.h" -#include "../lcd/marlinui.h" - -#if ENABLED(AUTO_REPORT_FANS) - #include "../libs/autoreport.h" -#endif - -#if ENABLED(PARK_HEAD_ON_PAUSE) - #include "../gcode/queue.h" -#endif - -/** - * fancheck.h - */ -#define TACHO_COUNT TERN(HAS_E7_FAN_TACHO, 8, TERN(HAS_E6_FAN_TACHO, 7, TERN(HAS_E5_FAN_TACHO, 6, TERN(HAS_E4_FAN_TACHO, 5, TERN(HAS_E3_FAN_TACHO, 4, TERN(HAS_E2_FAN_TACHO, 3, TERN(HAS_E1_FAN_TACHO, 2, 1))))))) - -class FanCheck { - private: - - enum class TachoError : uint8_t { NONE, DETECTED, REPORTED, FIXED }; - - #if HAS_PWMFANCHECK - static bool measuring; // For future use (3 wires PWM controlled fans) - #else - static constexpr bool measuring = true; - #endif - static Flags tacho_state; - static uint16_t edge_counter[TACHO_COUNT]; - static uint8_t rps[TACHO_COUNT]; - static TachoError error; - - static void report_speed_error(uint8_t fan); - - public: - - static bool enabled; - - static void init(); - static void update_tachometers(); - static void compute_speed(uint16_t elapsedTime); - static void print_fan_states(); - #if HAS_PWMFANCHECK - static void toggle_measuring() { measuring = !measuring; } - static bool is_measuring() { return measuring; } - #endif - - static void check_deferred_error() { - if (error == TachoError::DETECTED) { - error = TachoError::REPORTED; - TERN(PARK_HEAD_ON_PAUSE, queue.inject(F("M125")), kill(GET_TEXT_F(MSG_FAN_SPEED_FAULT))); - } - } - - #if ENABLED(AUTO_REPORT_FANS) - struct AutoReportFan { static void report(); }; - static AutoReporter auto_reporter; - #endif -}; - -extern FanCheck fan_check; - -#endif // HAS_FANCHECK diff --git a/src/feature/fanmux.cpp b/src/feature/fanmux.cpp deleted file mode 100644 index 43952ca..0000000 --- a/src/feature/fanmux.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/pause.cpp - Pause feature support functions - * This may be combined with related G-codes if features are consolidated. - */ - -#include "../inc/MarlinConfig.h" - -#if HAS_FANMUX - -#include "fanmux.h" - -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_PIN, TEST(e, 2) ? HIGH : LOW); - #endif - #endif -} - -void fanmux_init() { - 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 diff --git a/src/feature/fanmux.h b/src/feature/fanmux.h deleted file mode 100644 index efb92cf..0000000 --- a/src/feature/fanmux.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/fanmux.h - Cooling Fan Multiplexer support functions - */ - -void fanmux_switch(const uint8_t e); -void fanmux_init(); diff --git a/src/feature/filwidth.cpp b/src/feature/filwidth.cpp deleted file mode 100644 index 2bd9c78..0000000 --- a/src/feature/filwidth.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - -#include "filwidth.h" - -FilamentWidthSensor filwidth; - -bool FilamentWidthSensor::enabled; // = false; // (M405-M406) Filament Width Sensor ON/OFF. -uint32_t FilamentWidthSensor::accum; // = 0 // ADC accumulator -uint16_t FilamentWidthSensor::raw; // = 0 // Measured filament diameter - one extruder only -float FilamentWidthSensor::nominal_mm = DEFAULT_NOMINAL_FILAMENT_DIA, // (M104) Nominal filament width - FilamentWidthSensor::measured_mm = DEFAULT_MEASURED_FILAMENT_DIA, // Measured filament diameter - FilamentWidthSensor::e_count = 0, - FilamentWidthSensor::delay_dist = 0; -uint8_t FilamentWidthSensor::meas_delay_cm = MEASUREMENT_DELAY_CM; // Distance delay setting -int8_t FilamentWidthSensor::ratios[MAX_MEASUREMENT_DELAY + 1], // Ring buffer to delay measurement. (Extruder factor minus 100) - FilamentWidthSensor::index_r, // Indexes into ring buffer - FilamentWidthSensor::index_w; - -void FilamentWidthSensor::init() { - const int8_t ratio = sample_to_size_ratio(); - LOOP_L_N(i, COUNT(ratios)) ratios[i] = ratio; - index_r = index_w = 0; -} - -#endif // FILAMENT_WIDTH_SENSOR diff --git a/src/feature/filwidth.h b/src/feature/filwidth.h deleted file mode 100644 index 9eb1e77..0000000 --- a/src/feature/filwidth.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" -#include "../module/planner.h" -#include "../module/thermistor/thermistors.h" - -class FilamentWidthSensor { -public: - static constexpr int MMD_CM = MAX_MEASUREMENT_DELAY + 1, MMD_MM = MMD_CM * 10; - static bool enabled; // (M405-M406) Filament Width Sensor ON/OFF. - static uint32_t accum; // ADC accumulator - static uint16_t raw; // Measured filament diameter - one extruder only - static float nominal_mm, // (M104) Nominal filament width - measured_mm, // Measured filament diameter - e_count, delay_dist; - static uint8_t meas_delay_cm; // Distance delay setting - static int8_t ratios[MMD_CM], // Ring buffer to delay measurement. (Extruder factor minus 100) - index_r, index_w; // Indexes into ring buffer - - FilamentWidthSensor() { init(); } - static void init(); - - static void enable(const bool ena) { enabled = ena; } - - static void set_delay_cm(const uint8_t cm) { - meas_delay_cm = _MIN(cm, MAX_MEASUREMENT_DELAY); - } - - /** - * Convert Filament Width (mm) to an extrusion ratio - * and reduce to an 8 bit value. - * - * A nominal width of 1.75 and measured width of 1.73 - * gives (100 * 1.75 / 1.73) for a ratio of 101 and - * a return value of 1. - */ - static int8_t sample_to_size_ratio() { - return ABS(nominal_mm - measured_mm) <= FILWIDTH_ERROR_MARGIN - ? int(100.0f * nominal_mm / measured_mm) - 100 : 0; - } - - // Apply a single ADC reading to the raw value - static void accumulate(const uint16_t adc) { - if (adc > 102) // Ignore ADC under 0.5 volts - accum += (uint32_t(adc) << 7) - (accum >> 7); - } - - // Convert raw measurement to mm - static float raw_to_mm(const uint16_t v) { return v * float(ADC_VREF) * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); } - static float raw_to_mm() { return raw_to_mm(raw); } - - // A scaled reading is ready - // Divide to get to 0-16384 range since we used 1/128 IIR filter approach - static void reading_ready() { raw = accum >> 10; } - - // Update mm from the raw measurement - static void update_measured_mm() { measured_mm = raw_to_mm(); } - - // Update ring buffer used to delay filament measurements - static void advance_e(const_float_t e_move) { - - // Increment counters with the E distance - e_count += e_move; - delay_dist += e_move; - - // Only get new measurements on forward E movement - if (!UNEAR_ZERO(e_count)) { - - // Loop the delay distance counter (modulus by the mm length) - while (delay_dist >= MMD_MM) delay_dist -= MMD_MM; - - // Convert into an index (cm) into the measurement array - index_r = int8_t(delay_dist * 0.1f); - - // If the ring buffer is not full... - if (index_r != index_w) { - e_count = 0; // Reset the E movement counter - const int8_t meas_sample = sample_to_size_ratio(); - do { - if (++index_w >= MMD_CM) index_w = 0; // The next unused slot - ratios[index_w] = meas_sample; // Store the measurement - } while (index_r != index_w); // More slots to fill? - } - } - } - - // Dynamically set the volumetric multiplier based on the delayed width measurement. - static void update_volumetric() { - if (enabled) { - int8_t read_index = index_r - meas_delay_cm; - if (read_index < 0) read_index += MMD_CM; // Loop around buffer if needed - LIMIT(read_index, 0, MAX_MEASUREMENT_DELAY); - planner.apply_filament_width_sensor(ratios[read_index]); - } - } - -}; - -extern FilamentWidthSensor filwidth; diff --git a/src/feature/fwretract.cpp b/src/feature/fwretract.cpp deleted file mode 100644 index 2835564..0000000 --- a/src/feature/fwretract.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * fwretract.cpp - Implement firmware-based retraction - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(FWRETRACT) - -#include "fwretract.h" - -FWRetract fwretract; // Single instance - this calls the constructor - -#include "../module/motion.h" -#include "../module/planner.h" - -#include "../gcode/gcode.h" - -#if ENABLED(RETRACT_SYNC_MIXING) - #include "mixing.h" -#endif - -// private: - -#if HAS_MULTI_EXTRUDER - Flags FWRetract::retracted_swap; // Which extruders are swap-retracted -#endif - -// public: - -fwretract_settings_t FWRetract::settings; // M207 S F Z W, M208 S F W R - -#if ENABLED(FWRETRACT_AUTORETRACT) - bool FWRetract::autoretract_enabled; // M209 S - Autoretract switch -#endif - -Flags FWRetract::retracted; // Which extruders are currently retracted - -float FWRetract::current_retract[EXTRUDERS], // Retract value used by planner - FWRetract::current_hop; - -void FWRetract::reset() { - TERN_(FWRETRACT_AUTORETRACT, autoretract_enabled = false); - settings.retract_length = RETRACT_LENGTH; - settings.retract_feedrate_mm_s = RETRACT_FEEDRATE; - settings.retract_zraise = RETRACT_ZRAISE; - settings.retract_recover_extra = RETRACT_RECOVER_LENGTH; - settings.retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE; - settings.swap_retract_length = RETRACT_LENGTH_SWAP; - settings.swap_retract_recover_extra = RETRACT_RECOVER_LENGTH_SWAP; - settings.swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; - current_hop = 0.0; - - retracted.reset(); - EXTRUDER_LOOP() { - E_TERN_(retracted_swap.clear(e)); - current_retract[e] = 0.0; - } -} - -/** - * 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: 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 FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) { - // Prevent two retracts or recovers in a row - if (retracted[active_extruder] == retracting) return; - - // Prevent two swap-retract or recovers in a row - #if HAS_MULTI_EXTRUDER - // Allow G10 S1 only after G11 - if (swapping && retracted_swap[active_extruder] == retracting) return; - // G11 priority to recover the long retract if activated - if (!retracting) swapping = retracted_swap[active_extruder]; - #else - constexpr bool swapping = false; - #endif - - /* // debugging - SERIAL_ECHOLNPGM( - "retracting ", AS_DIGIT(retracting), - " swapping ", swapping, - " active extruder ", active_extruder - ); - EXTRUDER_LOOP() { - SERIAL_ECHOLNPGM("retracted[", e, "] ", AS_DIGIT(retracted[e])); - #if HAS_MULTI_EXTRUDER - SERIAL_ECHOLNPGM("retracted_swap[", e, "] ", AS_DIGIT(retracted_swap[e])); - #endif - } - SERIAL_ECHOLNPGM("current_position.z ", current_position.z); - SERIAL_ECHOLNPGM("current_position.e ", current_position.e); - SERIAL_ECHOLNPGM("current_hop ", current_hop); - //*/ - - const float base_retract = TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) - * (swapping ? settings.swap_retract_length : settings.retract_length); - - // The current position will be the destination for E and Z moves - destination = current_position; - - #if ENABLED(RETRACT_SYNC_MIXING) - const uint8_t old_mixing_tool = mixer.get_current_vtool(); - mixer.T(MIXER_AUTORETRACT_TOOL); - #endif - - const feedRate_t fr_max_z = planner.settings.max_feedrate_mm_s[Z_AXIS]; - if (retracting) { - // Retract by moving from a faux E position back to the current E position - current_retract[active_extruder] = base_retract; - prepare_internal_move_to_destination( // set current from destination - settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) - ); - - // Is a Z hop set, and has the hop not yet been done? - if (!current_hop && settings.retract_zraise > 0.01f) { // Apply hop only once - current_hop += settings.retract_zraise; // Add to the hop total (again, only once) - // Raise up, set_current_to_destination. Maximum Z feedrate - prepare_internal_move_to_destination(fr_max_z); - } - } - else { - // If a hop was done and Z hasn't changed, undo the Z hop - if (current_hop) { - current_hop = 0; - // Lower Z, set_current_to_destination. Maximum Z feedrate - prepare_internal_move_to_destination(fr_max_z); - } - - const float extra_recover = swapping ? settings.swap_retract_recover_extra : settings.retract_recover_extra; - if (extra_recover) { - current_position.e -= extra_recover; // Adjust the current E position by the extra amount to recover - sync_plan_position_e(); // Sync the planner position so the extra amount is recovered - } - - current_retract[active_extruder] = 0; - - // Recover E, set_current_to_destination - prepare_internal_move_to_destination( - (swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s) - * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) - ); - } - - TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool - - retracted.set(active_extruder, retracting); // Active extruder now retracted / recovered - - // If swap retract/recover update the retracted_swap flag too - #if HAS_MULTI_EXTRUDER - if (swapping) retracted_swap.set(active_extruder, retracting); - #endif - - /* // debugging - SERIAL_ECHOLNPGM("retracting ", AS_DIGIT(retracting)); - SERIAL_ECHOLNPGM("swapping ", AS_DIGIT(swapping)); - SERIAL_ECHOLNPGM("active_extruder ", active_extruder); - EXTRUDER_LOOP() { - SERIAL_ECHOLNPGM("retracted[", e, "] ", AS_DIGIT(retracted[e])); - #if HAS_MULTI_EXTRUDER - SERIAL_ECHOLNPGM("retracted_swap[", e, "] ", AS_DIGIT(retracted_swap[e])); - #endif - } - SERIAL_ECHOLNPGM("current_position.z ", current_position.z); - SERIAL_ECHOLNPGM("current_position.e ", current_position.e); - SERIAL_ECHOLNPGM("current_hop ", current_hop); - //*/ -} - -//extern const char SP_Z_STR[]; - -/** - * 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_zraise - */ -void FWRetract::M207() { - if (!parser.seen("FSWZ")) return M207_report(); - if (parser.seenval('S')) settings.retract_length = parser.value_axis_units(E_AXIS); - if (parser.seenval('F')) settings.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); - if (parser.seenval('Z')) settings.retract_zraise = parser.value_linear_units(); - if (parser.seenval('W')) settings.swap_retract_length = parser.value_axis_units(E_AXIS); -} - -void FWRetract::M207_report() { - SERIAL_ECHOLNPGM_P( - PSTR(" M207 S"), LINEAR_UNIT(settings.retract_length) - , PSTR(" W"), LINEAR_UNIT(settings.swap_retract_length) - , PSTR(" F"), LINEAR_UNIT(MMS_TO_MMM(settings.retract_feedrate_mm_s)) - , SP_Z_STR, LINEAR_UNIT(settings.retract_zraise) - ); -} - -/** - * M208: Set firmware un-retraction values - * - * S[+units] retract_recover_extra (in addition to M207 S*) - * W[+units] swap_retract_recover_extra (multi-extruder) - * F[units/min] retract_recover_feedrate_mm_s - * R[units/min] swap_retract_recover_feedrate_mm_s - */ -void FWRetract::M208() { - if (!parser.seen("FSRW")) return M208_report(); - if (parser.seen('S')) settings.retract_recover_extra = parser.value_axis_units(E_AXIS); - if (parser.seen('F')) settings.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); - if (parser.seen('R')) settings.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); - if (parser.seen('W')) settings.swap_retract_recover_extra = parser.value_axis_units(E_AXIS); -} - -void FWRetract::M208_report() { - SERIAL_ECHOLNPGM( - " M208 S", LINEAR_UNIT(settings.retract_recover_extra) - , " W", LINEAR_UNIT(settings.swap_retract_recover_extra) - , " F", LINEAR_UNIT(MMS_TO_MMM(settings.retract_recover_feedrate_mm_s)) - ); -} - -#if ENABLED(FWRETRACT_AUTORETRACT) - - /** - * M209: Enable automatic retract (M209 S1) - * For slicers that don't support G10/11, reversed extrude-only - * moves will be classified as retraction. - */ - void FWRetract::M209() { - if (!parser.seen('S')) return M209_report(); - if (MIN_AUTORETRACT <= MAX_AUTORETRACT) - enable_autoretract(parser.value_bool()); - } - - void FWRetract::M209_report() { - SERIAL_ECHOLNPGM(" M209 S", AS_DIGIT(autoretract_enabled)); - } - -#endif // FWRETRACT_AUTORETRACT - - -#endif // FWRETRACT diff --git a/src/feature/fwretract.h b/src/feature/fwretract.h deleted file mode 100644 index db2a62c..0000000 --- a/src/feature/fwretract.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * fwretract.h - Define firmware-based retraction interface - */ - -#include "../inc/MarlinConfigPre.h" - -typedef struct { - float retract_length; // M207 S - G10 Retract length - feedRate_t retract_feedrate_mm_s; // M207 F - G10 Retract feedrate - float retract_zraise, // M207 Z - G10 Retract hop size - retract_recover_extra; // M208 S - G11 Recover length - feedRate_t retract_recover_feedrate_mm_s; // M208 F - G11 Recover feedrate - float swap_retract_length, // M207 W - G10 Swap Retract length - swap_retract_recover_extra; // M208 W - G11 Swap Recover length - feedRate_t swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate -} fwretract_settings_t; - -#if ENABLED(FWRETRACT) - -class FWRetract { -private: - #if HAS_MULTI_EXTRUDER - static Flags retracted_swap; // Which extruders are swap-retracted - #endif - -public: - static fwretract_settings_t settings; - - #if ENABLED(FWRETRACT_AUTORETRACT) - static bool autoretract_enabled; // M209 S - Autoretract switch - #else - static constexpr bool autoretract_enabled = false; - #endif - - static Flags retracted; // Which extruders are currently retracted - static float current_retract[EXTRUDERS], // Retract value used by planner - current_hop; // Hop value used by planner - - FWRetract() { reset(); } - - static void reset(); - - static void refresh_autoretract() { retracted.reset(); } - - static void enable_autoretract(const bool enable) { - #if ENABLED(FWRETRACT_AUTORETRACT) - autoretract_enabled = enable; - refresh_autoretract(); - #endif - } - - static void retract(const bool retracting E_OPTARG(bool swapping=false)); - - static void M207_report(); - static void M207(); - static void M208_report(); - static void M208(); - #if ENABLED(FWRETRACT_AUTORETRACT) - static void M209_report(); - static void M209(); - #endif -}; - -extern FWRetract fwretract; - -#endif // FWRETRACT diff --git a/src/feature/host_actions.cpp b/src/feature/host_actions.cpp deleted file mode 100644 index c03a6bc..0000000 --- a/src/feature/host_actions.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(HOST_ACTION_COMMANDS) - -//#define DEBUG_HOST_ACTIONS - -#include "host_actions.h" - -#if ENABLED(ADVANCED_PAUSE_FEATURE) - #include "pause.h" - #include "../gcode/queue.h" -#endif - -#if HAS_FILAMENT_SENSOR - #include "runout.h" -#endif - -HostUI hostui; - -void HostUI::action(FSTR_P const fstr, const bool eol) { - PORT_REDIRECT(SerialMask::All); - SERIAL_ECHOPGM("//action:"); - SERIAL_ECHOF(fstr); - if (eol) SERIAL_EOL(); -} - -#ifdef ACTION_ON_KILL - void HostUI::kill() { action(F(ACTION_ON_KILL)); } -#endif -#ifdef ACTION_ON_PAUSE - void HostUI::pause(const bool eol/*=true*/) { action(F(ACTION_ON_PAUSE), eol); } -#endif -#ifdef ACTION_ON_PAUSED - void HostUI::paused(const bool eol/*=true*/) { action(F(ACTION_ON_PAUSED), eol); } -#endif -#ifdef ACTION_ON_RESUME - void HostUI::resume() { action(F(ACTION_ON_RESUME)); } -#endif -#ifdef ACTION_ON_RESUMED - void HostUI::resumed() { action(F(ACTION_ON_RESUMED)); } -#endif -#ifdef ACTION_ON_CANCEL - void HostUI::cancel() { action(F(ACTION_ON_CANCEL)); } -#endif -#ifdef ACTION_ON_START - void HostUI::start() { action(F(ACTION_ON_START)); } -#endif - -#if ENABLED(G29_RETRY_AND_RECOVER) - #ifdef ACTION_ON_G29_RECOVER - void HostUI::g29_recover() { action(F(ACTION_ON_G29_RECOVER)); } - #endif - #ifdef ACTION_ON_G29_FAILURE - void HostUI::g29_failure() { action(F(ACTION_ON_G29_FAILURE)); } - #endif -#endif - -#ifdef SHUTDOWN_ACTION - void HostUI::shutdown() { action(F(SHUTDOWN_ACTION)); } -#endif - -#if ENABLED(HOST_PROMPT_SUPPORT) - - PromptReason HostUI::host_prompt_reason = PROMPT_NOT_DEFINED; - - PGMSTR(CONTINUE_STR, "Continue"); - PGMSTR(DISMISS_STR, "Dismiss"); - - #if HAS_RESUME_CONTINUE - extern bool wait_for_user; - #endif - - void HostUI::notify(const char * const cstr) { - PORT_REDIRECT(SerialMask::All); - action(F("notification "), false); - SERIAL_ECHOLN(cstr); - } - - void HostUI::notify_P(PGM_P const pstr) { - PORT_REDIRECT(SerialMask::All); - action(F("notification "), false); - SERIAL_ECHOLNPGM_P(pstr); - } - - void HostUI::prompt(FSTR_P const ptype, const bool eol/*=true*/) { - PORT_REDIRECT(SerialMask::All); - action(F("prompt_"), false); - SERIAL_ECHOF(ptype); - if (eol) SERIAL_EOL(); - } - - void HostUI::prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char/*='\0'*/) { - prompt(ptype, false); - PORT_REDIRECT(SerialMask::All); - SERIAL_CHAR(' '); - SERIAL_ECHOF(fstr); - if (extra_char != '\0') SERIAL_CHAR(extra_char); - SERIAL_EOL(); - } - void HostUI::prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char/*='\0'*/) { - prompt_end(); - host_prompt_reason = reason; - prompt_plus(F("begin"), fstr, extra_char); - } - void HostUI::prompt_button(FSTR_P const fstr) { prompt_plus(F("button"), fstr); } - void HostUI::prompt_end() { prompt(F("end")); } - void HostUI::prompt_show() { prompt(F("show")); } - - void HostUI::_prompt_show(FSTR_P const btn1, FSTR_P const btn2) { - if (btn1) prompt_button(btn1); - if (btn2) prompt_button(btn2); - prompt_show(); - } - void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) { - prompt_begin(reason, fstr); - _prompt_show(btn1, btn2); - } - void HostUI::prompt_do(const PromptReason reason, FSTR_P const fstr, const char extra_char, FSTR_P const btn1/*=nullptr*/, FSTR_P const btn2/*=nullptr*/) { - prompt_begin(reason, fstr, extra_char); - _prompt_show(btn1, btn2); - } - - #if ENABLED(ADVANCED_PAUSE_FEATURE) - void HostUI::filament_load_prompt() { - const bool disable_to_continue = TERN0(HAS_FILAMENT_SENSOR, runout.filament_ran_out); - prompt_do(PROMPT_FILAMENT_RUNOUT, F("Paused"), F("PurgeMore"), - disable_to_continue ? F("DisableRunout") : FPSTR(CONTINUE_STR) - ); - } - #endif - - // - // Handle responses from the host, such as: - // - Filament runout responses: Purge More, Continue - // - General "Continue" response - // - Resume Print response - // - Dismissal of info - // - void HostUI::handle_response(const uint8_t response) { - const PromptReason hpr = host_prompt_reason; - host_prompt_reason = PROMPT_NOT_DEFINED; // Reset now ahead of logic - switch (hpr) { - case PROMPT_FILAMENT_RUNOUT: - switch (response) { - - case 0: // "Purge More" button - #if BOTH(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE) - pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // Simulate menu selection (menu exits, doesn't extrude more) - #endif - break; - - case 1: // "Continue" / "Disable Runout" button - #if BOTH(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE) - pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // Simulate menu selection - #endif - #if HAS_FILAMENT_SENSOR - if (runout.filament_ran_out) { // Disable a triggered sensor - runout.enabled = false; - runout.reset(); - } - #endif - break; - } - break; - case PROMPT_USER_CONTINUE: - TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); - break; - case PROMPT_PAUSE_RESUME: - #if BOTH(ADVANCED_PAUSE_FEATURE, SDSUPPORT) - extern const char M24_STR[]; - queue.inject_P(M24_STR); - #endif - break; - case PROMPT_INFO: - break; - default: break; - } - } - -#endif // HOST_PROMPT_SUPPORT - -#endif // HOST_ACTION_COMMANDS diff --git a/src/feature/host_actions.h b/src/feature/host_actions.h deleted file mode 100644 index 41d66b8..0000000 --- a/src/feature/host_actions.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" -#include "../HAL/shared/Marduino.h" - -#if ENABLED(HOST_PROMPT_SUPPORT) - - enum PromptReason : uint8_t { - PROMPT_NOT_DEFINED, - PROMPT_FILAMENT_RUNOUT, - PROMPT_USER_CONTINUE, - PROMPT_FILAMENT_RUNOUT_REHEAT, - PROMPT_PAUSE_RESUME, - PROMPT_INFO - }; - -#endif - -class HostUI { - public: - - static void action(FSTR_P const fstr, const bool eol=true); - - #ifdef ACTION_ON_KILL - static void kill(); - #endif - #ifdef ACTION_ON_PAUSE - static void pause(const bool eol=true); - #endif - #ifdef ACTION_ON_PAUSED - static void paused(const bool eol=true); - #endif - #ifdef ACTION_ON_RESUME - static void resume(); - #endif - #ifdef ACTION_ON_RESUMED - static void resumed(); - #endif - #ifdef ACTION_ON_CANCEL - static void cancel(); - #endif - #ifdef ACTION_ON_START - static void start(); - #endif - #ifdef SHUTDOWN_ACTION - static void shutdown(); - #endif - - #if ENABLED(G29_RETRY_AND_RECOVER) - #ifdef ACTION_ON_G29_RECOVER - static void g29_recover(); - #endif - #ifdef ACTION_ON_G29_FAILURE - static void g29_failure(); - #endif - #endif - - #if ENABLED(HOST_PROMPT_SUPPORT) - private: - static void prompt(FSTR_P const ptype, const bool eol=true); - static void prompt_plus(FSTR_P const ptype, FSTR_P const fstr, const char extra_char='\0'); - static void prompt_show(); - static void _prompt_show(FSTR_P const btn1, FSTR_P const btn2); - - public: - static PromptReason host_prompt_reason; - - static void handle_response(const uint8_t response); - - static void notify_P(PGM_P const message); - static void notify(FSTR_P const fmsg) { notify_P(FTOP(fmsg)); } - static void notify(const char * const message); - - static void prompt_begin(const PromptReason reason, FSTR_P const fstr, const char extra_char='\0'); - static void prompt_button(FSTR_P const fstr); - static void prompt_end(); - static void prompt_do(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr); - static void prompt_do(const PromptReason reason, FSTR_P const pstr, const char extra_char, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr); - static void prompt_open(const PromptReason reason, FSTR_P const pstr, FSTR_P const btn1=nullptr, FSTR_P const btn2=nullptr) { - if (host_prompt_reason == PROMPT_NOT_DEFINED) prompt_do(reason, pstr, btn1, btn2); - } - - #if ENABLED(ADVANCED_PAUSE_FEATURE) - static void filament_load_prompt(); - #endif - - #endif - -}; - -extern HostUI hostui; - -extern const char CONTINUE_STR[], DISMISS_STR[]; diff --git a/src/feature/hotend_idle.cpp b/src/feature/hotend_idle.cpp deleted file mode 100644 index 4b137f4..0000000 --- a/src/feature/hotend_idle.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Hotend Idle Timeout - * Prevent filament in the nozzle from charring and causing a critical jam. - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(HOTEND_IDLE_TIMEOUT) - -#include "hotend_idle.h" -#include "../gcode/gcode.h" - -#include "../module/temperature.h" -#include "../module/motion.h" -#include "../module/planner.h" -#include "../lcd/marlinui.h" - -extern HotendIdleProtection hotend_idle; - -millis_t HotendIdleProtection::next_protect_ms = 0; - -void HotendIdleProtection::check_hotends(const millis_t &ms) { - bool do_prot = false; - HOTEND_LOOP() { - const bool busy = (TERN0(HAS_RESUME_CONTINUE, wait_for_user) || planner.has_blocks_queued()); - if (thermalManager.degHotend(e) >= (HOTEND_IDLE_MIN_TRIGGER) && !busy) { - do_prot = true; break; - } - } - if (bool(next_protect_ms) != do_prot) - next_protect_ms = do_prot ? ms + hp_interval : 0; -} - -void HotendIdleProtection::check_e_motion(const millis_t &ms) { - static float old_e_position = 0; - if (old_e_position != current_position.e) { - old_e_position = current_position.e; // Track filament motion - if (next_protect_ms) // If some heater is on then... - next_protect_ms = ms + hp_interval; // ...delay the timeout till later - } -} - -void HotendIdleProtection::check() { - const millis_t ms = millis(); // Shared millis - - check_hotends(ms); // Any hotends need protection? - check_e_motion(ms); // Motion will protect them - - // Hot and not moving for too long... - if (next_protect_ms && ELAPSED(ms, next_protect_ms)) - timed_out(); -} - -// Lower (but don't raise) hotend / bed temperatures -void HotendIdleProtection::timed_out() { - next_protect_ms = 0; - SERIAL_ECHOLNPGM("Hotend Idle Timeout"); - LCD_MESSAGE(MSG_HOTEND_IDLE_TIMEOUT); - HOTEND_LOOP() { - if ((HOTEND_IDLE_NOZZLE_TARGET) < thermalManager.degTargetHotend(e)) - thermalManager.setTargetHotend(HOTEND_IDLE_NOZZLE_TARGET, e); - } - #if HAS_HEATED_BED - if ((HOTEND_IDLE_BED_TARGET) < thermalManager.degTargetBed()) - thermalManager.setTargetBed(HOTEND_IDLE_BED_TARGET); - #endif -} - -#endif // HOTEND_IDLE_TIMEOUT diff --git a/src/feature/hotend_idle.h b/src/feature/hotend_idle.h deleted file mode 100644 index 40f557d..0000000 --- a/src/feature/hotend_idle.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../core/millis_t.h" - -class HotendIdleProtection { -public: - static void check(); -private: - static constexpr millis_t hp_interval = SEC_TO_MS(HOTEND_IDLE_TIMEOUT_SEC); - static millis_t next_protect_ms; - static void check_hotends(const millis_t &ms); - static void check_e_motion(const millis_t &ms); - static void timed_out(); -}; - -extern HotendIdleProtection hotend_idle; diff --git a/src/feature/joystick.cpp b/src/feature/joystick.cpp deleted file mode 100644 index acab5d7..0000000 --- a/src/feature/joystick.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * joystick.cpp - joystick input / jogging - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(JOYSTICK) - -#include "joystick.h" - -#include "../inc/MarlinConfig.h" // for pins -#include "../module/planner.h" - -Joystick joystick; - -#if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extui/ui_api.h" -#endif - -#if HAS_JOY_ADC_X - temp_info_t Joystick::x; // = { 0 } - #if ENABLED(INVERT_JOY_X) - #define JOY_X(N) (16383 - (N)) - #else - #define JOY_X(N) (N) - #endif -#endif -#if HAS_JOY_ADC_Y - temp_info_t Joystick::y; // = { 0 } - #if ENABLED(INVERT_JOY_Y) - #define JOY_Y(N) (16383 - (N)) - #else - #define JOY_Y(N) (N) - #endif -#endif -#if HAS_JOY_ADC_Z - temp_info_t Joystick::z; // = { 0 } - #if ENABLED(INVERT_JOY_Z) - #define JOY_Z(N) (16383 - (N)) - #else - #define JOY_Z(N) (N) - #endif -#endif - -#if ENABLED(JOYSTICK_DEBUG) - void Joystick::report() { - SERIAL_ECHOPGM("Joystick"); - #if HAS_JOY_ADC_X - SERIAL_ECHOPGM_P(SP_X_STR, JOY_X(x.getraw())); - #endif - #if HAS_JOY_ADC_Y - SERIAL_ECHOPGM_P(SP_Y_STR, JOY_Y(y.getraw())); - #endif - #if HAS_JOY_ADC_Z - SERIAL_ECHOPGM_P(SP_Z_STR, JOY_Z(z.getraw())); - #endif - #if HAS_JOY_ADC_EN - SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)"); - #endif - SERIAL_EOL(); - } -#endif - -#if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z - - void Joystick::calculate(xyz_float_t &norm_jog) { - // Do nothing if enable pin (active-low) is not LOW - #if HAS_JOY_ADC_EN - if (READ(JOY_EN_PIN)) return; - #endif - - auto _normalize_joy = [](float &axis_jog, const raw_adc_t raw, const raw_adc_t (&joy_limits)[4]) { - if (WITHIN(raw, joy_limits[0], joy_limits[3])) { - // within limits, check deadzone - if (raw > joy_limits[2]) - axis_jog = (raw - joy_limits[2]) / float(joy_limits[3] - joy_limits[2]); - else if (raw < joy_limits[1]) - axis_jog = int16_t(raw - joy_limits[1]) / float(joy_limits[1] - joy_limits[0]); // negative value - // Map normal to jog value via quadratic relationship - axis_jog = SIGN(axis_jog) * sq(axis_jog); - } - }; - - #if HAS_JOY_ADC_X - static constexpr raw_adc_t joy_x_limits[4] = JOY_X_LIMITS; - _normalize_joy(norm_jog.x, JOY_X(x.getraw()), joy_x_limits); - #endif - #if HAS_JOY_ADC_Y - static constexpr raw_adc_t joy_y_limits[4] = JOY_Y_LIMITS; - _normalize_joy(norm_jog.y, JOY_Y(y.getraw()), joy_y_limits); - #endif - #if HAS_JOY_ADC_Z - static constexpr raw_adc_t joy_z_limits[4] = JOY_Z_LIMITS; - _normalize_joy(norm_jog.z, JOY_Z(z.getraw()), joy_z_limits); - #endif - } - -#endif - -#if ENABLED(POLL_JOG) - - void Joystick::inject_jog_moves() { - // Recursion barrier - static bool injecting_now; // = false; - if (injecting_now) return; - - #if ENABLED(NO_MOTION_BEFORE_HOMING) - if (TERN0(HAS_JOY_ADC_X, axis_should_home(X_AXIS)) || TERN0(HAS_JOY_ADC_Y, axis_should_home(Y_AXIS)) || TERN0(HAS_JOY_ADC_Z, axis_should_home(Z_AXIS))) - return; - #endif - - static constexpr int QUEUE_DEPTH = 5; // Insert up to this many movements - static constexpr float target_lag = 0.25f, // Aim for 1/4 second lag - seg_time = target_lag / QUEUE_DEPTH; // 0.05 seconds, short segments inserted every 1/20th of a second - static constexpr millis_t timer_limit_ms = millis_t(seg_time * 500); // 25 ms minimum delay between insertions - - // The planner can merge/collapse small moves, so the movement queue is unreliable to control the lag - static millis_t next_run = 0; - if (PENDING(millis(), next_run)) return; - next_run = millis() + timer_limit_ms; - - // Only inject a command if the planner has fewer than 5 moves and there are no unparsed commands - if (planner.movesplanned() >= QUEUE_DEPTH || queue.has_commands_queued()) - return; - - // Normalized jog values are 0 for no movement and -1 or +1 for as max feedrate (nonlinear relationship) - // Jog are initialized to zero and handling input can update values but doesn't have to - // You could use a two-axis joystick and a one-axis keypad and they might work together - xyz_float_t norm_jog{0}; - - // Use ADC values and defined limits. The active zone is normalized: -1..0 (dead) 0..1 - #if HAS_JOY_ADC_X || HAS_JOY_ADC_Y || HAS_JOY_ADC_Z - joystick.calculate(norm_jog); - #endif - - // Other non-joystick poll-based jogging could be implemented here - // with "jogging" encapsulated as a more general class. - - TERN_(EXTENSIBLE_UI, ExtUI::_joystick_update(norm_jog)); - - // norm_jog values of [-1 .. 1] maps linearly to [-feedrate .. feedrate] - xyz_float_t move_dist{0}; - float hypot2 = 0; - LOOP_NUM_AXES(i) if (norm_jog[i]) { - move_dist[i] = seg_time * norm_jog[i] * TERN(EXTENSIBLE_UI, manual_feedrate_mm_s, planner.settings.max_feedrate_mm_s)[i]; - hypot2 += sq(move_dist[i]); - } - - if (!UNEAR_ZERO(hypot2)) { - current_position += move_dist; - apply_motion_limits(current_position); - const float length = sqrt(hypot2); - PlannerHints hints(length); - injecting_now = true; - planner.buffer_line(current_position, length / seg_time, active_extruder, hints); - injecting_now = false; - } - } - -#endif // POLL_JOG - -#endif // JOYSTICK diff --git a/src/feature/joystick.h b/src/feature/joystick.h deleted file mode 100644 index 91bf6bd..0000000 --- a/src/feature/joystick.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * joystick.h - joystick input / jogging - */ - -#include "../inc/MarlinConfigPre.h" -#include "../core/types.h" -#include "../module/temperature.h" - -class Joystick { - friend class Temperature; - private: - #if HAS_JOY_ADC_X - static temp_info_t x; - #endif - #if HAS_JOY_ADC_Y - static temp_info_t y; - #endif - #if HAS_JOY_ADC_Z - static temp_info_t z; - #endif - public: - #if ENABLED(JOYSTICK_DEBUG) - static void report(); - #endif - static void calculate(xyz_float_t &norm_jog); - static void inject_jog_moves(); -}; - -extern Joystick joystick; diff --git a/src/feature/leds/blinkm.cpp b/src/feature/leds/blinkm.cpp deleted file mode 100644 index 868eb4b..0000000 --- a/src/feature/leds/blinkm.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * blinkm.cpp - Control a BlinkM over i2c - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(BLINKM) - -#include "blinkm.h" -#include "leds.h" -#include - -void blinkm_set_led_color(const LEDColor &color) { - Wire.begin(); - Wire.beginTransmission(I2C_ADDRESS(0x09)); - Wire.write('o'); //to disable ongoing script, only needs to be used once - Wire.write('n'); - Wire.write(color.r); - Wire.write(color.g); - Wire.write(color.b); - Wire.endTransmission(); -} - -#endif // BLINKM diff --git a/src/feature/leds/blinkm.h b/src/feature/leds/blinkm.h deleted file mode 100644 index 29a9e78..0000000 --- a/src/feature/leds/blinkm.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * blinkm.h - Control a BlinkM over i2c - */ - -struct LEDColor; -typedef LEDColor LEDColor; - -void blinkm_set_led_color(const LEDColor &color); diff --git a/src/feature/leds/leds.cpp b/src/feature/leds/leds.cpp deleted file mode 100644 index 2a53a7c..0000000 --- a/src/feature/leds/leds.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * leds.cpp - Marlin RGB LED general support - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_COLOR_LEDS - -#include "leds.h" - -#if ENABLED(BLINKM) - #include "blinkm.h" -#endif - -#if ENABLED(PCA9632) - #include "pca9632.h" -#endif - -#if ENABLED(PCA9533) - #include "pca9533.h" -#endif - -#if EITHER(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL) - #include "../../feature/caselight.h" -#endif - -#if ENABLED(LED_COLOR_PRESETS) - const LEDColor LEDLights::defaultLEDColor = LEDColor( - LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE - OPTARG(HAS_WHITE_LED, LED_USER_PRESET_WHITE) - OPTARG(NEOPIXEL_LED, LED_USER_PRESET_BRIGHTNESS) - ); -#endif - -#if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED) - LEDColor LEDLights::color; - bool LEDLights::lights_on; -#endif - -LEDLights leds; - -void LEDLights::setup() { - #if EITHER(RGB_LED, RGBW_LED) - if (PWM_PIN(RGB_LED_R_PIN)) SET_PWM(RGB_LED_R_PIN); else SET_OUTPUT(RGB_LED_R_PIN); - if (PWM_PIN(RGB_LED_G_PIN)) SET_PWM(RGB_LED_G_PIN); else SET_OUTPUT(RGB_LED_G_PIN); - if (PWM_PIN(RGB_LED_B_PIN)) SET_PWM(RGB_LED_B_PIN); else SET_OUTPUT(RGB_LED_B_PIN); - #if ENABLED(RGBW_LED) - if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN); - #endif - #endif - TERN_(NEOPIXEL_LED, neo.init()); - TERN_(PCA9533, PCA9533_init()); - TERN_(LED_USER_PRESET_STARTUP, set_default()); -} - -void LEDLights::set_color(const LEDColor &incol - OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence/*=false*/) -) { - - #if ENABLED(NEOPIXEL_LED) - - const uint32_t neocolor = LEDColorWhite() == incol - ? neo.Color(NEO_WHITE) - : neo.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_LED, incol.w)); - - #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) - static uint16_t nextLed = 0; - #ifdef NEOPIXEL_BKGD_INDEX_FIRST - while (WITHIN(nextLed, NEOPIXEL_BKGD_INDEX_FIRST, NEOPIXEL_BKGD_INDEX_LAST)) { - neo.reset_background_color(); - if (++nextLed >= neo.pixels()) { nextLed = 0; return; } - } - #endif - #endif - - #if BOTH(CASE_LIGHT_MENU, CASE_LIGHT_USE_NEOPIXEL) - // Update brightness only if caselight is ON or switching leds off - if (caselight.on || incol.is_off()) - #endif - neo.set_brightness(incol.i); - - #if ENABLED(NEOPIXEL_IS_SEQUENTIAL) - if (isSequence) { - neo.set_pixel_color(nextLed, neocolor); - neo.show(); - if (++nextLed >= neo.pixels()) nextLed = 0; - return; - } - #endif - - #if BOTH(CASE_LIGHT_MENU, CASE_LIGHT_USE_NEOPIXEL) - // Update color only if caselight is ON or switching leds off - if (caselight.on || incol.is_off()) - #endif - neo.set_color(neocolor); - - #endif - - #if ENABLED(BLINKM) - - // This variant uses i2c to send the RGB components to the device. - blinkm_set_led_color(incol); - - #endif - - #if EITHER(RGB_LED, RGBW_LED) - - // This variant uses 3-4 separate pins for the RGB(W) components. - // If the pins can do PWM then their intensity will be set. - #define _UPDATE_RGBW(C,c) do { \ - if (PWM_PIN(RGB_LED_##C##_PIN)) \ - hal.set_pwm_duty(pin_t(RGB_LED_##C##_PIN), c); \ - else \ - WRITE(RGB_LED_##C##_PIN, c ? HIGH : LOW); \ - }while(0) - #define UPDATE_RGBW(C,c) _UPDATE_RGBW(C, TERN1(CASE_LIGHT_USE_RGB_LED, caselight.on) ? incol.c : 0) - UPDATE_RGBW(R,r); UPDATE_RGBW(G,g); UPDATE_RGBW(B,b); - #if ENABLED(RGBW_LED) - UPDATE_RGBW(W,w); - #endif - - #endif - - // Update I2C LED driver - TERN_(PCA9632, PCA9632_set_led_color(incol)); - TERN_(PCA9533, PCA9533_set_rgb(incol.r, incol.g, incol.b)); - - #if EITHER(LED_CONTROL_MENU, PRINTER_EVENT_LEDS) - // Don't update the color when OFF - lights_on = !incol.is_off(); - if (lights_on) color = incol; - #endif -} - -#if ENABLED(LED_CONTROL_MENU) - void LEDLights::toggle() { if (lights_on) set_off(); else update(); } -#endif - -#if LED_POWEROFF_TIMEOUT > 0 - - millis_t LEDLights::led_off_time; // = 0 - - void LEDLights::update_timeout(const bool power_on) { - if (lights_on) { - const millis_t ms = millis(); - if (power_on) - reset_timeout(ms); - else if (ELAPSED(ms, led_off_time)) - set_off(); - } - } - -#endif - -#if ENABLED(NEOPIXEL2_SEPARATE) - - #if ENABLED(NEO2_COLOR_PRESETS) - const LEDColor LEDLights2::defaultLEDColor = LEDColor( - NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE - OPTARG(HAS_WHITE_LED2, NEO2_USER_PRESET_WHITE) - OPTARG(NEOPIXEL_LED, NEO2_USER_PRESET_BRIGHTNESS) - ); - #endif - - #if ENABLED(LED_CONTROL_MENU) - LEDColor LEDLights2::color; - bool LEDLights2::lights_on; - #endif - - LEDLights2 leds2; - - void LEDLights2::setup() { - neo2.init(); - TERN_(NEO2_USER_PRESET_STARTUP, set_default()); - } - - void LEDLights2::set_color(const LEDColor &incol) { - const uint32_t neocolor = LEDColorWhite() == incol - ? neo2.Color(NEO2_WHITE) - : neo2.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_LED2, incol.w)); - neo2.set_brightness(incol.i); - neo2.set_color(neocolor); - - #if ENABLED(LED_CONTROL_MENU) - // Don't update the color when OFF - lights_on = !incol.is_off(); - if (lights_on) color = incol; - #endif - } - - #if ENABLED(LED_CONTROL_MENU) - void LEDLights2::toggle() { if (lights_on) set_off(); else update(); } - #endif - -#endif // NEOPIXEL2_SEPARATE - -#endif // HAS_COLOR_LEDS diff --git a/src/feature/leds/leds.h b/src/feature/leds/leds.h deleted file mode 100644 index 8649dd0..0000000 --- a/src/feature/leds/leds.h +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * leds.h - Marlin general RGB LED support - */ - -#include "../../inc/MarlinConfigPre.h" - -#include - -// A white component can be passed -#if EITHER(RGBW_LED, PCA9632_RGBW) - #define HAS_WHITE_LED 1 -#endif - -#if ENABLED(NEOPIXEL_LED) - #define _NEOPIXEL_INCLUDE_ - #include "neopixel.h" - #undef _NEOPIXEL_INCLUDE_ -#endif - -/** - * LEDcolor type for use with leds.set_color - */ -typedef struct LEDColor { - uint8_t r, g, b - OPTARG(HAS_WHITE_LED, w) - OPTARG(NEOPIXEL_LED, i) - ; - - LEDColor() : r(255), g(255), b(255) - OPTARG(HAS_WHITE_LED, w(255)) - OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)) - {} - - LEDColor(const LEDColor&) = default; - - LEDColor(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w=0) OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS)) - : r(r), g(g), b(b) OPTARG(HAS_WHITE_LED, w(w)) OPTARG(NEOPIXEL_LED, i(i)) {} - - LEDColor(const uint8_t (&rgbw)[4]) : r(rgbw[0]), g(rgbw[1]), b(rgbw[2]) - OPTARG(HAS_WHITE_LED, w(rgbw[3])) - OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)) - {} - - LEDColor& operator=(const uint8_t (&rgbw)[4]) { - r = rgbw[0]; g = rgbw[1]; b = rgbw[2]; - TERN_(HAS_WHITE_LED, w = rgbw[3]); - return *this; - } - - bool operator==(const LEDColor &right) { - if (this == &right) return true; - return 0 == memcmp(this, &right, sizeof(LEDColor)); - } - - bool operator!=(const LEDColor &right) { return !operator==(right); } - - bool is_off() const { - return 3 > r + g + b + TERN0(HAS_WHITE_LED, w); - } -} LEDColor; - -/** - * Color presets - */ - -#define LEDColorOff() LEDColor( 0, 0, 0) -#define LEDColorRed() LEDColor(255, 0, 0) -#if ENABLED(LED_COLORS_REDUCE_GREEN) - #define LEDColorOrange() LEDColor(255, 25, 0) - #define LEDColorYellow() LEDColor(255, 75, 0) -#else - #define LEDColorOrange() LEDColor(255, 80, 0) - #define LEDColorYellow() LEDColor(255, 255, 0) -#endif -#define LEDColorGreen() LEDColor( 0, 255, 0) -#define LEDColorBlue() LEDColor( 0, 0, 255) -#define LEDColorIndigo() LEDColor( 0, 255, 255) -#define LEDColorViolet() LEDColor(255, 0, 255) -#if HAS_WHITE_LED && DISABLED(RGB_LED) - #define LEDColorWhite() LEDColor( 0, 0, 0, 255) -#else - #define LEDColorWhite() LEDColor(255, 255, 255) -#endif - -class LEDLights { -public: - LEDLights() {} // ctor - - static void setup(); // init() - - static void set_color(const LEDColor &color - OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence=false) - ); - - static void set_color(uint8_t r, uint8_t g, uint8_t b - OPTARG(HAS_WHITE_LED, uint8_t w=0) - OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS) - OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence=false) - ) { - set_color(LEDColor(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, i)) OPTARG(NEOPIXEL_IS_SEQUENTIAL, isSequence)); - } - - static void set_off() { set_color(LEDColorOff()); } - static void set_green() { set_color(LEDColorGreen()); } - static void set_white() { set_color(LEDColorWhite()); } - - #if ENABLED(LED_COLOR_PRESETS) - static const LEDColor defaultLEDColor; - static void set_default() { set_color(defaultLEDColor); } - static void set_red() { set_color(LEDColorRed()); } - static void set_orange() { set_color(LEDColorOrange()); } - static void set_yellow() { set_color(LEDColorYellow()); } - static void set_blue() { set_color(LEDColorBlue()); } - static void set_indigo() { set_color(LEDColorIndigo()); } - static void set_violet() { set_color(LEDColorViolet()); } - #endif - - #if ENABLED(PRINTER_EVENT_LEDS) - static LEDColor get_color() { return lights_on ? color : LEDColorOff(); } - #endif - - #if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED) - static LEDColor color; // last non-off color - static bool lights_on; // the last set color was "on" - #endif - - #if ENABLED(LED_CONTROL_MENU) - static void toggle(); // swap "off" with color - #endif - #if EITHER(LED_CONTROL_MENU, CASE_LIGHT_USE_RGB_LED) - static void update() { set_color(color); } - #endif - - #if LED_POWEROFF_TIMEOUT > 0 - private: - static millis_t led_off_time; - public: - static void reset_timeout(const millis_t &ms) { - led_off_time = ms + LED_POWEROFF_TIMEOUT; - if (!lights_on) update(); - } - static void update_timeout(const bool power_on); - #endif -}; - -extern LEDLights leds; - -#if ENABLED(NEOPIXEL2_SEPARATE) - - class LEDLights2 { - public: - LEDLights2() {} - - static void setup(); // init() - - static void set_color(const LEDColor &color); - - static void set_color(uint8_t r, uint8_t g, uint8_t b - OPTARG(HAS_WHITE_LED, uint8_t w=0) - OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS) - ) { - set_color(LEDColor(r, g, b - OPTARG(HAS_WHITE_LED, w) - OPTARG(NEOPIXEL_LED, i) - )); - } - - static void set_off() { set_color(LEDColorOff()); } - static void set_green() { set_color(LEDColorGreen()); } - static void set_white() { set_color(LEDColorWhite()); } - - #if ENABLED(NEO2_COLOR_PRESETS) - static const LEDColor defaultLEDColor; - static void set_default() { set_color(defaultLEDColor); } - static void set_red() { set_color(LEDColorRed()); } - static void set_orange() { set_color(LEDColorOrange()); } - static void set_yellow() { set_color(LEDColorYellow()); } - static void set_blue() { set_color(LEDColorBlue()); } - static void set_indigo() { set_color(LEDColorIndigo()); } - static void set_violet() { set_color(LEDColorViolet()); } - #endif - - #if ENABLED(NEOPIXEL2_SEPARATE) - static LEDColor color; // last non-off color - static bool lights_on; // the last set color was "on" - static void toggle(); // swap "off" with color - static void update() { set_color(color); } - #endif - }; - - extern LEDLights2 leds2; - -#endif // NEOPIXEL2_SEPARATE diff --git a/src/feature/leds/neopixel.cpp b/src/feature/leds/neopixel.cpp deleted file mode 100644 index 4f10423..0000000 --- a/src/feature/leds/neopixel.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Marlin RGB LED general support - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(NEOPIXEL_LED) - -#include "leds.h" - -#if EITHER(NEOPIXEL_STARTUP_TEST, NEOPIXEL2_STARTUP_TEST) - #include "../../core/utility.h" -#endif - -Marlin_NeoPixel neo; -pixel_index_t Marlin_NeoPixel::neoindex; - -Adafruit_NeoPixel Marlin_NeoPixel::adaneo1(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800); -#if CONJOINED_NEOPIXEL - Adafruit_NeoPixel Marlin_NeoPixel::adaneo2(NEOPIXEL_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE + NEO_KHZ800); -#endif - -#ifdef NEOPIXEL_BKGD_INDEX_FIRST - - void Marlin_NeoPixel::set_background_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w) { - for (int background_led = NEOPIXEL_BKGD_INDEX_FIRST; background_led <= NEOPIXEL_BKGD_INDEX_LAST; background_led++) - set_pixel_color(background_led, adaneo1.Color(r, g, b, w)); - } - - void Marlin_NeoPixel::reset_background_color() { - constexpr uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR; - set_background_color(background_color); - } - -#endif - -void Marlin_NeoPixel::set_color(const uint32_t color) { - if (neoindex >= 0) { - set_pixel_color(neoindex, color); - neoindex = -1; - } - else { - for (uint16_t i = 0; i < pixels(); ++i) { - #ifdef NEOPIXEL_BKGD_INDEX_FIRST - if (i == NEOPIXEL_BKGD_INDEX_FIRST && TERN(NEOPIXEL_BKGD_ALWAYS_ON, true, color != 0x000000)) { - reset_background_color(); - i += NEOPIXEL_BKGD_INDEX_LAST - (NEOPIXEL_BKGD_INDEX_FIRST); - continue; - } - #endif - set_pixel_color(i, color); - } - } - show(); -} - -void Marlin_NeoPixel::set_color_startup(const uint32_t color) { - for (uint16_t i = 0; i < pixels(); ++i) - set_pixel_color(i, color); - show(); -} - -void Marlin_NeoPixel::init() { - neoindex = -1; // -1 .. NEOPIXEL_PIXELS-1 range - set_brightness(NEOPIXEL_BRIGHTNESS); // 0 .. 255 range - begin(); - show(); // initialize to all off - - #if ENABLED(NEOPIXEL_STARTUP_TEST) - set_color_startup(adaneo1.Color(255, 0, 0, 0)); // red - safe_delay(500); - set_color_startup(adaneo1.Color(0, 255, 0, 0)); // green - safe_delay(500); - set_color_startup(adaneo1.Color(0, 0, 255, 0)); // blue - safe_delay(500); - #if HAS_WHITE_LED - set_color_startup(adaneo1.Color(0, 0, 0, 255)); // white - safe_delay(500); - #endif - #endif - - #ifdef NEOPIXEL_BKGD_INDEX_FIRST - reset_background_color(); - #endif - - set_color(adaneo1.Color - TERN(LED_USER_PRESET_STARTUP, - (LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE, LED_USER_PRESET_WHITE), - (255, 255, 255, 255)) - ); -} - -#if ENABLED(NEOPIXEL2_SEPARATE) - - Marlin_NeoPixel2 neo2; - - pixel_index_t Marlin_NeoPixel2::neoindex; - Adafruit_NeoPixel Marlin_NeoPixel2::adaneo(NEOPIXEL2_PIXELS, NEOPIXEL2_PIN, NEOPIXEL2_TYPE); - - void Marlin_NeoPixel2::set_color(const uint32_t color) { - if (neoindex >= 0) { - set_pixel_color(neoindex, color); - neoindex = -1; - } - else { - for (uint16_t i = 0; i < pixels(); ++i) - set_pixel_color(i, color); - } - show(); - } - - void Marlin_NeoPixel2::set_color_startup(const uint32_t color) { - for (uint16_t i = 0; i < pixels(); ++i) - set_pixel_color(i, color); - show(); - } - - void Marlin_NeoPixel2::init() { - neoindex = -1; // -1 .. NEOPIXEL2_PIXELS-1 range - set_brightness(NEOPIXEL2_BRIGHTNESS); // 0 .. 255 range - begin(); - show(); // initialize to all off - - #if ENABLED(NEOPIXEL2_STARTUP_TEST) - set_color_startup(adaneo.Color(255, 0, 0, 0)); // red - safe_delay(500); - set_color_startup(adaneo.Color(0, 255, 0, 0)); // green - safe_delay(500); - set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue - safe_delay(500); - #if HAS_WHITE_LED2 - set_color_startup(adaneo.Color(0, 0, 0, 255)); // white - safe_delay(500); - #endif - #endif - - set_color(adaneo.Color - TERN(NEO2_USER_PRESET_STARTUP, - (NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE, NEO2_USER_PRESET_WHITE), - (0, 0, 0, 0)) - ); - } - -#endif // NEOPIXEL2_SEPARATE - -#endif // NEOPIXEL_LED diff --git a/src/feature/leds/neopixel.h b/src/feature/leds/neopixel.h deleted file mode 100644 index d71aa25..0000000 --- a/src/feature/leds/neopixel.h +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * NeoPixel support - */ - -#ifndef _NEOPIXEL_INCLUDE_ - #error "Always include 'leds.h' and not 'neopixel.h' directly." -#endif - -// ------------------------ -// Includes -// ------------------------ - -#include "../../inc/MarlinConfig.h" - -#include -#include - -// ------------------------ -// Defines -// ------------------------ - -#define _NEO_IS_RGB(N) (N == NEO_RGB || N == NEO_RBG || N == NEO_GRB || N == NEO_GBR || N == NEO_BRG || N == NEO_BGR) - -#if !_NEO_IS_RGB(NEOPIXEL_TYPE) - #define HAS_WHITE_LED 1 -#endif - -#if HAS_WHITE_LED - #define NEO_WHITE 0, 0, 0, 255 -#else - #define NEO_WHITE 255, 255, 255 -#endif - -#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE) - #define MULTIPLE_NEOPIXEL_TYPES 1 -#endif - -#if EITHER(MULTIPLE_NEOPIXEL_TYPES, NEOPIXEL2_INSERIES) - #define CONJOINED_NEOPIXEL 1 -#endif - -// ------------------------ -// Types -// ------------------------ - -typedef IF<(TERN0(NEOPIXEL_LED, NEOPIXEL_PIXELS > 127)), int16_t, int8_t>::type pixel_index_t; - -// ------------------------ -// Classes -// ------------------------ - -class Marlin_NeoPixel { -private: - static Adafruit_NeoPixel adaneo1; - #if CONJOINED_NEOPIXEL - static Adafruit_NeoPixel adaneo2; - #endif - -public: - static pixel_index_t neoindex; - - static void init(); - static void set_color_startup(const uint32_t c); - - static void set_color(const uint32_t c); - - #ifdef NEOPIXEL_BKGD_INDEX_FIRST - static void set_background_color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t w); - static void set_background_color(const uint8_t (&rgbw)[4]) { set_background_color(rgbw[0], rgbw[1], rgbw[2], rgbw[3]); } - static void reset_background_color(); - #endif - - static void begin() { - adaneo1.begin(); - TERN_(CONJOINED_NEOPIXEL, adaneo2.begin()); - } - - static void set_pixel_color(const uint16_t n, const uint32_t c) { - #if ENABLED(NEOPIXEL2_INSERIES) - if (n >= NEOPIXEL_PIXELS) adaneo2.setPixelColor(n - (NEOPIXEL_PIXELS), c); - else adaneo1.setPixelColor(n, c); - #else - adaneo1.setPixelColor(n, c); - TERN_(MULTIPLE_NEOPIXEL_TYPES, adaneo2.setPixelColor(n, c)); - #endif - } - - static void set_brightness(const uint8_t b) { - adaneo1.setBrightness(b); - TERN_(CONJOINED_NEOPIXEL, adaneo2.setBrightness(b)); - } - - static void show() { - // Some platforms cannot maintain PWM output when NeoPixel disables interrupts for long durations. - TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT()); - adaneo1.show(); - #if PIN_EXISTS(NEOPIXEL2) - #if CONJOINED_NEOPIXEL - adaneo2.show(); - #else - adaneo1.show(); - adaneo1.setPin(NEOPIXEL_PIN); - #endif - #endif - TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT()); - } - - // Accessors - static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); } - - static uint8_t brightness() { return adaneo1.getBrightness(); } - - static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w)) { - return adaneo1.Color(r, g, b OPTARG(HAS_WHITE_LED, w)); - } -}; - -extern Marlin_NeoPixel neo; - -// Neo pixel channel 2 -#if ENABLED(NEOPIXEL2_SEPARATE) - - #if _NEO_IS_RGB(NEOPIXEL2_TYPE) - #define NEOPIXEL2_IS_RGB 1 - #define NEO2_WHITE 255, 255, 255 - #else - #define NEOPIXEL2_IS_RGBW 1 - #define HAS_WHITE_LED2 1 // A white component can be passed for NEOPIXEL2 - #define NEO2_WHITE 0, 0, 0, 255 - #endif - - class Marlin_NeoPixel2 { - private: - static Adafruit_NeoPixel adaneo; - - public: - static pixel_index_t neoindex; - - static void init(); - static void set_color_startup(const uint32_t c); - - static void set_color(const uint32_t c); - - static void begin() { adaneo.begin(); } - static void set_pixel_color(const uint16_t n, const uint32_t c) { adaneo.setPixelColor(n, c); } - static void set_brightness(const uint8_t b) { adaneo.setBrightness(b); } - static void show() { - adaneo.show(); - adaneo.setPin(NEOPIXEL2_PIN); - } - - // Accessors - static uint16_t pixels() { return adaneo.numPixels();} - static uint8_t brightness() { return adaneo.getBrightness(); } - static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED2, uint8_t w)) { - return adaneo.Color(r, g, b OPTARG(HAS_WHITE_LED2, w)); - } - }; - - extern Marlin_NeoPixel2 neo2; - -#endif // NEOPIXEL2_SEPARATE - -#undef _NEO_IS_RGB diff --git a/src/feature/leds/pca9533.cpp b/src/feature/leds/pca9533.cpp deleted file mode 100644 index 914db21..0000000 --- a/src/feature/leds/pca9533.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * PCA9533 LED controller driver (MightyBoard, FlashForge Creator Pro, etc.) - * by @grauerfuchs - 1 Apr 2020 - */ -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PCA9533) - -#include "pca9533.h" -#include - -void PCA9533_init() { - Wire.begin(); - PCA9533_reset(); -} - -static void PCA9533_writeAllRegisters(uint8_t psc0, uint8_t pwm0, uint8_t psc1, uint8_t pwm1, uint8_t ls0) { - uint8_t data[6] = { PCA9533_REG_PSC0 | PCA9533_REGM_AI, psc0, pwm0, psc1, pwm1, ls0 }; - Wire.beginTransmission(PCA9533_Addr >> 1); - Wire.write(data, 6); - Wire.endTransmission(); - delayMicroseconds(1); -} - -static void PCA9533_writeRegister(uint8_t reg, uint8_t val) { - uint8_t data[2] = { reg, val }; - Wire.beginTransmission(PCA9533_Addr >> 1); - Wire.write(data, 2); - Wire.endTransmission(); - delayMicroseconds(1); -} - -// Reset (clear) all registers -void PCA9533_reset() { - PCA9533_writeAllRegisters(0, 0, 0, 0, 0); -} - -// Turn all LEDs off -void PCA9533_setOff() { - PCA9533_writeRegister(PCA9533_REG_SEL, 0); -} - -void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue) { - uint8_t r_pwm0 = 0; // Register data - PWM value - uint8_t r_pwm1 = 0; // Register data - PWM value - - uint8_t op_g = 0, op_r = 0, op_b = 0; // Opcodes - Green, Red, Blue - - // Light theory! GREEN takes priority because - // it's the most visible to the human eye. - if (green == 0) op_g = PCA9533_LED_OP_OFF; - else if (green == 255) op_g = PCA9533_LED_OP_ON; - else { r_pwm0 = green; op_g = PCA9533_LED_OP_PWM0; } - - // RED - if (red == 0) op_r = PCA9533_LED_OP_OFF; - else if (red == 255) op_r = PCA9533_LED_OP_ON; - else if (r_pwm0 == 0 || r_pwm0 == red) { - r_pwm0 = red; op_r = PCA9533_LED_OP_PWM0; - } - else { - r_pwm1 = red; op_r = PCA9533_LED_OP_PWM1; - } - - // BLUE - if (blue == 0) op_b = PCA9533_LED_OP_OFF; - else if (blue == 255) op_b = PCA9533_LED_OP_ON; - else if (r_pwm0 == 0 || r_pwm0 == blue) { - r_pwm0 = blue; op_b = PCA9533_LED_OP_PWM0; - } - else if (r_pwm1 == 0 || r_pwm1 == blue) { - r_pwm1 = blue; op_b = PCA9533_LED_OP_PWM1; - } - else { - /** - * Conflict. 3 values are requested but only 2 channels exist. - * G is on channel 0 and R is on channel 1, so work from there. - * Find the closest match, average the values, then use the free channel. - */ - uint8_t dgb = ABS(green - blue), - dgr = ABS(green - red), - dbr = ABS(blue - red); - if (dgb < dgr && dgb < dbr) { // Mix with G on channel 0. - op_b = PCA9533_LED_OP_PWM0; - r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)blue) / 2); - } - else if (dbr <= dgr && dbr <= dgb) { // Mix with R on channel 1. - op_b = PCA9533_LED_OP_PWM1; - r_pwm1 = uint8_t(((uint16_t)red + (uint16_t)blue) / 2); - } - else { // Mix R+G on 0 and put B on 1. - op_r = PCA9533_LED_OP_PWM0; - r_pwm0 = uint8_t(((uint16_t)green + (uint16_t)red) / 2); - op_b = PCA9533_LED_OP_PWM1; - r_pwm1 = blue; - } - } - - // Write the changes to the hardware - PCA9533_writeAllRegisters(0, r_pwm0, 0, r_pwm1, - (op_g << PCA9533_LED_OFS_GRN) | (op_r << PCA9533_LED_OFS_RED) | (op_b << PCA9533_LED_OFS_BLU) - ); -} - -#endif // PCA9533 diff --git a/src/feature/leds/pca9533.h b/src/feature/leds/pca9533.h deleted file mode 100644 index 431058c..0000000 --- a/src/feature/leds/pca9533.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/* - * Driver for the PCA9533 LED controller found on the MightyBoard - * used by FlashForge Creator Pro, MakerBot, etc. - * Written 2020 APR 01 by grauerfuchs - */ -#include - -#define ENABLE_I2C_PULLUPS - -// Chip address (for Wire) -#define PCA9533_Addr 0xC4 - -// Control registers -#define PCA9533_REG_READ 0x00 -#define PCA9533_REG_PSC0 0x01 -#define PCA9533_REG_PWM0 0x02 -#define PCA9533_REG_PSC1 0x03 -#define PCA9533_REG_PWM1 0x04 -#define PCA9533_REG_SEL 0x05 -#define PCA9533_REGM_AI 0x10 - -// LED selector operation -#define PCA9533_LED_OP_OFF 0B00 -#define PCA9533_LED_OP_ON 0B01 -#define PCA9533_LED_OP_PWM0 0B10 -#define PCA9533_LED_OP_PWM1 0B11 - -// Select register bit offsets for LED colors -#define PCA9533_LED_OFS_RED 0 -#define PCA9533_LED_OFS_GRN 2 -#define PCA9533_LED_OFS_BLU 4 - -void PCA9533_init(); -void PCA9533_reset(); -void PCA9533_set_rgb(uint8_t red, uint8_t green, uint8_t blue); -void PCA9533_setOff(); diff --git a/src/feature/leds/pca9632.cpp b/src/feature/leds/pca9632.cpp deleted file mode 100644 index abea988..0000000 --- a/src/feature/leds/pca9632.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Driver for the Philips PCA9632 LED driver. - * Written by Robert Mendon Feb 2017. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PCA9632) - -#include "pca9632.h" -#include "leds.h" -#include - -#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 White=LED3 -#ifndef PCA9632_RED - #define PCA9632_RED 0x00 -#endif -#ifndef PCA9632_GRN - #define PCA9632_GRN 0x02 -#endif -#ifndef PCA9632_BLU - #define PCA9632_BLU 0x04 -#endif -#if HAS_WHITE_LED && !defined(PCA9632_WHT) - #define PCA9632_WHT 0x06 -#endif - -// If any of the color indexes are greater than 0x04 they can't use auto increment -#if !defined(PCA9632_NO_AUTO_INC) && (PCA9632_RED > 0x04 || PCA9632_GRN > 0x04 || PCA9632_BLU > 0x04 || PCA9632_WHT > 0x04) - #define PCA9632_NO_AUTO_INC -#endif - -#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(I2C_ADDRESS(addr)); - Wire.write(regadd); - Wire.write(value); - Wire.endTransmission(); -} - -static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const byte vr, const byte vg, const byte vb - OPTARG(PCA9632_RGBW, const byte vw) -) { - #if DISABLED(PCA9632_NO_AUTO_INC) - uint8_t data[4]; - data[0] = PCA9632_AUTO_IND | regadd; - data[1 + (PCA9632_RED >> 1)] = vr; - data[1 + (PCA9632_GRN >> 1)] = vg; - data[1 + (PCA9632_BLU >> 1)] = vb; - Wire.beginTransmission(I2C_ADDRESS(addr)); - Wire.write(data, sizeof(data)); - Wire.endTransmission(); - #else - PCA9632_WriteRegister(addr, regadd + (PCA9632_RED >> 1), vr); - PCA9632_WriteRegister(addr, regadd + (PCA9632_GRN >> 1), vg); - PCA9632_WriteRegister(addr, regadd + (PCA9632_BLU >> 1), vb); - #if ENABLED(PCA9632_RGBW) - PCA9632_WriteRegister(addr, regadd + (PCA9632_WHT >> 1), vw); - #endif - #endif -} - -#if 0 - static byte PCA9632_ReadRegister(const byte addr, const byte regadd) { - Wire.beginTransmission(I2C_ADDRESS(addr)); - Wire.write(regadd); - const byte value = Wire.read(); - Wire.endTransmission(); - return value; - } -#endif - -void PCA9632_set_led_color(const LEDColor &color) { - Wire.begin(); - if (!PCA_init) { - PCA_init = 1; - PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE1, PCA9632_MODE1_VALUE); - PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_MODE2, PCA9632_MODE2_VALUE); - } - - const byte LEDOUT = (color.r ? LED_PWM << PCA9632_RED : 0) - | (color.g ? LED_PWM << PCA9632_GRN : 0) - | (color.b ? LED_PWM << PCA9632_BLU : 0) - #if ENABLED(PCA9632_RGBW) - | (color.w ? LED_PWM << PCA9632_WHT : 0) - #endif - ; - - PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, color.r, color.g, color.b - OPTARG(PCA9632_RGBW, color.w) - ); - PCA9632_WriteRegister(PCA9632_ADDRESS,PCA9632_LEDOUT, LEDOUT); -} - -#if ENABLED(PCA9632_BUZZER) - - void PCA9632_buzz(const long, const uint16_t) { - uint8_t data[] = PCA9632_BUZZER_DATA; - Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS)); - Wire.write(data, sizeof(data)); - Wire.endTransmission(); - } - -#endif // PCA9632_BUZZER - -#endif // PCA9632 diff --git a/src/feature/leds/pca9632.h b/src/feature/leds/pca9632.h deleted file mode 100644 index fb59a8c..0000000 --- a/src/feature/leds/pca9632.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Driver for the Philips PCA9632 LED driver. - * Written by Robert Mendon Feb 2017. - */ - -struct LEDColor; -typedef LEDColor LEDColor; - -void PCA9632_set_led_color(const LEDColor &color); - -#if ENABLED(PCA9632_BUZZER) - #include - void PCA9632_buzz(const long, const uint16_t); -#endif diff --git a/src/feature/leds/printer_event_leds.cpp b/src/feature/leds/printer_event_leds.cpp deleted file mode 100644 index e6407a6..0000000 --- a/src/feature/leds/printer_event_leds.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/leds/printer_event_leds.cpp - LED color changing based on printer status - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(PRINTER_EVENT_LEDS) - -#include "printer_event_leds.h" - -PrinterEventLEDs printerEventLEDs; - -#if HAS_LEDS_OFF_FLAG - bool PrinterEventLEDs::leds_off_after_print; // = false -#endif - -#if HAS_TEMP_HOTEND || HAS_HEATED_BED - - uint8_t PrinterEventLEDs::old_intensity = 0; - - inline uint8_t pel_intensity(const celsius_t start, const celsius_t current, const celsius_t target) { - if (start == target) return 255; - return (uint8_t)map(constrain(current, start, target), start, target, 0, 255); - } - - inline void pel_set_rgb(const uint8_t r, const uint8_t g, const uint8_t b OPTARG(HAS_WHITE_LED, const uint8_t w=0)) { - leds.set_color( - LEDColor(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, neo.brightness())) - OPTARG(NEOPIXEL_IS_SEQUENTIAL, true) - ); - } - -#endif - -#if HAS_TEMP_HOTEND - - void PrinterEventLEDs::onHotendHeating(const celsius_t start, const celsius_t current, const celsius_t target) { - const uint8_t blue = pel_intensity(start, current, target); - if (blue != old_intensity) { - old_intensity = blue; - pel_set_rgb(255, 0, 255 - blue); - } - } - -#endif - -#if HAS_HEATED_BED - - void PrinterEventLEDs::onBedHeating(const celsius_t start, const celsius_t current, const celsius_t target) { - const uint8_t red = pel_intensity(start, current, target); - if (red != old_intensity) { - old_intensity = red; - pel_set_rgb(red, 0, 255); - } - } - -#endif - -#if HAS_HEATED_CHAMBER - - void PrinterEventLEDs::onChamberHeating(const celsius_t start, const celsius_t current, const celsius_t target) { - const uint8_t green = pel_intensity(start, current, target); - if (green != old_intensity) { - old_intensity = green; - pel_set_rgb(255, green, 255); - } - } - -#endif - -#endif // PRINTER_EVENT_LEDS diff --git a/src/feature/leds/printer_event_leds.h b/src/feature/leds/printer_event_leds.h deleted file mode 100644 index 2a4342e..0000000 --- a/src/feature/leds/printer_event_leds.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/leds/printer_event_leds.h - LED color changing based on printer status - */ - -#include "leds.h" -#include "../../inc/MarlinConfig.h" - -class PrinterEventLEDs { -private: - static uint8_t old_intensity; - - #if HAS_LEDS_OFF_FLAG - static bool leds_off_after_print; - #endif - - static void set_done() { TERN(LED_COLOR_PRESETS, leds.set_default(), leds.set_off()); } - -public: - #if HAS_TEMP_HOTEND - static LEDColor onHotendHeatingStart() { old_intensity = 0; return leds.get_color(); } - static void onHotendHeating(const celsius_t start, const celsius_t current, const celsius_t target); - #endif - - #if HAS_HEATED_BED - static LEDColor onBedHeatingStart() { old_intensity = 127; return leds.get_color(); } - static void onBedHeating(const celsius_t start, const celsius_t current, const celsius_t target); - #endif - - #if HAS_HEATED_CHAMBER - static LEDColor onChamberHeatingStart() { old_intensity = 127; return leds.get_color(); } - static void onChamberHeating(const celsius_t start, const celsius_t current, const celsius_t target); - #endif - - #if HAS_TEMP_HOTEND || HAS_HEATED_BED || HAS_HEATED_CHAMBER - static void onHeatingDone() { leds.set_white(); } - static void onPidTuningDone(LEDColor c) { leds.set_color(c); } - #endif - - #if ENABLED(SDSUPPORT) - - static void onPrintCompleted() { - leds.set_green(); - #if HAS_LEDS_OFF_FLAG - leds_off_after_print = true; - #else - safe_delay(2000); - set_done(); - #endif - } - - static void onResumeAfterWait() { - #if HAS_LEDS_OFF_FLAG - if (leds_off_after_print) { - set_done(); - leds_off_after_print = false; - } - #endif - } - - #endif // SDSUPPORT -}; - -extern PrinterEventLEDs printerEventLEDs; diff --git a/src/feature/leds/tempstat.cpp b/src/feature/leds/tempstat.cpp deleted file mode 100644 index 967b9f4..0000000 --- a/src/feature/leds/tempstat.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * Marlin RGB LED general support - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(TEMP_STAT_LEDS) - -#include "tempstat.h" -#include "../../module/temperature.h" - -void handle_status_leds() { - static int8_t old_red = -1; // Invalid value to force LED initialization - static millis_t next_status_led_update_ms = 0; - if (ELAPSED(millis(), next_status_led_update_ms)) { - next_status_led_update_ms += 500; // Update every 0.5s - celsius_t max_temp = TERN0(HAS_HEATED_BED, _MAX(thermalManager.degTargetBed(), thermalManager.wholeDegBed())); - HOTEND_LOOP() - max_temp = _MAX(max_temp, thermalManager.wholeDegHotend(e), thermalManager.degTargetHotend(e)); - const int8_t new_red = (max_temp > 55) ? HIGH : (max_temp < 54 || old_red < 0) ? LOW : old_red; - if (new_red != old_red) { - old_red = new_red; - #if PIN_EXISTS(STAT_LED_RED) - WRITE(STAT_LED_RED_PIN, new_red); - #endif - #if PIN_EXISTS(STAT_LED_BLUE) - WRITE(STAT_LED_BLUE_PIN, !new_red); - #endif - } - } -} - -#endif // TEMP_STAT_LEDS diff --git a/src/feature/leds/tempstat.h b/src/feature/leds/tempstat.h deleted file mode 100644 index a8b919b..0000000 --- a/src/feature/leds/tempstat.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * Marlin general RGB LED support - */ - -void handle_status_leds(); diff --git a/src/feature/max7219.cpp b/src/feature/max7219.cpp deleted file mode 100644 index ef698f8..0000000 --- a/src/feature/max7219.cpp +++ /dev/null @@ -1,698 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * This module is off by default, but can be enabled to facilitate the display of - * extra debug information during code development. - * - * 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 - * - * send() is called automatically at startup, and then there are a number of - * support functions available to control the LEDs in the 8x8 grid. - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(MAX7219_DEBUG) - -#define MAX7219_ERRORS // Disable to save 406 bytes of Program Memory - -#include "max7219.h" - -#include "../module/planner.h" -#include "../MarlinCore.h" -#include "../HAL/shared/Delay.h" - -#if ENABLED(MAX7219_SIDE_BY_SIDE) && MAX7219_NUMBER_UNITS > 1 - #define HAS_SIDE_BY_SIDE 1 -#endif - -#if _ROT == 0 || _ROT == 180 - #define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES) - #define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8) -#elif _ROT == 90 || _ROT == 270 - #define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8) - #define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES) -#else - #error "MAX7219_ROTATE must be a multiple of +/- 90°." -#endif - -Max7219 max7219; - -uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 }; -uint8_t Max7219::suspended; // = 0; - -#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7)) - -#if _ROT == 0 || _ROT == 270 - #define _LED_BIT(Q) (7 - ((Q) & 0x7)) -#else - #define _LED_BIT(Q) ((Q) & 0x7) -#endif -#if _ROT == 0 || _ROT == 180 - #define LED_BIT(X,Y) _LED_BIT(X) -#else - #define LED_BIT(X,Y) _LED_BIT(Y) -#endif -#if _ROT == 0 || _ROT == 90 - #define _LED_IND(P,Q) (_LED_TOP(P) + ((Q) & 0x7)) -#else - #define _LED_IND(P,Q) (_LED_TOP(P) + (7 - ((Q) & 0x7))) -#endif - -#if HAS_SIDE_BY_SIDE - #if (_ROT == 0 || _ROT == 90) == DISABLED(MAX7219_REVERSE_ORDER) - #define _LED_TOP(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3) - #else - #define _LED_TOP(Q) ((Q) & ~0x7) - #endif - #if _ROT == 0 || _ROT == 180 - #define LED_IND(X,Y) _LED_IND(Y,Y) - #elif _ROT == 90 || _ROT == 270 - #define LED_IND(X,Y) _LED_IND(X,X) - #endif -#else - #if (_ROT == 0 || _ROT == 270) == DISABLED(MAX7219_REVERSE_ORDER) - #define _LED_TOP(Q) ((Q) & ~0x7) - #else - #define _LED_TOP(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3) - #endif - #if _ROT == 0 || _ROT == 180 - #define LED_IND(X,Y) _LED_IND(X,Y) - #elif _ROT == 90 || _ROT == 270 - #define LED_IND(X,Y) _LED_IND(Y,X) - #endif -#endif - -#define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y)); }while(0) -#define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y)); }while(0) -#define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0) -#define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y)) - -#ifdef CPU_32_BIT - #define SIG_DELAY() DELAY_US(1) // Approximate a 1µs delay on 32-bit ARM - #undef CRITICAL_SECTION_START - #undef CRITICAL_SECTION_END - #define CRITICAL_SECTION_START() NOOP - #define CRITICAL_SECTION_END() NOOP -#else - #define SIG_DELAY() DELAY_NS(250) -#endif - -void Max7219::error(FSTR_P const func, const int32_t v1, const int32_t v2/*=-1*/) { - #if ENABLED(MAX7219_ERRORS) - SERIAL_ECHOPGM("??? Max7219::"); - SERIAL_ECHOF(func, AS_CHAR('(')); - SERIAL_ECHO(v1); - if (v2 > 0) SERIAL_ECHOPGM(", ", v2); - SERIAL_CHAR(')'); - SERIAL_EOL(); - #else - UNUSED(func); UNUSED(v1); UNUSED(v2); - #endif -} - -/** - * Flip the lowest n_bytes of the supplied bits: - * flipped(x, 1) flips the low 8 bits of x. - * flipped(x, 2) flips the low 16 bits of x. - * flipped(x, 3) flips the low 24 bits of x. - * flipped(x, 4) flips the low 32 bits of x. - */ -inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) { - uint32_t mask = 1, outbits = 0; - LOOP_L_N(b, n_bytes * 8) { - outbits <<= 1; - if (bits & mask) outbits |= 1; - mask <<= 1; - } - return outbits; -} - -void Max7219::noop() { - CRITICAL_SECTION_START(); - SIG_DELAY(); - WRITE(MAX7219_DIN_PIN, LOW); - for (uint8_t i = 16; i--;) { - SIG_DELAY(); - WRITE(MAX7219_CLK_PIN, LOW); - SIG_DELAY(); - SIG_DELAY(); - WRITE(MAX7219_CLK_PIN, HIGH); - SIG_DELAY(); - } - CRITICAL_SECTION_END(); -} - -void Max7219::putbyte(uint8_t data) { - CRITICAL_SECTION_START(); - for (uint8_t i = 8; i--;) { - SIG_DELAY(); - WRITE(MAX7219_CLK_PIN, LOW); // tick - SIG_DELAY(); - WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit - SIG_DELAY(); - WRITE(MAX7219_CLK_PIN, HIGH); // tock - SIG_DELAY(); - data <<= 1; - } - CRITICAL_SECTION_END(); -} - -void Max7219::pulse_load() { - SIG_DELAY(); - WRITE(MAX7219_LOAD_PIN, LOW); // tell the chip to load the data - SIG_DELAY(); - WRITE(MAX7219_LOAD_PIN, HIGH); - SIG_DELAY(); -} - -void Max7219::send(const uint8_t reg, const uint8_t data) { - SIG_DELAY(); - CRITICAL_SECTION_START(); - SIG_DELAY(); - putbyte(reg); // specify register - SIG_DELAY(); - putbyte(data); // put data - CRITICAL_SECTION_END(); -} - -// Send out a single native row of bits to just one unit -void Max7219::refresh_unit_line(const uint8_t line) { - if (suspended) return; - #if MAX7219_NUMBER_UNITS == 1 - send(LINE_REG(line), led_line[line]); - #else - for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) - if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop(); - #endif - pulse_load(); -} - -// Send out a single native row of bits to all units -void Max7219::refresh_line(const uint8_t line) { - if (suspended) return; - #if MAX7219_NUMBER_UNITS == 1 - refresh_unit_line(line); - #else - for (uint8_t u = MAX7219_NUMBER_UNITS; u--;) - send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]); - #endif - pulse_load(); -} - -void Max7219::set(const uint8_t line, const uint8_t bits) { - led_line[line] = bits; - refresh_unit_line(line); -} - -#if ENABLED(MAX7219_NUMERIC) - - // Draw an integer with optional leading zeros and optional decimal point - void Max7219::print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) { - if (suspended) return; - constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A }, - led_decimal = 0x80, led_minus = 0x01; - bool blank = false, neg = value < 0; - if (neg) value *= -1; - while (size--) { - const bool minus = neg && blank; - if (minus) neg = false; - send( - max7219_reg_digit0 + start + size, - minus ? led_minus : blank ? 0x00 : led_numeral[value % 10] | (dec ? led_decimal : 0x00) - ); - pulse_load(); // tell the chips to load the clocked out data - value /= 10; - if (!value && !leadzero) blank = true; - dec = false; - } - } - - // Draw a float with a decimal point and optional digits - void Max7219::print(const uint8_t start, const_float_t value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) { - if (pre_size) print(start, value, pre_size, leadzero, !!post_size); - if (post_size) { - const int16_t after = ABS(value) * (10 ^ post_size); - print(start + pre_size, after, post_size, true); - } - } - -#endif // MAX7219_NUMERIC - -// Modify a single LED bit and send the changed line -void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) { - if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_set"), x, y); - if (BIT_7219(x, y) == on) return; - XOR_7219(x, y); - refresh_unit_line(LED_IND(x, y)); -} - -void Max7219::led_on(const uint8_t x, const uint8_t y) { - if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_on"), x, y); - led_set(x, y, true); -} - -void Max7219::led_off(const uint8_t x, const uint8_t y) { - if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_off"), x, y); - led_set(x, y, false); -} - -void Max7219::led_toggle(const uint8_t x, const uint8_t y) { - if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_toggle"), x, y); - led_set(x, y, !BIT_7219(x, y)); -} - -void Max7219::send_row(const uint8_t row) { - if (suspended) return; - #if _ROT == 0 || _ROT == 180 // Native Lines are horizontal too - #if MAX7219_X_LEDS <= 8 - refresh_unit_line(LED_IND(0, row)); // A single unit line - #else - refresh_line(LED_IND(0, row)); // Same line, all units - #endif - #else // Native lines are vertical - UNUSED(row); - refresh(); // Actually a column - #endif -} - -void Max7219::send_column(const uint8_t col) { - if (suspended) return; - #if _ROT == 90 || _ROT == 270 // Native Lines are vertical too - #if MAX7219_Y_LEDS <= 8 - refresh_unit_line(LED_IND(col, 0)); // A single unit line - #else - refresh_line(LED_IND(col, 0)); // Same line, all units - #endif - #else // Native lines are horizontal - UNUSED(col); - refresh(); // Actually a row - #endif -} - -void Max7219::clear() { - ZERO(led_line); - refresh(); -} - -void Max7219::fill() { - memset(led_line, 0xFF, sizeof(led_line)); - refresh(); -} - -void Max7219::clear_row(const uint8_t row) { - if (row >= MAX7219_Y_LEDS) return error(F("clear_row"), row); - LOOP_L_N(x, MAX7219_X_LEDS) CLR_7219(x, row); - send_row(row); -} - -void Max7219::clear_column(const uint8_t col) { - if (col >= MAX7219_X_LEDS) return error(F("set_column"), col); - LOOP_L_N(y, MAX7219_Y_LEDS) CLR_7219(col, y); - send_column(col); -} - -/** - * Plot the low order bits of val to the specified row of the matrix. - * With 4 Max7219 units in the chain, it's possible to set 32 bits at - * once with a single call to the function (if rotated 90° or 270°). - */ -void Max7219::set_row(const uint8_t row, const uint32_t val) { - if (row >= MAX7219_Y_LEDS) return error(F("set_row"), row); - uint32_t mask = _BV32(MAX7219_X_LEDS - 1); - LOOP_L_N(x, MAX7219_X_LEDS) { - if (val & mask) SET_7219(x, row); else CLR_7219(x, row); - mask >>= 1; - } - send_row(row); -} - -/** - * Plot the low order bits of val to the specified column of the matrix. - * With 4 Max7219 units in the chain, it's possible to set 32 bits at - * once with a single call to the function (if rotated 0° or 180°). - */ -void Max7219::set_column(const uint8_t col, const uint32_t val) { - if (col >= MAX7219_X_LEDS) return error(F("set_column"), col); - uint32_t mask = _BV32(MAX7219_Y_LEDS - 1); - LOOP_L_N(y, MAX7219_Y_LEDS) { - if (val & mask) SET_7219(col, y); else CLR_7219(col, y); - mask >>= 1; - } - send_column(col); -} - -void Max7219::set_rows_16bits(const uint8_t y, uint32_t val) { - #if MAX7219_X_LEDS == 8 - if (y > MAX7219_Y_LEDS - 2) return error(F("set_rows_16bits"), y, val); - set_row(y + 1, val); val >>= 8; - set_row(y + 0, val); - #else // at least 16 bits on each row - if (y > MAX7219_Y_LEDS - 1) return error(F("set_rows_16bits"), y, val); - set_row(y, val); - #endif -} - -void Max7219::set_rows_32bits(const uint8_t y, uint32_t val) { - #if MAX7219_X_LEDS == 8 - if (y > MAX7219_Y_LEDS - 4) return error(F("set_rows_32bits"), y, val); - set_row(y + 3, val); val >>= 8; - set_row(y + 2, val); val >>= 8; - set_row(y + 1, val); val >>= 8; - set_row(y + 0, val); - #elif MAX7219_X_LEDS == 16 - if (y > MAX7219_Y_LEDS - 2) return error(F("set_rows_32bits"), y, val); - set_row(y + 1, val); val >>= 16; - set_row(y + 0, val); - #else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits - if (y > MAX7219_Y_LEDS - 1) return error(F("set_rows_32bits"), y, val); - set_row(y, val); - #endif -} - -void Max7219::set_columns_16bits(const uint8_t x, uint32_t val) { - #if MAX7219_Y_LEDS == 8 - if (x > MAX7219_X_LEDS - 2) return error(F("set_columns_16bits"), x, val); - set_column(x + 0, val); val >>= 8; - set_column(x + 1, val); - #else // at least 16 bits in each column - if (x > MAX7219_X_LEDS - 1) return error(F("set_columns_16bits"), x, val); - set_column(x, val); - #endif -} - -void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) { - #if MAX7219_Y_LEDS == 8 - if (x > MAX7219_X_LEDS - 4) return error(F("set_rows_32bits"), x, val); - set_column(x + 3, val); val >>= 8; - set_column(x + 2, val); val >>= 8; - set_column(x + 1, val); val >>= 8; - set_column(x + 0, val); - #elif MAX7219_Y_LEDS == 16 - if (x > MAX7219_X_LEDS - 2) return error(F("set_rows_32bits"), x, val); - set_column(x + 1, val); val >>= 16; - set_column(x + 0, val); - #else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits - if (x > MAX7219_X_LEDS - 1) return error(F("set_rows_32bits"), x, val); - set_column(x, val); - #endif -} - -// Initialize the Max7219 -void Max7219::register_setup() { - LOOP_L_N(i, MAX7219_NUMBER_UNITS) - send(max7219_reg_scanLimit, 0x07); - pulse_load(); // Tell the chips to load the clocked out data - - LOOP_L_N(i, MAX7219_NUMBER_UNITS) - send(max7219_reg_decodeMode, 0x00); // Using an led matrix (not digits) - pulse_load(); // Tell the chips to load the clocked out data - - LOOP_L_N(i, MAX7219_NUMBER_UNITS) - send(max7219_reg_shutdown, 0x01); // Not in shutdown mode - pulse_load(); // Tell the chips to load the clocked out data - - LOOP_L_N(i, MAX7219_NUMBER_UNITS) - send(max7219_reg_displayTest, 0x00); // No display test - pulse_load(); // Tell the chips to load the clocked out data - - LOOP_L_N(i, MAX7219_NUMBER_UNITS) - send(max7219_reg_intensity, 0x01 & 0x0F); // The first 0x0F is the value you can set - // Range: 0x00 to 0x0F - pulse_load(); // Tell the chips to load the clocked out data -} - -#ifdef MAX7219_INIT_TEST - - uint8_t test_mode = 0; - millis_t next_patt_ms; - bool patt_on; - - #if MAX7219_INIT_TEST == 2 - - #define MAX7219_LEDS (MAX7219_X_LEDS * MAX7219_Y_LEDS) - - constexpr millis_t pattern_delay = 4; - - int8_t spiralx, spiraly, spiral_dir; - IF<(MAX7219_LEDS > 255), uint16_t, uint8_t>::type spiral_count; - - void Max7219::test_pattern() { - constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; - led_set(spiralx, spiraly, patt_on); - const int8_t x = spiralx + way[spiral_dir][0], y = spiraly + way[spiral_dir][1]; - if (!WITHIN(x, 0, MAX7219_X_LEDS - 1) || !WITHIN(y, 0, MAX7219_Y_LEDS - 1) || BIT_7219(x, y) == patt_on) - spiral_dir = (spiral_dir + 1) & 0x3; - spiralx += way[spiral_dir][0]; - spiraly += way[spiral_dir][1]; - if (!spiral_count--) { - if (!patt_on) - test_mode = 0; - else { - spiral_count = MAX7219_LEDS; - spiralx = spiraly = spiral_dir = 0; - patt_on = false; - } - } - } - - #else - - constexpr millis_t pattern_delay = 20; - int8_t sweep_count, sweepx, sweep_dir; - - void Max7219::test_pattern() { - set_column(sweepx, patt_on ? 0xFFFFFFFF : 0x00000000); - sweepx += sweep_dir; - if (!WITHIN(sweepx, 0, MAX7219_X_LEDS - 1)) { - if (!patt_on) { - sweep_dir *= -1; - sweepx += sweep_dir; - } - else - sweepx -= MAX7219_X_LEDS * sweep_dir; - patt_on ^= true; - next_patt_ms += 100; - if (++test_mode > 4) test_mode = 0; - } - } - - #endif - - void Max7219::run_test_pattern() { - const millis_t ms = millis(); - if (PENDING(ms, next_patt_ms)) return; - next_patt_ms = ms + pattern_delay; - test_pattern(); - } - - void Max7219::start_test_pattern() { - clear(); - test_mode = 1; - patt_on = true; - #if MAX7219_INIT_TEST == 2 - spiralx = spiraly = spiral_dir = 0; - spiral_count = MAX7219_LEDS; - #else - sweep_dir = 1; - sweepx = 0; - sweep_count = MAX7219_X_LEDS; - #endif - } - -#endif // MAX7219_INIT_TEST - -void Max7219::init() { - SET_OUTPUT(MAX7219_DIN_PIN); - SET_OUTPUT(MAX7219_CLK_PIN); - OUT_WRITE(MAX7219_LOAD_PIN, HIGH); - delay(1); - - register_setup(); - - LOOP_LE_N(i, 7) { // Empty registers to turn all LEDs off - led_line[i] = 0x00; - send(max7219_reg_digit0 + i, 0); - pulse_load(); // Tell the chips to load the clocked out data - } - - #ifdef MAX7219_INIT_TEST - start_test_pattern(); - #endif -} - -/** - * This code demonstrates some simple debugging using a single 8x8 LED Matrix. If your feature could - * benefit from matrix display, add its code here. Very little processing is required, so the 7219 is - * ideal for debugging when realtime feedback is important but serial output can't be used. - */ - -// Apply changes to update a marker -void Max7219::mark16(const uint8_t pos, const uint8_t v1, const uint8_t v2) { - #if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line. - led_off(v1 & 0xF, pos); - led_on(v2 & 0xF, pos); - #elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column. - led_off(pos, v1 & 0xF); - led_on(pos, v2 & 0xF); - #else // Single 8x8 LED matrix. Use two lines to get 16 LEDs. - led_off(v1 & 0x7, pos + (v1 >= 8)); - led_on(v2 & 0x7, pos + (v2 >= 8)); - #endif -} - -// Apply changes to update a tail-to-head range -void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) { - #if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line. - if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF) - led_off(n & 0xF, y); - if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF) - led_on(n & 0xF, y); - #elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column. - if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF) - led_off(y, n & 0xF); - if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF) - led_on(y, n & 0xF); - #else // Single 8x8 LED matrix. Use two lines to get 16 LEDs. - if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF) - led_off(n & 0x7, y + (n >= 8)); - if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF) - led_on(n & 0x7, y + (n >= 8)); - #endif -} - -// Apply changes to update a quantity -void Max7219::quantity16(const uint8_t pos, const uint8_t ov, const uint8_t nv) { - for (uint8_t i = _MIN(nv, ov); i < _MAX(nv, ov); i++) - led_set( - #if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line. - i, pos - #elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column. - pos, i - #else // Single 8x8 LED matrix. Use two lines to get 16 LEDs. - i >> 1, pos + (i & 1) - #endif - , nv >= ov - ); -} - -void Max7219::idle_tasks() { - #define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE)) - #define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE)) - #if MAX7219_USE_HEAD || MAX7219_USE_TAIL - CRITICAL_SECTION_START(); - #if MAX7219_USE_HEAD - const uint8_t head = planner.block_buffer_head; - #endif - #if MAX7219_USE_TAIL - const uint8_t tail = planner.block_buffer_tail; - #endif - CRITICAL_SECTION_END(); - #endif - - #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) - static uint8_t refresh_cnt; // = 0 - constexpr uint16_t refresh_limit = 5; - static millis_t next_blink = 0; - const millis_t ms = millis(); - const bool do_blink = ELAPSED(ms, next_blink); - #else - static uint16_t refresh_cnt; // = 0 - constexpr bool do_blink = true; - constexpr uint16_t refresh_limit = 50000; - #endif - - // Some Max7219 units are vulnerable to electrical noise, especially - // with long wires next to high current wires. If the display becomes - // corrupted, this will fix it within a couple seconds. - if (do_blink && ++refresh_cnt >= refresh_limit) { - refresh_cnt = 0; - register_setup(); - } - - #ifdef MAX7219_INIT_TEST - if (test_mode) { - run_test_pattern(); - return; - } - #endif - - #if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE) - if (do_blink) { - led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1); - next_blink = ms + 1000; - } - #endif - - #if defined(MAX7219_DEBUG_PLANNER_HEAD) && defined(MAX7219_DEBUG_PLANNER_TAIL) && MAX7219_DEBUG_PLANNER_HEAD == MAX7219_DEBUG_PLANNER_TAIL - - static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF; - - if (last_head_cnt != head || last_tail_cnt != tail) { - range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head); - last_head_cnt = head; - last_tail_cnt = tail; - } - - #else - - #ifdef MAX7219_DEBUG_PLANNER_HEAD - static int16_t last_head_cnt = 0x1; - if (last_head_cnt != head) { - mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head); - last_head_cnt = head; - } - #endif - - #ifdef MAX7219_DEBUG_PLANNER_TAIL - static int16_t last_tail_cnt = 0x1; - if (last_tail_cnt != tail) { - mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail); - last_tail_cnt = tail; - } - #endif - - #endif - - #ifdef MAX7219_DEBUG_PLANNER_QUEUE - static int16_t last_depth = 0; - const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF; - if (current_depth != last_depth) { - quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth); - last_depth = current_depth; - } - #endif - - // After resume() automatically do a refresh() - if (suspended == 0x80) { - suspended = 0; - refresh(); - } -} - -#endif // MAX7219_DEBUG diff --git a/src/feature/max7219.h b/src/feature/max7219.h deleted file mode 100644 index 809bda6..0000000 --- a/src/feature/max7219.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * This module is off by default, but can be enabled to facilitate the display of - * extra debug information during code development. - * - * 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. - * - * If you are using the Max7219 matrix for firmware debug purposes in time sensitive - * areas of the code, please be aware that the orientation (rotation) of the display can - * affect the speed. The Max7219 can update a single column fairly fast. It is much - * faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do - * a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees. - */ - -#include "../inc/MarlinConfig.h" - -#ifndef MAX7219_ROTATE - #define MAX7219_ROTATE 0 -#endif -#define _ROT ((MAX7219_ROTATE + 360) % 360) - -#ifndef MAX7219_NUMBER_UNITS - #define MAX7219_NUMBER_UNITS 1 -#endif -#define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS)) - -// -// 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_decodeMode 0x09 -#define max7219_reg_intensity 0x0A -#define max7219_reg_scanLimit 0x0B -#define max7219_reg_shutdown 0x0C -#define max7219_reg_displayTest 0x0F - -class Max7219 { -public: - static uint8_t led_line[MAX7219_LINES]; - - Max7219() {} - - static void init(); - static void register_setup(); - static void putbyte(uint8_t data); - static void pulse_load(); - - // Set a single register (e.g., a whole native row) - static void send(const uint8_t reg, const uint8_t data); - - // Refresh all units - static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); } - - // Suspend / resume updates to the LED unit - // Use these methods to speed up multiple changes - // or to apply updates from interrupt context. - static void suspend() { suspended++; } - static void resume() { suspended--; suspended |= 0x80; } - - // Update a single native line on all units - static void refresh_line(const uint8_t line); - - // Update a single native line on just one unit - static void refresh_unit_line(const uint8_t line); - - #if ENABLED(MAX7219_NUMERIC) - // Draw an integer with optional leading zeros and optional decimal point - void print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false); - // Draw a float with a decimal point and optional digits - void print(const uint8_t start, const_float_t value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false); - #endif - - // Set a single LED by XY coordinate - static void led_set(const uint8_t x, const uint8_t y, const bool on); - static void led_on(const uint8_t x, const uint8_t y); - static void led_off(const uint8_t x, const uint8_t y); - static void led_toggle(const uint8_t x, const uint8_t y); - - // Set all LEDs in a single column - static void set_column(const uint8_t col, const uint32_t val); - static void clear_column(const uint8_t col); - - // Set all LEDs in a single row - static void set_row(const uint8_t row, const uint32_t val); - static void clear_row(const uint8_t row); - - // 16 and 32 bit versions of Row and Column functions - // Multiple rows and columns will be used to display the value if - // the array of matrix LED's is too narrow to accomplish the goal - static void set_rows_16bits(const uint8_t y, uint32_t val); - static void set_rows_32bits(const uint8_t y, uint32_t val); - static void set_columns_16bits(const uint8_t x, uint32_t val); - static void set_columns_32bits(const uint8_t x, uint32_t val); - - // Quickly clear the whole matrix - static void clear(); - - // Quickly fill the whole matrix - static void fill(); - - // Apply custom code to update the matrix - static void idle_tasks(); - -private: - static uint8_t suspended; - static void error(FSTR_P const func, const int32_t v1, const int32_t v2=-1); - static void noop(); - static void set(const uint8_t line, const uint8_t bits); - static void send_row(const uint8_t row); - static void send_column(const uint8_t col); - static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2); - static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh); - static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv); - - #ifdef MAX7219_INIT_TEST - static void test_pattern(); - static void run_test_pattern(); - static void start_test_pattern(); - #endif -}; - -extern Max7219 max7219; diff --git a/src/feature/meatpack.cpp b/src/feature/meatpack.cpp deleted file mode 100644 index 07ff41e..0000000 --- a/src/feature/meatpack.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * MeatPack G-code Compression - * - * Algorithm & Implementation: Scott Mudge - mail@scottmudge.com - * Date: Dec. 2020 - * - * Character Frequencies from ~30 MB of comment-stripped G-code: - * '1' -> 4451136 '4' -> 1353273 '\n' -> 1087683 '-' -> 90242 - * '0' -> 4253577 '9' -> 1352147 'G' -> 1075806 'Z' -> 34109 - * ' ' -> 3053297 '3' -> 1262929 'X' -> 975742 'M' -> 11879 - * '.' -> 3035310 '5' -> 1189871 'E' -> 965275 'S' -> 9910 - * '2' -> 1523296 '6' -> 1127900 'Y' -> 965274 - * '8' -> 1366812 '7' -> 1112908 'F' -> 99416 - * - * When space is omitted the letter 'E' is used in its place - */ - -#include "../inc/MarlinConfig.h" - -#if HAS_MEATPACK - -#include "meatpack.h" - -#define MeatPack_ProtocolVersion "PV01" -//#define MP_DEBUG - -#define DEBUG_OUT ENABLED(MP_DEBUG) -#include "../core/debug_out.h" - -// The 15 most-common characters used in G-code, ~90-95% of all G-code uses these characters -// Stored in SRAM for performance. -uint8_t meatPackLookupTable[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '.', ' ', '\n', 'G', 'X', - '\0' // Unused. 0b1111 indicates a literal character -}; - -#if ENABLED(MP_DEBUG) - uint8_t chars_decoded = 0; // Log the first 64 bytes after each reset -#endif - -void MeatPack::reset_state() { - state = 0; - cmd_is_next = false; - second_char = 0; - cmd_count = full_char_count = char_out_count = 0; - TERN_(MP_DEBUG, chars_decoded = 0); -} - -/** - * Unpack one or two characters from a packed byte into a buffer. - * Return flags indicating whether any literal bytes follow. - */ -uint8_t MeatPack::unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out) { - uint8_t out = 0; - - // If lower nybble is 1111, the higher nybble is unused, and next char is full. - if ((pk & kFirstNotPacked) == kFirstNotPacked) - out = kFirstCharIsLiteral; - else { - const uint8_t chr = pk & 0x0F; - chars_out[0] = meatPackLookupTable[chr]; // Set the first char - } - - // Check if upper nybble is 1111... if so, we don't need the second char. - if ((pk & kSecondNotPacked) == kSecondNotPacked) - out |= kSecondCharIsLiteral; - else { - const uint8_t chr = (pk >> 4) & 0x0F; - chars_out[1] = meatPackLookupTable[chr]; // Set the second char - } - - return out; -} - -/** - * Interpret a single (non-command) character - * according to the current MeatPack state. - */ -void MeatPack::handle_rx_char_inner(const uint8_t c) { - if (TEST(state, MPConfig_Bit_Active)) { // Is MeatPack active? - if (!full_char_count) { // No literal characters to fetch? - uint8_t buf[2] = { 0, 0 }; - const uint8_t res = unpack_chars(c, buf); // Decode the byte into one or two characters. - if (res & kFirstCharIsLiteral) { // The 1st character couldn't be packed. - ++full_char_count; // So the next stream byte is a full character. - if (res & kSecondCharIsLiteral) ++full_char_count; // The 2nd character couldn't be packed. Another stream byte is a full character. - else second_char = buf[1]; // Retain the unpacked second character. - } - else { - handle_output_char(buf[0]); // Send the unpacked first character out. - if (buf[0] != '\n') { // After a newline the next char won't be set - if (res & kSecondCharIsLiteral) ++full_char_count; // The 2nd character couldn't be packed. The next stream byte is a full character. - else handle_output_char(buf[1]); // Send the unpacked second character out. - } - } - } - else { - handle_output_char(c); // Pass through the character that couldn't be packed... - if (second_char) { - handle_output_char(second_char); // ...and send an unpacked 2nd character, if set. - second_char = 0; - } - --full_char_count; // One literal character was consumed - } - } - else // Packing not enabled, just copy character to output - handle_output_char(c); -} - -/** - * Buffer a single output character which will be picked up in - * GCodeQueue::get_serial_commands via calls to get_result_char - */ -void MeatPack::handle_output_char(const uint8_t c) { - char_out_buf[char_out_count++] = c; - - #if ENABLED(MP_DEBUG) - if (chars_decoded < 1024) { - ++chars_decoded; - DEBUG_ECHOLNPGM("RB: ", AS_CHAR(c)); - } - #endif -} - -/** - * Process a MeatPack command byte to update the state. - * Report the new state to serial. - */ -void MeatPack::handle_command(const MeatPack_Command c) { - switch (c) { - case MPCommand_QueryConfig: break; - case MPCommand_EnablePacking: SBI(state, MPConfig_Bit_Active); DEBUG_ECHOLNPGM("[MPDBG] ENA REC"); break; - case MPCommand_DisablePacking: CBI(state, MPConfig_Bit_Active); DEBUG_ECHOLNPGM("[MPDBG] DIS REC"); break; - case MPCommand_ResetAll: reset_state(); DEBUG_ECHOLNPGM("[MPDBG] RESET REC"); break; - case MPCommand_EnableNoSpaces: - SBI(state, MPConfig_Bit_NoSpaces); - meatPackLookupTable[kSpaceCharIdx] = kSpaceCharReplace; DEBUG_ECHOLNPGM("[MPDBG] ENA NSP"); break; - case MPCommand_DisableNoSpaces: - CBI(state, MPConfig_Bit_NoSpaces); - meatPackLookupTable[kSpaceCharIdx] = ' '; DEBUG_ECHOLNPGM("[MPDBG] DIS NSP"); break; - default: DEBUG_ECHOLNPGM("[MPDBG] UNK CMD REC"); - } - report_state(); -} - -void MeatPack::report_state() { - // NOTE: if any configuration vars are added below, the outgoing sync text for host plugin - // should not contain the "PV' substring, as this is used to indicate protocol version - SERIAL_ECHOPGM("[MP] " MeatPack_ProtocolVersion " "); - serialprint_onoff(TEST(state, MPConfig_Bit_Active)); - SERIAL_ECHOF(TEST(state, MPConfig_Bit_NoSpaces) ? F(" NSP\n") : F(" ESP\n")); -} - -/** - * Interpret a single character received from serial - * according to the current meatpack state. - */ -void MeatPack::handle_rx_char(const uint8_t c, const serial_index_t serial_ind) { - if (c == kCommandByte) { // A command (0xFF) byte? - if (cmd_count) { // In fact, two in a row? - cmd_is_next = true; // Then a MeatPack command follows - cmd_count = 0; - } - else - ++cmd_count; // cmd_count = 1 // One command byte received so far... - return; - } - - if (cmd_is_next) { // Were two command bytes received? - PORT_REDIRECT(SERIAL_PORTMASK(serial_ind)); - handle_command((MeatPack_Command)c); // Then the byte is a MeatPack command - cmd_is_next = false; - return; - } - - if (cmd_count) { // Only a single 0xFF was received - handle_rx_char_inner(kCommandByte); // A single 0xFF is passed on literally so it can be interpreted as kFirstNotPacked|kSecondNotPacked - cmd_count = 0; - } - - handle_rx_char_inner(c); // Other characters are passed on for MeatPack decoding -} - -uint8_t MeatPack::get_result_char(char * const __restrict out) { - uint8_t res = 0; - if (char_out_count) { - res = char_out_count; - char_out_count = 0; - for (uint8_t i = 0; i < res; ++i) - out[i] = (char)char_out_buf[i]; - } - return res; -} - -#endif // HAS_MEATPACK diff --git a/src/feature/meatpack.h b/src/feature/meatpack.h deleted file mode 100644 index 98a535e..0000000 --- a/src/feature/meatpack.h +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * MeatPack G-code Compression - * - * Algorithm & Implementation: Scott Mudge - mail@scottmudge.com - * Date: Dec. 2020 - * - * Specifically optimized for 3D printing G-Code, this is a zero-cost data compression method - * which packs ~180-190% more data into the same amount of bytes going to the CNC controller. - * As a majority of G-Code can be represented by a restricted alphabet, I performed histogram - * analysis on a wide variety of 3D printing G-code samples, and found ~93% of all G-code could - * be represented by the same 15-character alphabet. - * - * This allowed me to design a system of packing 2 8-bit characters into a single byte, assuming - * they fall within this limited 15-character alphabet. Using a 4-bit lookup table, these 8-bit - * characters can be represented by a 4-bit index. - * - * Combined with some logic to allow commingling of full-width characters outside of this 15- - * character alphabet (at the cost of an extra 8-bits per full-width character), and by stripping - * out unnecessary comments, the end result is G-code which is roughly half the original size. - * - * Why did I do this? I noticed micro-stuttering and other data-bottleneck issues while printing - * objects with high curvature, especially at high speeds. There is also the issue of the limited - * baud rate provided by Prusa's Atmega2560-based boards, over the USB serial connection. So soft- - * ware like OctoPrint would also suffer this same micro-stuttering and poor print quality issue. - * - */ -#pragma once - -#include -#include "../core/serial_hook.h" - -/** - * Commands sent to MeatPack to control its behavior. - * They are sent by first sending 2x MeatPack_CommandByte (0xFF) in sequence, - * followed by one of the command bytes below. - * Provided that 0xFF is an exceedingly rare character that is virtually never - * present in G-code naturally, it is safe to assume 2 in sequence should never - * happen naturally, and so it is used as a signal here. - * - * 0xFF *IS* used in "packed" G-code (used to denote that the next 2 characters are - * full-width), however 2 in a row will never occur, as the next 2 bytes will always - * some non-0xFF character. - */ -enum MeatPack_Command : uint8_t { - MPCommand_None = 0, - MPCommand_EnablePacking = 0xFB, - MPCommand_DisablePacking = 0xFA, - MPCommand_ResetAll = 0xF9, - MPCommand_QueryConfig = 0xF8, - MPCommand_EnableNoSpaces = 0xF7, - MPCommand_DisableNoSpaces = 0xF6 -}; - -enum MeatPack_ConfigStateBits : uint8_t { - MPConfig_Bit_Active = 0, - MPConfig_Bit_NoSpaces = 1 -}; - -class MeatPack { - - // Utility definitions - static const uint8_t kCommandByte = 0b11111111, - kFirstNotPacked = 0b00001111, - kSecondNotPacked = 0b11110000, - kFirstCharIsLiteral = 0b00000001, - kSecondCharIsLiteral = 0b00000010; - - static const uint8_t kSpaceCharIdx = 11; - static const char kSpaceCharReplace = 'E'; - - bool cmd_is_next; // A command is pending - uint8_t state; // Configuration state - uint8_t second_char; // Buffers a character if dealing with out-of-sequence pairs - uint8_t cmd_count, // Counter of command bytes received (need 2) - full_char_count, // Counter for full-width characters to be received - char_out_count; // Stores number of characters to be read out. - uint8_t char_out_buf[2]; // Output buffer for caching up to 2 characters - -public: - // Pass in a character rx'd by SD card or serial. Automatically parses command/ctrl sequences, - // and will control state internally. - void handle_rx_char(const uint8_t c, const serial_index_t serial_ind); - - /** - * After passing in rx'd char using above method, call this to get characters out. - * Can return from 0 to 2 characters at once. - * @param out [in] Output pointer for unpacked/processed data. - * @return Number of characters returned. Range from 0 to 2. - */ - uint8_t get_result_char(char * const __restrict out); - - void reset_state(); - void report_state(); - uint8_t unpack_chars(const uint8_t pk, uint8_t* __restrict const chars_out); - void handle_command(const MeatPack_Command c); - void handle_output_char(const uint8_t c); - void handle_rx_char_inner(const uint8_t c); - - MeatPack() : cmd_is_next(false), state(0), second_char(0), cmd_count(0), full_char_count(0), char_out_count(0) {} -}; - -// Implement the MeatPack serial class so it's transparent to rest of the code -template -struct MeatpackSerial : public SerialBase > { - typedef SerialBase< MeatpackSerial > BaseClassT; - - SerialT & out; - MeatPack meatpack; - - char serialBuffer[2]; - uint8_t charCount; - uint8_t readIndex; - - NO_INLINE void write(uint8_t c) { out.write(c); } - void flush() { out.flush(); } - void begin(long br) { out.begin(br); readIndex = 0; } - void end() { out.end(); } - - void msgDone() { out.msgDone(); } - // Existing instances implement Arduino's operator bool, so use that if it's available - bool connected() { return Private::HasMember_connected::value ? CALL_IF_EXISTS(bool, &out, connected) : (bool)out; } - void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); } - SerialFeature features(serial_index_t index) const { return SerialFeature::MeatPack | CALL_IF_EXISTS(SerialFeature, &out, features, index); } - - - int available(serial_index_t index) { - if (charCount) return charCount; // The buffer still has data - if (out.available(index) <= 0) return 0; // No data to read - - // Don't read in read method, instead do it here, so we can make progress in the read method - const int r = out.read(index); - if (r == -1) return 0; // This is an error from the underlying serial code - meatpack.handle_rx_char((uint8_t)r, index); - charCount = meatpack.get_result_char(serialBuffer); - readIndex = 0; - - return charCount; - } - - int readImpl(const serial_index_t index) { - // Not enough char to make progress? - if (charCount == 0 && available(index) == 0) return -1; - - charCount--; - return serialBuffer[readIndex++]; - } - - int read(serial_index_t index) { return readImpl(index); } - int available() { return available(0); } - int read() { return readImpl(0); } - - MeatpackSerial(const bool e, SerialT & out) : BaseClassT(e), out(out) {} -}; diff --git a/src/feature/mixing.cpp b/src/feature/mixing.cpp deleted file mode 100644 index b1a069e..0000000 --- a/src/feature/mixing.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(MIXING_EXTRUDER) - -//#define MIXER_NORMALIZER_DEBUG - -#include "mixing.h" - -Mixer mixer; - -#ifdef MIXER_NORMALIZER_DEBUG - #include "../core/serial.h" -#endif - -// Used up to Planner level -uint_fast8_t Mixer::selected_vtool = 0; -float Mixer::collector[MIXING_STEPPERS]; // mix proportion. 0.0 = off, otherwise <= COLOR_A_MASK. -mixer_comp_t Mixer::color[NR_MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS]; - -// Used in Stepper -int_fast8_t Mixer::runner = 0; -mixer_comp_t Mixer::s_color[MIXING_STEPPERS]; -mixer_accu_t Mixer::accu[MIXING_STEPPERS] = { 0 }; - -#if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) - mixer_perc_t Mixer::mix[MIXING_STEPPERS]; -#endif - -void Mixer::normalize(const uint8_t tool_index) { - float cmax = 0; - #ifdef MIXER_NORMALIZER_DEBUG - float csum = 0; - #endif - MIXER_STEPPER_LOOP(i) { - const float v = collector[i]; - NOLESS(cmax, v); - #ifdef MIXER_NORMALIZER_DEBUG - csum += v; - #endif - } - #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("Mixer: Old relation : [ "); - MIXER_STEPPER_LOOP(i) { - SERIAL_DECIMAL(collector[i] / csum); - SERIAL_CHAR(' '); - } - SERIAL_ECHOLNPGM("]"); - #endif - - // Scale all values so their maximum is COLOR_A_MASK - const float scale = float(COLOR_A_MASK) / cmax; - MIXER_STEPPER_LOOP(i) color[tool_index][i] = collector[i] * scale; - - #ifdef MIXER_NORMALIZER_DEBUG - csum = 0; - SERIAL_ECHOPGM("Mixer: Normalize to : [ "); - MIXER_STEPPER_LOOP(i) { - SERIAL_ECHO(uint16_t(color[tool_index][i])); - SERIAL_CHAR(' '); - csum += color[tool_index][i]; - } - SERIAL_ECHOLNPGM("]"); - SERIAL_ECHOPGM("Mixer: New relation : [ "); - MIXER_STEPPER_LOOP(i) { - SERIAL_ECHO_F(uint16_t(color[tool_index][i]) / csum, 3); - SERIAL_CHAR(' '); - } - SERIAL_ECHOLNPGM("]"); - #endif - - TERN_(GRADIENT_MIX, refresh_gradient()); -} - -void Mixer::reset_vtools() { - // Virtual Tools 0, 1, 2, 3 = Filament 1, 2, 3, 4, etc. - // Every virtual tool gets a pure filament - LOOP_L_N(t, _MIN(MIXING_VIRTUAL_TOOLS, MIXING_STEPPERS)) - MIXER_STEPPER_LOOP(i) - color[t][i] = (t == i) ? COLOR_A_MASK : 0; - - // Remaining virtual tools are 100% filament 1 - #if MIXING_VIRTUAL_TOOLS > MIXING_STEPPERS - LOOP_S_L_N(t, MIXING_STEPPERS, MIXING_VIRTUAL_TOOLS) - MIXER_STEPPER_LOOP(i) - color[t][i] = (i == 0) ? COLOR_A_MASK : 0; - #endif - - // MIXING_PRESETS: Set a variety of obvious mixes as presets - #if ENABLED(MIXING_PRESETS) && WITHIN(MIXING_STEPPERS, 2, 3) - #if MIXING_STEPPERS == 2 - if (MIXING_VIRTUAL_TOOLS > 2) { collector[0] = 1; collector[1] = 1; mixer.normalize(2); } // 1:1 - if (MIXING_VIRTUAL_TOOLS > 3) { collector[0] = 3; mixer.normalize(3); } // 3:1 - if (MIXING_VIRTUAL_TOOLS > 4) { collector[0] = 1; collector[1] = 3; mixer.normalize(4); } // 1:3 - if (MIXING_VIRTUAL_TOOLS > 5) { collector[1] = 2; mixer.normalize(5); } // 1:2 - if (MIXING_VIRTUAL_TOOLS > 6) { collector[0] = 2; collector[1] = 1; mixer.normalize(6); } // 2:1 - if (MIXING_VIRTUAL_TOOLS > 7) { collector[0] = 3; collector[1] = 2; mixer.normalize(7); } // 3:2 - #else - if (MIXING_VIRTUAL_TOOLS > 3) { collector[0] = 1; collector[1] = 1; collector[2] = 1; mixer.normalize(3); } // 1:1:1 - if (MIXING_VIRTUAL_TOOLS > 4) { collector[1] = 3; collector[2] = 0; mixer.normalize(4); } // 1:3:0 - if (MIXING_VIRTUAL_TOOLS > 5) { collector[0] = 0; collector[2] = 1; mixer.normalize(5); } // 0:3:1 - if (MIXING_VIRTUAL_TOOLS > 6) { collector[1] = 1; mixer.normalize(6); } // 0:1:1 - if (MIXING_VIRTUAL_TOOLS > 7) { collector[0] = 1; collector[2] = 0; mixer.normalize(7); } // 1:1:0 - #endif - ZERO(collector); - #endif -} - -// called at boot -void Mixer::init() { - - ZERO(collector); - - reset_vtools(); - - #if HAS_MIXER_SYNC_CHANNEL - // AUTORETRACT_TOOL gets the same amount of all filaments - MIXER_STEPPER_LOOP(i) - color[MIXER_AUTORETRACT_TOOL][i] = COLOR_A_MASK; - #endif - - #if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) - update_mix_from_vtool(); - #endif - - TERN_(GRADIENT_MIX, update_gradient_for_planner_z()); -} - -void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/, float (&c)[MIXING_STEPPERS]/*=collector*/) { - float csum = 0, cmax = 0; - MIXER_STEPPER_LOOP(i) { - const float v = color[t][i]; - cmax = _MAX(cmax, v); - csum += v; - } - //SERIAL_ECHOPGM("Mixer::refresh_collector(", proportion, ", ", t, ") cmax=", cmax, " csum=", csum, " color"); - const float inv_prop = proportion / csum; - MIXER_STEPPER_LOOP(i) { - c[i] = color[t][i] * inv_prop; - //SERIAL_ECHOPGM(" [", t, "][", i, "] = ", color[t][i], " (", c[i], ") "); - } - //SERIAL_EOL(); -} - -#if ENABLED(GRADIENT_MIX) - - #include "../module/motion.h" - #include "../module/planner.h" - - gradient_t Mixer::gradient = { - false, // enabled - {0}, // color (array) - 0, 0, // start_z, end_z - 0, 1, // start_vtool, end_vtool - {0}, {0} // start_mix[], end_mix[] - OPTARG(GRADIENT_VTOOL, -1) // vtool_index - }; - - float Mixer::prev_z; // = 0 - - void Mixer::update_gradient_for_z(const_float_t z) { - if (z == prev_z) return; - prev_z = z; - - const float slice = gradient.end_z - gradient.start_z; - - float pct = (z - gradient.start_z) / slice; - NOLESS(pct, 0.0f); NOMORE(pct, 1.0f); - - MIXER_STEPPER_LOOP(i) { - const mixer_perc_t sm = gradient.start_mix[i]; - mix[i] = sm + (gradient.end_mix[i] - sm) * pct; - } - - copy_mix_to_color(gradient.color); - } - - void Mixer::update_gradient_for_planner_z() { - #if ENABLED(DELTA) - get_cartesian_from_steppers(); - update_gradient_for_z(cartes.z); - #else - update_gradient_for_z(planner.get_axis_position_mm(Z_AXIS)); - #endif - } - -#endif // GRADIENT_MIX - -#endif // MIXING_EXTRUDER diff --git a/src/feature/mixing.h b/src/feature/mixing.h deleted file mode 100644 index 85d52d6..0000000 --- a/src/feature/mixing.h +++ /dev/null @@ -1,262 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -//#define MIXER_NORMALIZER_DEBUG - -#ifndef __AVR__ // || HAS_DUAL_MIXING - // Use 16-bit (or fastest) data for the integer mix factors - typedef uint_fast16_t mixer_comp_t; - typedef uint_fast16_t mixer_accu_t; - #define COLOR_A_MASK 0x8000 - #define COLOR_MASK 0x7FFF -#else - // Use 8-bit data for the integer mix factors - // Exactness is sacrificed for speed - #define MIXER_ACCU_SIGNED - typedef uint8_t mixer_comp_t; - typedef int8_t mixer_accu_t; - #define COLOR_A_MASK 0x80 - #define COLOR_MASK 0x7F -#endif - -typedef int8_t mixer_perc_t; - -#ifndef MIXING_VIRTUAL_TOOLS - #define MIXING_VIRTUAL_TOOLS 1 -#endif - -enum MixTool { - FIRST_USER_VIRTUAL_TOOL = 0 - , LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1 - , NR_USER_VIRTUAL_TOOLS - , MIXER_DIRECT_SET_TOOL = NR_USER_VIRTUAL_TOOLS - #if HAS_MIXER_SYNC_CHANNEL - , MIXER_AUTORETRACT_TOOL - #endif - , NR_MIXING_VIRTUAL_TOOLS -}; - -#define MAX_VTOOLS TERN(HAS_MIXER_SYNC_CHANNEL, 254, 255) -static_assert(NR_MIXING_VIRTUAL_TOOLS <= MAX_VTOOLS, "MIXING_VIRTUAL_TOOLS must be <= " STRINGIFY(MAX_VTOOLS) "!"); - -#define MIXER_STEPPER_LOOP(VAR) for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) - -#if ENABLED(GRADIENT_MIX) - - typedef struct { - bool enabled; // This gradient is enabled - mixer_comp_t color[MIXING_STEPPERS]; // The current gradient color - float start_z, end_z; // Region for gradient - int8_t start_vtool, end_vtool; // Start and end virtual tools - mixer_perc_t start_mix[MIXING_STEPPERS], // Start and end mixes from those tools - end_mix[MIXING_STEPPERS]; - #if ENABLED(GRADIENT_VTOOL) - int8_t vtool_index; // Use this virtual tool number as index - #endif - } gradient_t; - -#endif - -/** - * @brief Mixer class - * @details Contains data and behaviors for a Mixing Extruder - */ -class Mixer { - public: - - static float collector[MIXING_STEPPERS]; // M163 components, also editable from LCD - - static void init(); // Populate colors at boot time - - static void reset_vtools(); - static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool, float (&c)[MIXING_STEPPERS]=collector); - - // Used up to Planner level - FORCE_INLINE static void set_collector(const uint8_t c, const float f) { collector[c] = _MAX(f, 0.0f); } - - static void normalize(const uint8_t tool_index); - FORCE_INLINE static void normalize() { normalize(selected_vtool); } - - FORCE_INLINE static uint8_t get_current_vtool() { return selected_vtool; } - - FORCE_INLINE static void T(const uint_fast8_t c) { - selected_vtool = c; - TERN_(GRADIENT_VTOOL, refresh_gradient()); - TERN_(HAS_DUAL_MIXING, update_mix_from_vtool()); - } - - // Used when dealing with blocks - FORCE_INLINE static void populate_block(mixer_comp_t b_color[MIXING_STEPPERS]) { - #if ENABLED(GRADIENT_MIX) - if (gradient.enabled) { - MIXER_STEPPER_LOOP(i) b_color[i] = gradient.color[i]; - return; - } - #endif - MIXER_STEPPER_LOOP(i) b_color[i] = color[selected_vtool][i]; - } - - FORCE_INLINE static void stepper_setup(mixer_comp_t b_color[MIXING_STEPPERS]) { - MIXER_STEPPER_LOOP(i) s_color[i] = b_color[i]; - } - - #if EITHER(HAS_DUAL_MIXING, GRADIENT_MIX) - - static mixer_perc_t mix[MIXING_STEPPERS]; // Scratch array for the Mix in proportion to 100 - - static void copy_mix_to_color(mixer_comp_t (&tcolor)[MIXING_STEPPERS]) { - // Scale each component to the largest one in terms of COLOR_A_MASK - // So the largest component will be COLOR_A_MASK and the other will be in proportion to it - const float scale = (COLOR_A_MASK) * RECIPROCAL(_MAX( - LIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]) - )); - - // Scale all values so their maximum is COLOR_A_MASK - MIXER_STEPPER_LOOP(i) tcolor[i] = mix[i] * scale; - - #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOPGM(" ] to Color [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, tcolor[0], tcolor[1], tcolor[2], tcolor[3], tcolor[4], tcolor[5]); - SERIAL_ECHOLNPGM(" ]"); - #endif - } - - static void update_mix_from_vtool(const uint8_t j=selected_vtool) { - float ctot = 0; - MIXER_STEPPER_LOOP(i) ctot += color[j][i]; - //MIXER_STEPPER_LOOP(i) mix[i] = 100.0f * color[j][i] / ctot; - MIXER_STEPPER_LOOP(i) mix[i] = mixer_perc_t(100.0f * color[j][i] / ctot); - - #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("V-tool ", j, " [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, color[j][0], color[j][1], color[j][2], color[j][3], color[j][4], color[j][5]); - SERIAL_ECHOPGM(" ] to Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOLNPGM(" ]"); - #endif - } - - #endif // HAS_DUAL_MIXING || GRADIENT_MIX - - #if HAS_DUAL_MIXING - - // Update the virtual tool from an edited mix - static void update_vtool_from_mix() { - copy_mix_to_color(color[selected_vtool]); - TERN_(GRADIENT_MIX, refresh_gradient()); - // MIXER_STEPPER_LOOP(i) collector[i] = mix[i]; - // normalize(); - } - - #endif // HAS_DUAL_MIXING - - #if ENABLED(GRADIENT_MIX) - - static gradient_t gradient; - static float prev_z; - - // Update the current mix from the gradient for a given Z - static void update_gradient_for_z(const_float_t z); - static void update_gradient_for_planner_z(); - static void gradient_control(const_float_t z) { - if (gradient.enabled) { - if (z >= gradient.end_z) - T(gradient.end_vtool); - else - update_gradient_for_z(z); - } - } - - static void update_mix_from_gradient() { - float ctot = 0; - MIXER_STEPPER_LOOP(i) ctot += gradient.color[i]; - MIXER_STEPPER_LOOP(i) mix[i] = (mixer_perc_t)CEIL(100.0f * gradient.color[i] / ctot); - - #ifdef MIXER_NORMALIZER_DEBUG - SERIAL_ECHOPGM("Gradient [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, gradient.color[0], gradient.color[1], gradient.color[2], gradient.color[3], gradient.color[4], gradient.color[5]); - SERIAL_ECHOPGM(" ] to Mix [ "); - SERIAL_ECHOLIST_N(MIXING_STEPPERS, mix[0], mix[1], mix[2], mix[3], mix[4], mix[5]); - SERIAL_ECHOLNPGM(" ]"); - #endif - } - - // Refresh the gradient after a change - static void refresh_gradient() { - #if ENABLED(GRADIENT_VTOOL) - const bool is_grd = (gradient.vtool_index == -1 || selected_vtool == (uint8_t)gradient.vtool_index); - #else - constexpr bool is_grd = true; - #endif - gradient.enabled = is_grd && gradient.start_vtool != gradient.end_vtool && gradient.start_z < gradient.end_z; - if (gradient.enabled) { - mixer_perc_t mix_bak[MIXING_STEPPERS]; - COPY(mix_bak, mix); - update_mix_from_vtool(gradient.start_vtool); - COPY(gradient.start_mix, mix); - update_mix_from_vtool(gradient.end_vtool); - COPY(gradient.end_mix, mix); - update_gradient_for_planner_z(); - COPY(mix, mix_bak); - prev_z = -1; - } - } - - #endif // GRADIENT_MIX - - // Used in Stepper - FORCE_INLINE static uint8_t get_stepper() { return runner; } - FORCE_INLINE static uint8_t get_next_stepper() { - for (;;) { - if (--runner < 0) runner = MIXING_STEPPERS - 1; - accu[runner] += s_color[runner]; - if ( - #ifdef MIXER_ACCU_SIGNED - accu[runner] < 0 - #else - accu[runner] & COLOR_A_MASK - #endif - ) { - accu[runner] &= COLOR_MASK; - return runner; - } - } - } - - private: - - // Used up to Planner level - static uint_fast8_t selected_vtool; - static mixer_comp_t color[NR_MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS]; - - // Used in Stepper - static int_fast8_t runner; - static mixer_comp_t s_color[MIXING_STEPPERS]; - static mixer_accu_t accu[MIXING_STEPPERS]; -}; - -extern Mixer mixer; diff --git a/src/feature/mmu/mmu.cpp b/src/feature/mmu/mmu.cpp deleted file mode 100644 index 58c49ed..0000000 --- a/src/feature/mmu/mmu.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_PRUSA_MMU1 - -#include "../../MarlinCore.h" -#include "../../module/planner.h" -#include "../../module/stepper.h" - -void mmu_init() { - SET_OUTPUT(E_MUX0_PIN); - SET_OUTPUT(E_MUX1_PIN); - SET_OUTPUT(E_MUX2_PIN); -} - -void select_multiplexed_stepper(const uint8_t e) { - planner.synchronize(); - stepper.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); -} - -#endif // HAS_PRUSA_MMU1 diff --git a/src/feature/mmu/mmu.h b/src/feature/mmu/mmu.h deleted file mode 100644 index 23742d0..0000000 --- a/src/feature/mmu/mmu.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void mmu_init(); -void select_multiplexed_stepper(const uint8_t e); diff --git a/src/feature/mmu/mmu2-serial-protocol.md b/src/feature/mmu/mmu2-serial-protocol.md deleted file mode 100644 index d8939ae..0000000 --- a/src/feature/mmu/mmu2-serial-protocol.md +++ /dev/null @@ -1,94 +0,0 @@ -Startup sequence -================ - -When initialized, MMU sends - -- MMU => 'start\n' - -We follow with - -- MMU <= 'S1\n' -- MMU => 'ok*Firmware version*\n' -- MMU <= 'S2\n' -- MMU => 'ok*Build number*\n' - -#if (12V_mode) - -- MMU <= 'M1\n' -- MMU => 'ok\n' - -#endif - -- MMU <= 'P0\n' -- MMU => '*FINDA status*\n' - -Now we are sure MMU is available and ready. If there was a timeout or other communication problem somewhere, printer will be killed. - -- *Firmware version* is an integer value, but we don't care about it -- *Build number* is an integer value and has to be >=126, or =>132 if 12V mode is enabled -- *FINDA status* is 1 if the filament is loaded to the extruder, 0 otherwise - - -*Build number* is checked against the required value, if it does not match, printer is halted. - - - -Toolchange -========== - -- MMU <= 'T*Filament index*\n' - -MMU sends - -- MMU => 'ok\n' - -as soon as the filament is fed down to the extruder. We follow with - -- MMU <= 'C0\n' - -MMU will feed a few more millimeters of filament for the extruder gears to grab. -When done, the MMU sends - -- MMU => 'ok\n' - -We don't wait for a response here but immediately continue with the next G-code which should -be one or more extruder moves to feed the filament into the hotend. - - -FINDA status -============ - -- MMU <= 'P0\n' -- MMU => '*FINDA status*\n' - -*FINDA status* is 1 if the is filament loaded to the extruder, 0 otherwise. This could be used as filament runout sensor if probed regularly. - - - -Load filament -============= - -- MMU <= 'L*Filament index*\n' - -MMU will feed filament down to the extruder, when done - -- MMU => 'ok\n' - - -Unload filament -============= - -- MMU <= 'U0\n' - -MMU will retract current filament from the extruder, when done - -- MMU => 'ok\n' - - - -Eject filament -============== - -- MMU <= 'E*Filament index*\n' -- MMU => 'ok\n' - diff --git a/src/feature/mmu/mmu2.cpp b/src/feature/mmu/mmu2.cpp deleted file mode 100644 index a4718b5..0000000 --- a/src/feature/mmu/mmu2.cpp +++ /dev/null @@ -1,1046 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_PRUSA_MMU2 - -#include "mmu2.h" -#include "../../lcd/menu/menu_mmu2.h" - -MMU2 mmu2; - -#include "../../gcode/gcode.h" -#include "../../lcd/marlinui.h" -#include "../../libs/buzzer.h" -#include "../../libs/nozzle.h" -#include "../../module/temperature.h" -#include "../../module/planner.h" -#include "../../module/stepper.h" -#include "../../MarlinCore.h" - -#if ENABLED(HOST_PROMPT_SUPPORT) - #include "../../feature/host_actions.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#endif - -#define DEBUG_OUT ENABLED(MMU2_DEBUG) -#include "../../core/debug_out.h" - -#define MMU_TODELAY 100 -#define MMU_TIMEOUT 10 -#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0) -#define MMU_P0_TIMEOUT 3000UL // Timeout for P0 command: 3seconds - -#define MMU2_COMMAND(S) tx_str(F(S "\n")) - -#if ENABLED(MMU_EXTRUDER_SENSOR) - uint8_t mmu_idl_sens = 0; - static bool mmu_loading_flag = false; -#endif - -#define MMU_CMD_NONE 0 -#define MMU_CMD_T0 0x10 // up to supported filaments -#define MMU_CMD_L0 0x20 // up to supported filaments -#define MMU_CMD_C0 0x30 -#define MMU_CMD_U0 0x40 -#define MMU_CMD_E0 0x50 // up to supported filaments -#define MMU_CMD_R0 0x60 -#define MMU_CMD_F0 0x70 // up to supported filaments - -#define MMU_REQUIRED_FW_BUILDNR TERN(MMU2_MODE_12V, 132, 126) - -#define MMU2_NO_TOOL 99 -#define MMU_BAUD 115200 - -bool MMU2::_enabled, MMU2::ready, MMU2::mmu_print_saved; -#if HAS_PRUSA_MMU2S - bool MMU2::mmu2s_triggered; -#endif -uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder; -int8_t MMU2::state = 0; -volatile int8_t MMU2::finda = 1; -volatile bool MMU2::finda_runout_valid; -int16_t MMU2::version = -1, MMU2::buildnr = -1; -millis_t MMU2::prev_request, MMU2::prev_P0_request; -char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE]; - -struct E_Step { - float extrude; //!< extrude distance in mm - feedRate_t feedRate; //!< feed rate in mm/s -}; - -static constexpr E_Step - ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE } - , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE } - #if HAS_PRUSA_MMU2S - , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE } - , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE } - #endif -; - -MMU2::MMU2() { - rx_buffer[0] = '\0'; -} - -void MMU2::init() { - - set_runout_valid(false); - - #if PIN_EXISTS(MMU2_RST) - WRITE(MMU2_RST_PIN, HIGH); - SET_OUTPUT(MMU2_RST_PIN); - #endif - - MMU2_SERIAL.begin(MMU_BAUD); - extruder = MMU2_NO_TOOL; - - safe_delay(10); - reset(); - rx_buffer[0] = '\0'; - state = -1; -} - -void MMU2::reset() { - DEBUG_ECHOLNPGM("MMU <= reset"); - - #if PIN_EXISTS(MMU2_RST) - WRITE(MMU2_RST_PIN, LOW); - safe_delay(20); - WRITE(MMU2_RST_PIN, HIGH); - #else - MMU2_COMMAND("X0"); // Send soft reset - #endif -} - -uint8_t MMU2::get_current_tool() { - return extruder == MMU2_NO_TOOL ? -1 : extruder; -} - -#if EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) - #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE) -#endif - -void mmu2_attn_buzz(const bool two=false) { - BUZZ(200, 404); - if (two) { BUZZ(10, 0); BUZZ(200, 404); } -} - -void MMU2::mmu_loop() { - - switch (state) { - - case 0: break; - - case -1: - if (rx_start()) { - prev_P0_request = millis(); // Initialize finda sensor timeout - - DEBUG_ECHOLNPGM("MMU => 'start'"); - DEBUG_ECHOLNPGM("MMU <= 'S1'"); - - MMU2_COMMAND("S1"); // Read Version - state = -2; - } - else if (millis() > 30000) { // 30sec after reset disable MMU - SERIAL_ECHOLNPGM("MMU not responding - DISABLED"); - state = 0; - } - break; - - case -2: - if (rx_ok()) { - sscanf(rx_buffer, "%huok\n", &version); - - DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'"); - - MMU2_COMMAND("S2"); // Read Build Number - state = -3; - } - break; - - case -3: - if (rx_ok()) { - sscanf(rx_buffer, "%huok\n", &buildnr); - - DEBUG_ECHOLNPGM("MMU => ", buildnr); - - check_version(); - - #if ENABLED(MMU2_MODE_12V) - DEBUG_ECHOLNPGM("MMU <= 'M1'"); - - MMU2_COMMAND("M1"); // Stealth Mode - state = -5; - - #else - DEBUG_ECHOLNPGM("MMU <= 'P0'"); - - MMU2_COMMAND("P0"); // Read FINDA - state = -4; - #endif - } - break; - - #if ENABLED(MMU2_MODE_12V) - case -5: - // response to M1 - if (rx_ok()) { - DEBUG_ECHOLNPGM("MMU => ok"); - - DEBUG_ECHOLNPGM("MMU <= 'P0'"); - - MMU2_COMMAND("P0"); // Read FINDA - state = -4; - } - break; - #endif - - case -4: - if (rx_ok()) { - sscanf(rx_buffer, "%hhuok\n", &finda); - - DEBUG_ECHOLNPGM("MMU => ", finda, "\nMMU - ENABLED"); - - _enabled = true; - state = 1; - TERN_(HAS_PRUSA_MMU2S, mmu2s_triggered = false); - } - break; - - case 1: - if (cmd) { - if (WITHIN(cmd, MMU_CMD_T0, MMU_CMD_T0 + EXTRUDERS - 1)) { - // tool change - const int filament = cmd - MMU_CMD_T0; - DEBUG_ECHOLNPGM("MMU <= T", filament); - tx_printf(F("T%d\n"), filament); - TERN_(MMU_EXTRUDER_SENSOR, mmu_idl_sens = 1); // enable idler sensor, if any - state = 3; // wait for response - } - else if (WITHIN(cmd, MMU_CMD_L0, MMU_CMD_L0 + EXTRUDERS - 1)) { - // load - const int filament = cmd - MMU_CMD_L0; - DEBUG_ECHOLNPGM("MMU <= L", filament); - tx_printf(F("L%d\n"), filament); - state = 3; // wait for response - } - else if (cmd == MMU_CMD_C0) { - // continue loading - DEBUG_ECHOLNPGM("MMU <= 'C0'"); - MMU2_COMMAND("C0"); - state = 3; // wait for response - } - else if (cmd == MMU_CMD_U0) { - // unload current - DEBUG_ECHOLNPGM("MMU <= 'U0'"); - - MMU2_COMMAND("U0"); - state = 3; // wait for response - } - else if (WITHIN(cmd, MMU_CMD_E0, MMU_CMD_E0 + EXTRUDERS - 1)) { - // eject filament - const int filament = cmd - MMU_CMD_E0; - DEBUG_ECHOLNPGM("MMU <= E", filament); - tx_printf(F("E%d\n"), filament); - state = 3; // wait for response - } - else if (cmd == MMU_CMD_R0) { - // recover after eject - DEBUG_ECHOLNPGM("MMU <= 'R0'"); - MMU2_COMMAND("R0"); - state = 3; // wait for response - } - else if (WITHIN(cmd, MMU_CMD_F0, MMU_CMD_F0 + EXTRUDERS - 1)) { - // filament type - const int filament = cmd - MMU_CMD_F0; - DEBUG_ECHOLNPGM("MMU <= F", filament, " ", cmd_arg); - tx_printf(F("F%d %d\n"), filament, cmd_arg); - state = 3; // wait for response - } - - last_cmd = cmd; - cmd = MMU_CMD_NONE; - } - else if (ELAPSED(millis(), prev_P0_request + 300)) { - MMU2_COMMAND("P0"); // Read FINDA - state = 2; // wait for response - } - - TERN_(HAS_PRUSA_MMU2S, check_filament()); - break; - - case 2: // response to command P0 - if (rx_ok()) { - sscanf(rx_buffer, "%hhuok\n", &finda); - - // This is super annoying. Only activate if necessary - // if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6); - - if (!finda && finda_runout_valid) filament_runout(); - if (cmd == MMU_CMD_NONE) ready = true; - state = 1; - } - else if (ELAPSED(millis(), prev_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s) - state = 1; - - TERN_(HAS_PRUSA_MMU2S, check_filament()); - break; - - case 3: // response to mmu commands - #if ENABLED(MMU_EXTRUDER_SENSOR) - if (mmu_idl_sens) { - if (FILAMENT_PRESENT() && mmu_loading_flag) { - DEBUG_ECHOLNPGM("MMU <= 'A'"); - MMU2_COMMAND("A"); // send 'abort' request - mmu_idl_sens = 0; - DEBUG_ECHOLNPGM("MMU IDLER_SENSOR = 0 - ABORT"); - } - } - #endif - - if (rx_ok()) { - #if HAS_PRUSA_MMU2S - // Respond to C0 MMU command in MMU2S model - const bool keep_trying = !mmu2s_triggered && last_cmd == MMU_CMD_C0; - if (keep_trying) { - // MMU ok received but filament sensor not triggered, retrying... - DEBUG_ECHOLNPGM("MMU => 'ok' (filament not present in gears)"); - DEBUG_ECHOLNPGM("MMU <= 'C0' (keep trying)"); - MMU2_COMMAND("C0"); - } - #else - constexpr bool keep_trying = false; - #endif - - if (!keep_trying) { - DEBUG_ECHOLNPGM("MMU => 'ok'"); - ready = true; - state = 1; - last_cmd = MMU_CMD_NONE; - } - } - else if (ELAPSED(millis(), prev_request + MMU_CMD_TIMEOUT)) { - // resend request after timeout - if (last_cmd) { - DEBUG_ECHOLNPGM("MMU retry"); - cmd = last_cmd; - last_cmd = MMU_CMD_NONE; - } - state = 1; - } - TERN_(HAS_PRUSA_MMU2S, check_filament()); - break; - } -} - -/** - * Check if MMU was started - */ -bool MMU2::rx_start() { - // check for start message - return rx_str(F("start\n")); -} - -/** - * Check if the data received ends with the given string. - */ -bool MMU2::rx_str(FSTR_P fstr) { - PGM_P pstr = FTOP(fstr); - - uint8_t i = strlen(rx_buffer); - - while (MMU2_SERIAL.available()) { - rx_buffer[i++] = MMU2_SERIAL.read(); - - if (i == sizeof(rx_buffer) - 1) { - DEBUG_ECHOLNPGM("rx buffer overrun"); - break; - } - } - rx_buffer[i] = '\0'; - - uint8_t len = strlen_P(pstr); - - if (i < len) return false; - - pstr += len; - - while (len--) { - char c0 = pgm_read_byte(pstr--), c1 = rx_buffer[i--]; - if (c0 == c1) continue; - if (c0 == '\r' && c1 == '\n') continue; // match cr as lf - if (c0 == '\n' && c1 == '\r') continue; // match lf as cr - return false; - } - return true; -} - -/** - * Transfer data to MMU, no argument - */ -void MMU2::tx_str(FSTR_P fstr) { - clear_rx_buffer(); - PGM_P pstr = FTOP(fstr); - while (const char c = pgm_read_byte(pstr)) { MMU2_SERIAL.write(c); pstr++; } - prev_request = millis(); -} - -/** - * Transfer data to MMU, single argument - */ -void MMU2::tx_printf(FSTR_P format, int argument = -1) { - clear_rx_buffer(); - const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument); - LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]); - prev_request = millis(); -} - -/** - * Transfer data to MMU, two arguments - */ -void MMU2::tx_printf(FSTR_P format, int argument1, int argument2) { - clear_rx_buffer(); - const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument1, argument2); - LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]); - prev_request = millis(); -} - -/** - * Empty the rx buffer - */ -void MMU2::clear_rx_buffer() { - while (MMU2_SERIAL.available()) MMU2_SERIAL.read(); - rx_buffer[0] = '\0'; -} - -/** - * Check if we received 'ok' from MMU - */ -bool MMU2::rx_ok() { - if (rx_str(F("ok\n"))) { - prev_P0_request = millis(); - return true; - } - return false; -} - -/** - * Check if MMU has compatible firmware - */ -void MMU2::check_version() { - if (buildnr < MMU_REQUIRED_FW_BUILDNR) { - SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required."); - kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE)); - } -} - -static void mmu2_not_responding() { - LCD_MESSAGE(MSG_MMU2_NOT_RESPONDING); - BUZZ(100, 659); - BUZZ(200, 698); - BUZZ(100, 659); - BUZZ(300, 440); - BUZZ(100, 659); -} - -#if HAS_PRUSA_MMU2S - - bool MMU2::load_to_gears() { - command(MMU_CMD_C0); - manage_response(true, true); - LOOP_L_N(i, MMU2_C0_RETRY) { // Keep loading until filament reaches gears - if (mmu2s_triggered) break; - command(MMU_CMD_C0); - manage_response(true, true); - check_filament(); - } - const bool success = mmu2s_triggered && can_load(); - if (!success) mmu2_not_responding(); - return success; - } - - /** - * Handle tool change - */ - void MMU2::tool_change(const uint8_t index) { - - if (!_enabled) return; - - set_runout_valid(false); - - if (index != extruder) { - - stepper.disable_extruder(); - ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); - - command(MMU_CMD_T0 + index); - manage_response(true, true); - - if (load_to_gears()) { - extruder = index; // filament change is finished - active_extruder = 0; - stepper.enable_extruder(); - SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder); - } - ui.reset_status(); - } - - set_runout_valid(true); - } - - /** - * Handle special T?/Tx/Tc commands - * - * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically - * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. - * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. - */ - void MMU2::tool_change(const char *special) { - if (!_enabled) return; - - set_runout_valid(false); - - switch (*special) { - case '?': { - #if ENABLED(MMU2_MENUS) - const uint8_t index = mmu2_choose_filament(); - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_filament_to_nozzle(index); - #else - ERR_BUZZ(); - #endif - } break; - - case 'x': { - #if ENABLED(MMU2_MENUS) - planner.synchronize(); - const uint8_t index = mmu2_choose_filament(); - stepper.disable_extruder(); - command(MMU_CMD_T0 + index); - manage_response(true, true); - - if (load_to_gears()) { - mmu_loop(); - stepper.enable_extruder(); - extruder = index; - active_extruder = 0; - } - #else - ERR_BUZZ(); - #endif - } break; - - case 'c': { - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_to_nozzle(); - } break; - } - - set_runout_valid(true); - } - -#elif ENABLED(MMU_EXTRUDER_SENSOR) - - /** - * Handle tool change - */ - void MMU2::tool_change(const uint8_t index) { - if (!_enabled) return; - - set_runout_valid(false); - - if (index != extruder) { - stepper.disable_extruder(); - if (FILAMENT_PRESENT()) { - DEBUG_ECHOLNPGM("Unloading\n"); - mmu_loading_flag = false; - command(MMU_CMD_U0); - manage_response(true, true); - } - ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); - mmu_loading_flag = true; - command(MMU_CMD_T0 + index); - manage_response(true, true); - mmu_continue_loading(); - command(MMU_CMD_C0); - extruder = index; - active_extruder = 0; - - stepper.enable_extruder(); - SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder); - - ui.reset_status(); - } - - set_runout_valid(true); - } - - /** - * Handle special T?/Tx/Tc commands - * - * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically - * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. - * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. - */ - void MMU2::tool_change(const char *special) { - if (!_enabled) return; - - set_runout_valid(false); - - switch (*special) { - case '?': { - DEBUG_ECHOLNPGM("case ?\n"); - #if ENABLED(MMU2_MENUS) - uint8_t index = mmu2_choose_filament(); - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_filament_to_nozzle(index); - #else - ERR_BUZZ(); - #endif - } break; - - case 'x': { - DEBUG_ECHOLNPGM("case x\n"); - #if ENABLED(MMU2_MENUS) - planner.synchronize(); - uint8_t index = mmu2_choose_filament(); - stepper.disable_extruder(); - command(MMU_CMD_T0 + index); - manage_response(true, true); - mmu_continue_loading(); - command(MMU_CMD_C0); - mmu_loop(); - - stepper.enable_extruder(); - extruder = index; - active_extruder = 0; - #else - ERR_BUZZ(); - #endif - } break; - - case 'c': { - DEBUG_ECHOLNPGM("case c\n"); - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); - } break; - } - - set_runout_valid(true); - } - - void MMU2::mmu_continue_loading() { - for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) { - DEBUG_ECHOLNPGM("Additional load attempt #", i); - if (FILAMENT_PRESENT()) break; - command(MMU_CMD_C0); - manage_response(true, true); - } - if (!FILAMENT_PRESENT()) { - DEBUG_ECHOLNPGM("Filament never reached sensor, runout"); - filament_runout(); - } - mmu_idl_sens = 0; - } - -#else // !HAS_PRUSA_MMU2S && !MMU_EXTRUDER_SENSOR - - /** - * Handle tool change - */ - void MMU2::tool_change(const uint8_t index) { - if (!_enabled) return; - - set_runout_valid(false); - - if (index != extruder) { - stepper.disable_extruder(); - ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1)); - command(MMU_CMD_T0 + index); - manage_response(true, true); - command(MMU_CMD_C0); - extruder = index; //filament change is finished - active_extruder = 0; - stepper.enable_extruder(); - SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder); - ui.reset_status(); - } - - set_runout_valid(true); - } - - /** - * Handle special T?/Tx/Tc commands - * - * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically - * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load. - * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. - */ - void MMU2::tool_change(const char *special) { - if (!_enabled) return; - - set_runout_valid(false); - - switch (*special) { - case '?': { - DEBUG_ECHOLNPGM("case ?\n"); - #if ENABLED(MMU2_MENUS) - uint8_t index = mmu2_choose_filament(); - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - load_filament_to_nozzle(index); - #else - ERR_BUZZ(); - #endif - } break; - - case 'x': { - DEBUG_ECHOLNPGM("case x\n"); - #if ENABLED(MMU2_MENUS) - planner.synchronize(); - uint8_t index = mmu2_choose_filament(); - stepper.disable_extruder(); - command(MMU_CMD_T0 + index); - manage_response(true, true); - command(MMU_CMD_C0); - mmu_loop(); - - stepper.enable_extruder(); - extruder = index; - active_extruder = 0; - #else - ERR_BUZZ(); - #endif - } break; - - case 'c': { - DEBUG_ECHOLNPGM("case c\n"); - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100); - execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); - } break; - } - - set_runout_valid(true); - } - -#endif // HAS_PRUSA_MMU2S - -/** - * Set next command - */ -void MMU2::command(const uint8_t mmu_cmd) { - if (!_enabled) return; - cmd = mmu_cmd; - ready = false; -} - -/** - * Wait for response from MMU - */ -bool MMU2::get_response() { - while (cmd != MMU_CMD_NONE) idle(); - - while (!ready) { - idle(); - if (state != 3) break; - } - - const bool ret = ready; - ready = false; - - return ret; -} - -/** - * Wait for response and deal with timeout if necessary - */ -void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) { - - constexpr xyz_pos_t park_point = NOZZLE_PARK_POINT; - bool response = false; - mmu_print_saved = false; - xyz_pos_t resume_position; - celsius_t resume_hotend_temp = thermalManager.degTargetHotend(active_extruder); - - KEEPALIVE_STATE(PAUSED_FOR_USER); - - while (!response) { - - response = get_response(); // wait for "ok" from mmu - - if (!response) { // No "ok" was received in reserved time frame, user will fix the issue on mmu unit - if (!mmu_print_saved) { // First occurrence. Save current position, park print head, disable nozzle heater. - - planner.synchronize(); - - mmu_print_saved = true; - - SERIAL_ECHOLNPGM("MMU not responding"); - - resume_hotend_temp = thermalManager.degTargetHotend(active_extruder); - resume_position = current_position; - - if (move_axes && all_axes_homed()) - nozzle.park(0, park_point /*= NOZZLE_PARK_POINT*/); - - if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder); - - mmu2_not_responding(); - } - } - else if (mmu_print_saved) { - SERIAL_ECHOLNPGM("MMU starts responding\n"); - - if (turn_off_nozzle && resume_hotend_temp) { - thermalManager.setTargetHotend(resume_hotend_temp, active_extruder); - LCD_MESSAGE(MSG_HEATING); - ERR_BUZZ(); - - while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(1000); - } - - LCD_MESSAGE(MSG_MMU2_RESUMING); - mmu2_attn_buzz(true); - - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" - - if (move_axes && all_axes_homed()) { - // Move XY to starting position, then Z - do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE)); - - // Move Z_AXIS to saved position - do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE)); - } - - #pragma GCC diagnostic pop - } - } -} - -void MMU2::set_filament_type(const uint8_t index, const uint8_t filamentType) { - if (!_enabled) return; - - cmd_arg = filamentType; - command(MMU_CMD_F0 + index); - - manage_response(true, true); -} - -void MMU2::filament_runout() { - queue.inject(F(MMU2_FILAMENT_RUNOUT_SCRIPT)); - planner.synchronize(); -} - -#if HAS_PRUSA_MMU2S - - void MMU2::check_filament() { - const bool present = FILAMENT_PRESENT(); - if (cmd == MMU_CMD_NONE && last_cmd == MMU_CMD_C0) { - if (present && !mmu2s_triggered) { - DEBUG_ECHOLNPGM("MMU <= 'A'"); - tx_str(F("A\n")); - } - // Slowly spin the extruder during C0 - else { - while (planner.movesplanned() < 3) { - current_position.e += 0.25; - line_to_current_position(MMM_TO_MMS(120)); - } - } - } - mmu2s_triggered = present; - } - - bool MMU2::can_load() { - execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence)); - - int filament_detected_count = 0; - const int steps = (MMU2_CAN_LOAD_RETRACT) / (MMU2_CAN_LOAD_INCREMENT); - DEBUG_ECHOLNPGM("MMU can_load:"); - LOOP_L_N(i, steps) { - execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence)); - check_filament(); // Don't trust the idle function - DEBUG_CHAR(mmu2s_triggered ? 'O' : 'o'); - if (mmu2s_triggered) ++filament_detected_count; - } - - if (filament_detected_count <= steps - (MMU2_CAN_LOAD_DEVIATION) / (MMU2_CAN_LOAD_INCREMENT)) { - DEBUG_ECHOLNPGM(" failed."); - return false; - } - - DEBUG_ECHOLNPGM(" succeeded."); - return true; - } - -#endif - -// Load filament into MMU2 -void MMU2::load_filament(const uint8_t index) { - if (!_enabled) return; - - command(MMU_CMD_L0 + index); - manage_response(false, false); - mmu2_attn_buzz(); -} - -/** - * Switch material and load to nozzle - */ -bool MMU2::load_filament_to_nozzle(const uint8_t index) { - - if (!_enabled) return false; - - if (thermalManager.tooColdToExtrude(active_extruder)) { - mmu2_attn_buzz(); - LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD); - return false; - } - - stepper.disable_extruder(); - command(MMU_CMD_T0 + index); - manage_response(true, true); - - const bool success = load_to_gears(); - if (success) { - mmu_loop(); - extruder = index; - active_extruder = 0; - load_to_nozzle(); - mmu2_attn_buzz(); - } - return success; -} - -/** - * Load filament to nozzle of multimaterial printer - * - * This function is used only after T? (user select filament) and M600 (change filament). - * It is not used after T0 .. T4 command (select filament), in such case, G-code is responsible for loading - * filament to nozzle. - */ -void MMU2::load_to_nozzle() { - execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); -} - -bool MMU2::eject_filament(const uint8_t index, const bool recover) { - - if (!_enabled) return false; - - if (thermalManager.tooColdToExtrude(active_extruder)) { - mmu2_attn_buzz(); - LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD); - return false; - } - - LCD_MESSAGE(MSG_MMU2_EJECTING_FILAMENT); - - stepper.enable_extruder(); - current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED; - line_to_current_position(MMM_TO_MMS(2500)); - planner.synchronize(); - command(MMU_CMD_E0 + index); - manage_response(false, false); - - if (recover) { - LCD_MESSAGE(MSG_MMU2_EJECT_RECOVER); - mmu2_attn_buzz(); - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("MMU2 Eject Recover"), FPSTR(CONTINUE_STR))); - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("MMU2 Eject Recover"))); - TERN_(HAS_RESUME_CONTINUE, wait_for_user_response()); - mmu2_attn_buzz(true); - - command(MMU_CMD_R0); - manage_response(false, false); - } - - ui.reset_status(); - - // no active tool - extruder = MMU2_NO_TOOL; - - set_runout_valid(false); - - mmu2_attn_buzz(); - - stepper.disable_extruder(); - - return true; -} - -/** - * Unload from hotend and retract to MMU - */ -bool MMU2::unload() { - - if (!_enabled) return false; - - if (thermalManager.tooColdToExtrude(active_extruder)) { - mmu2_attn_buzz(); - LCD_ALERTMESSAGE(MSG_HOTEND_TOO_COLD); - return false; - } - - // Unload sequence to optimize shape of the tip of the unloaded filament - execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step)); - - command(MMU_CMD_U0); - manage_response(false, true); - - mmu2_attn_buzz(); - - // no active tool - extruder = MMU2_NO_TOOL; - - set_runout_valid(false); - - return true; -} - -void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) { - - planner.synchronize(); - stepper.enable_extruder(); - - const E_Step* step = sequence; - - LOOP_L_N(i, steps) { - const float es = pgm_read_float(&(step->extrude)); - const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate)); - - DEBUG_ECHO_MSG("E step ", es, "/", fr_mm_m); - - current_position.e += es; - line_to_current_position(MMM_TO_MMS(fr_mm_m)); - planner.synchronize(); - - step++; - } - - stepper.disable_extruder(); -} - -#endif // HAS_PRUSA_MMU2 diff --git a/src/feature/mmu/mmu2.h b/src/feature/mmu/mmu2.h deleted file mode 100644 index 7d3d9ec..0000000 --- a/src/feature/mmu/mmu2.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../inc/MarlinConfig.h" - -#if HAS_FILAMENT_SENSOR - #include "../runout.h" -#endif - -#if SERIAL_USB - #define MMU_RX_SIZE 256 - #define MMU_TX_SIZE 256 -#else - #define MMU_RX_SIZE 16 - #define MMU_TX_SIZE 16 -#endif - -struct E_Step; - -class MMU2 { -public: - MMU2(); - - static void init(); - static void reset(); - static bool enabled() { return _enabled; } - static void mmu_loop(); - static void tool_change(const uint8_t index); - static void tool_change(const char *special); - static uint8_t get_current_tool(); - static void set_filament_type(const uint8_t index, const uint8_t type); - - static bool unload(); - static void load_filament(uint8_t); - static void load_all(); - static bool load_filament_to_nozzle(const uint8_t index); - static bool eject_filament(const uint8_t index, const bool recover); - -private: - static bool rx_str(FSTR_P fstr); - static void tx_str(FSTR_P fstr); - static void tx_printf(FSTR_P ffmt, const int argument); - static void tx_printf(FSTR_P ffmt, const int argument1, const int argument2); - static void clear_rx_buffer(); - - static bool rx_ok(); - static bool rx_start(); - static void check_version(); - - static void command(const uint8_t cmd); - static bool get_response(); - static void manage_response(const bool move_axes, const bool turn_off_nozzle); - - static void load_to_nozzle(); - static void execute_extruder_sequence(const E_Step * sequence, int steps); - - static void filament_runout(); - - #if HAS_PRUSA_MMU2S - static bool mmu2s_triggered; - static void check_filament(); - static bool can_load(); - static bool load_to_gears(); - #else - FORCE_INLINE static bool load_to_gears() { return true; } - #endif - - #if ENABLED(MMU_EXTRUDER_SENSOR) - static void mmu_continue_loading(); - #endif - - static bool _enabled, ready, mmu_print_saved; - - static uint8_t cmd, cmd_arg, last_cmd, extruder; - static int8_t state; - static volatile int8_t finda; - static volatile bool finda_runout_valid; - static int16_t version, buildnr; - static millis_t prev_request, prev_P0_request; - static char rx_buffer[MMU_RX_SIZE], tx_buffer[MMU_TX_SIZE]; - - static void set_runout_valid(const bool valid) { - finda_runout_valid = valid; - #if HAS_FILAMENT_SENSOR - if (valid) runout.reset(); - #endif - } - -}; - -extern MMU2 mmu2; diff --git a/src/feature/password/password.cpp b/src/feature/password/password.cpp deleted file mode 100644 index 1d376cc..0000000 --- a/src/feature/password/password.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(PASSWORD_FEATURE) - -#include "password.h" -#include "../../gcode/gcode.h" -#include "../../core/serial.h" - -Password password; - -// public: -bool Password::is_set, Password::is_locked, Password::did_first_run; // = false -uint32_t Password::value, Password::value_entry; - -// -// Authenticate user with password. -// Called from Setup, after SD Prinitng Stops/Aborts, and M510 -// -void Password::lock_machine() { - is_locked = true; - TERN_(HAS_MARLINUI_MENU, authenticate_user(ui.status_screen, screen_password_entry)); -} - -// -// Authentication check -// -void Password::authentication_check() { - if (value_entry == value) { - is_locked = false; - did_first_run = true; - } - else { - is_locked = true; - SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD); - } - TERN_(HAS_MARLINUI_MENU, authentication_done()); -} - -#endif // PASSWORD_FEATURE diff --git a/src/feature/password/password.h b/src/feature/password/password.h deleted file mode 100644 index 208765b..0000000 --- a/src/feature/password/password.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../../lcd/marlinui.h" - -class Password { -public: - static bool is_set, is_locked, did_first_run; - static uint32_t value, value_entry; - - Password() {} - - static void lock_machine(); - static void authentication_check(); - - #if HAS_MARLINUI_MENU - static void access_menu_password(); - static void authentication_done(); - static void media_gatekeeper(); - - private: - static void authenticate_user(const screenFunc_t, const screenFunc_t); - static void menu_password(); - static void menu_password_entry(); - static void screen_password_entry(); - static void screen_set_password(); - static void start_over(); - - static void digit_entered(); - static void set_password_done(const bool with_set=true); - static void menu_password_report(); - - static void remove_password(); - #endif -}; - -extern Password password; diff --git a/src/feature/pause.cpp b/src/feature/pause.cpp deleted file mode 100644 index 1c2ea59..0000000 --- a/src/feature/pause.cpp +++ /dev/null @@ -1,726 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/pause.cpp - Pause feature support functions - * This may be combined with related G-codes if features are consolidated. - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(ADVANCED_PAUSE_FEATURE) - -//#define DEBUG_PAUSE_RESUME - -#include "../MarlinCore.h" -#include "../gcode/gcode.h" -#include "../module/motion.h" -#include "../module/planner.h" -#include "../module/printcounter.h" -#include "../module/temperature.h" - -#if HAS_EXTRUDERS - #include "../module/stepper.h" -#endif - -#if ENABLED(AUTO_BED_LEVELING_UBL) - #include "bedlevel/bedlevel.h" -#endif - -#if ENABLED(FWRETRACT) - #include "fwretract.h" -#endif - -#if HAS_FILAMENT_SENSOR - #include "runout.h" -#endif - -#if ENABLED(HOST_ACTION_COMMANDS) - #include "host_actions.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../lcd/e3v2/proui/dwin.h" -#endif - -#include "../lcd/marlinui.h" - -#if HAS_SOUND - #include "../libs/buzzer.h" -#endif - -#if ENABLED(POWER_LOSS_RECOVERY) - #include "powerloss.h" -#endif - -#include "../libs/nozzle.h" -#include "pause.h" - -#define DEBUG_OUT ENABLED(DEBUG_PAUSE_RESUME) -#include "../core/debug_out.h" - -// private: - -static xyze_pos_t resume_position; - -#if M600_PURGE_MORE_RESUMABLE - PauseMenuResponse pause_menu_response; - PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT; -#endif - -fil_change_settings_t fc_settings[EXTRUDERS]; - -#if ENABLED(SDSUPPORT) - #include "../sd/cardreader.h" -#endif - -#if ENABLED(EMERGENCY_PARSER) - #define _PMSG(L) L##_M108 -#else - #define _PMSG(L) L##_LCD -#endif - -#if HAS_SOUND - static void impatient_beep(const int8_t max_beep_count, const bool restart=false) { - - if (TERN0(HAS_MARLINUI_MENU, pause_mode == PAUSE_MODE_PAUSE_PRINT)) return; - - static millis_t next_buzz = 0; - static int8_t runout_beep = 0; - - if (restart) next_buzz = runout_beep = 0; - - const bool always = max_beep_count < 0; - - const millis_t ms = millis(); - if (ELAPSED(ms, next_buzz)) { - if (always || runout_beep < max_beep_count + 5) { // Only beep as long as we're supposed to - next_buzz = ms + ((always || runout_beep < max_beep_count) ? 1000 : 500); - BUZZ(50, 880 - (runout_beep & 1) * 220); - runout_beep++; - } - } - } - inline void first_impatient_beep(const int8_t max_beep_count) { impatient_beep(max_beep_count, true); } -#else - inline void impatient_beep(const int8_t, const bool=false) {} - inline void first_impatient_beep(const int8_t) {} -#endif - -/** - * Ensure a safe temperature for extrusion - * - * - Fail if the TARGET temperature is too low - * - Display LCD placard with temperature status - * - Return when heating is done or aborted - * - * Returns 'true' if heating was completed, 'false' for abort - */ -static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=PAUSE_MODE_SAME) { - DEBUG_SECTION(est, "ensure_safe_temperature", true); - DEBUG_ECHOLNPGM("... wait:", wait, " mode:", mode); - - #if ENABLED(PREVENT_COLD_EXTRUSION) - if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) - thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder); - #endif - - ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode); UNUSED(mode); - - if (wait) return thermalManager.wait_for_hotend(active_extruder); - - // Allow interruption by Emergency Parser M108 - wait_for_heatup = TERN1(PREVENT_COLD_EXTRUSION, !thermalManager.allow_cold_extrude); - while (wait_for_heatup && ABS(thermalManager.wholeDegHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > (TEMP_WINDOW)) - idle(); - wait_for_heatup = false; - - #if ENABLED(PREVENT_COLD_EXTRUSION) - // A user can cancel wait-for-heating with M108 - if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) { - SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); - return false; - } - #endif - - return true; -} - -/** - * Load filament into the hotend - * - * - Fail if the a safe temperature was not reached - * - If pausing for confirmation, wait for a click or M108 - * - Show "wait for load" placard - * - Load and purge filament - * - Show "Purge more" / "Continue" menu - * - Return when "Continue" is selected - * - * Returns 'true' if load was completed, 'false' for abort - */ -bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load_length/*=0*/, const_float_t purge_length/*=0*/, const int8_t max_beep_count/*=0*/, - const bool show_lcd/*=false*/, const bool pause_for_user/*=false*/, - const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ - DXC_ARGS -) { - DEBUG_SECTION(lf, "load_filament", true); - DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " showlcd:", show_lcd, " pauseforuser:", pause_for_user, " pausemode:", mode DXC_SAY); - - if (!ensure_safe_temperature(false, mode)) { - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_STATUS, mode); - return false; - } - - if (pause_for_user) { - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_INSERT, mode); - SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_INSERT)); - - first_impatient_beep(max_beep_count); - - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; // LCD click or M108 will clear this - - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("Load Filament"))); - - #if ENABLED(HOST_PROMPT_SUPPORT) - const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, active_extruder); - hostui.prompt_do(PROMPT_USER_CONTINUE, F("Load Filament T"), tool, FPSTR(CONTINUE_STR)); - #endif - - while (wait_for_user) { - impatient_beep(max_beep_count); - #if BOTH(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR) - #if ENABLED(MULTI_FILAMENT_SENSOR) - #define _CASE_INSERTED(N) case N-1: if (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) wait_for_user = false; break; - switch (active_extruder) { - REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED) - } - #else - if (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE) wait_for_user = false; - #endif - #endif - idle_no_sleep(); - } - } - - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_LOAD, mode); - - #if ENABLED(DUAL_X_CARRIAGE) - const int8_t saved_ext = active_extruder; - const bool saved_ext_dup_mode = extruder_duplication_enabled; - set_duplication_enabled(false, DXC_ext); - #endif - - TERN_(BELTPRINTER, do_blocking_move_to_xy(0.00, 50.00)); - - // Slow Load filament - if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE); - - // Fast Load Filament - if (fast_load_length) { - #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 - const float saved_acceleration = planner.settings.retract_acceleration; - planner.settings.retract_acceleration = FILAMENT_CHANGE_FAST_LOAD_ACCEL; - #endif - - unscaled_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE); - - #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 - planner.settings.retract_acceleration = saved_acceleration; - #endif - } - - #if ENABLED(DUAL_X_CARRIAGE) // Tie the two extruders movement back together. - set_duplication_enabled(saved_ext_dup_mode, saved_ext); - #endif - - #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE) - - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE); - - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE))); - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE), FPSTR(CONTINUE_STR))); - wait_for_user = true; // A click or M108 breaks the purge_length loop - for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count) - unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE); - wait_for_user = false; - - #else - - do { - if (purge_length > 0) { - // "Wait for filament purge" - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE); - - // Extrude filament to get into hotend - unscaled_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE); - } - - TERN_(HOST_PROMPT_SUPPORT, hostui.filament_load_prompt()); // Initiate another host prompt. - - #if M600_PURGE_MORE_RESUMABLE - if (show_lcd) { - // Show "Purge More" / "Resume" menu and wait for reply - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = false; - #if EITHER(HAS_MARLINUI_MENU, DWIN_LCD_PROUI) - ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR - #else - pause_menu_response = PAUSE_RESPONSE_WAIT_FOR; - #endif - while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle_no_sleep(); - } - #endif - - // Keep looping if "Purge More" was selected - } while (TERN0(M600_PURGE_MORE_RESUMABLE, pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE)); - - #endif - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_end()); - - return true; -} - -/** - * Disabling E steppers for manual filament change should be fine - * as long as users don't spin the E motor ridiculously fast and - * send current back to their board, potentially frying it. - */ -inline void disable_active_extruder() { - #if HAS_EXTRUDERS - stepper.DISABLE_EXTRUDER(active_extruder); - safe_delay(100); - #endif -} - -/** - * Unload filament from the hotend - * - * - Fail if the a safe temperature was not reached - * - Show "wait for unload" placard - * - Retract, pause, then unload filament - * - Disable E stepper (on most machines) - * - * Returns 'true' if unload was completed, 'false' for abort - */ -bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/, - const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ - #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - , const_float_t mix_multiplier/*=1.0*/ - #endif -) { - DEBUG_SECTION(uf, "unload_filament", true); - DEBUG_ECHOLNPGM("... unloadlen:", unload_length, " showlcd:", show_lcd, " mode:", mode - #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - , " mixmult:", mix_multiplier - #endif - ); - - #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - constexpr float mix_multiplier = 1.0f; - #endif - - if (!ensure_safe_temperature(false, mode)) { - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_STATUS); - return false; - } - - if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_UNLOAD, mode); - - // Retract filament - unscaled_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier); - - // Wait for filament to cool - safe_delay(FILAMENT_UNLOAD_PURGE_DELAY); - - // Quickly purge - unscaled_e_move((FILAMENT_UNLOAD_PURGE_RETRACT + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier, - (FILAMENT_UNLOAD_PURGE_FEEDRATE) * mix_multiplier); - - // Unload filament - #if FILAMENT_CHANGE_UNLOAD_ACCEL > 0 - const float saved_acceleration = planner.settings.retract_acceleration; - planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL; - #endif - - unscaled_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier); - - #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 - planner.settings.retract_acceleration = saved_acceleration; - #endif - - // Disable the Extruder for manual change - disable_active_extruder(); - - return true; -} - -// public: - -/** - * Pause procedure - * - * - Abort if already paused - * - Send host action for pause, if configured - * - Abort if TARGET temperature is too low - * - Display "wait for start of filament change" (if a length was specified) - * - Initial retract, if current temperature is hot enough - * - Park the nozzle at the given position - * - Call unload_filament (if a length was specified) - * - * Return 'true' if pause was completed, 'false' for abort - */ -uint8_t did_pause_print = 0; - -bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool show_lcd/*=false*/, const_float_t unload_length/*=0*/ DXC_ARGS) { - DEBUG_SECTION(pp, "pause_print", true); - DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY); - - UNUSED(show_lcd); - - if (did_pause_print) return false; // already paused - - #if ENABLED(HOST_ACTION_COMMANDS) - #ifdef ACTION_ON_PAUSED - hostui.paused(); - #elif defined(ACTION_ON_PAUSE) - hostui.pause(); - #endif - #endif - - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR))); - TERN_(DWIN_LCD_PROUI, DWIN_Print_Pause()); - - // Indicate that the printer is paused - ++did_pause_print; - - // Pause the print job and timer - #if ENABLED(SDSUPPORT) - const bool was_sd_printing = IS_SD_PRINTING(); - if (was_sd_printing) { - card.pauseSDPrint(); - ++did_pause_print; // Indicate SD pause also - } - #endif - - print_job_timer.pause(); - - // Save current position - resume_position = current_position; - - // Will the nozzle be parking? - const bool do_park = !axes_should_home(); - - #if ENABLED(POWER_LOSS_RECOVERY) - // Save PLR info in case the power goes out while parked - const float park_raise = do_park ? nozzle.park_mode_0_height(park_point.z) - current_position.z : POWER_LOSS_ZRAISE; - if (was_sd_printing && recovery.enabled) recovery.save(true, park_raise, do_park); - #endif - - // Wait for buffered blocks to complete - planner.synchronize(); - - #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN - thermalManager.set_fans_paused(true); - #endif - - // Initial retract before move to filament change position - if (retract && thermalManager.hotEnoughToExtrude(active_extruder)) { - DEBUG_ECHOLNPGM("... retract:", retract); - - #if ENABLED(AUTO_BED_LEVELING_UBL) - const bool leveling_was_enabled = planner.leveling_active; // save leveling state - set_bed_leveling_enabled(false); // turn off leveling - #endif - - unscaled_e_move(retract, PAUSE_PARK_RETRACT_FEEDRATE); - - TERN_(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(leveling_was_enabled)); // restore leveling - } - - // If axes don't need to home then the nozzle can park - if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move - - #if ENABLED(DUAL_X_CARRIAGE) - const int8_t saved_ext = active_extruder; - const bool saved_ext_dup_mode = extruder_duplication_enabled; - set_duplication_enabled(false, DXC_ext); - #endif - - // Unload the filament, if specified - if (unload_length) - unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT); - - #if ENABLED(DUAL_X_CARRIAGE) - set_duplication_enabled(saved_ext_dup_mode, saved_ext); - #endif - - // Disable the Extruder for manual change - disable_active_extruder(); - - return true; -} - -/** - * For Paused Print: - * - Show "Press button (or M108) to resume" - * - * For Filament Change: - * - Show "Insert filament and press button to continue" - * - * - Wait for a click before returning - * - Heaters can time out and must reheat before continuing - * - * Used by M125 and M600 - */ - -void show_continue_prompt(const bool is_reload) { - DEBUG_SECTION(scp, "pause_print", true); - DEBUG_ECHOLNPGM("... is_reload:", is_reload); - - ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING); - SERIAL_ECHO_START(); - SERIAL_ECHOF(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); -} - -void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { - DEBUG_SECTION(wfc, "wait_for_confirmation", true); - DEBUG_ECHOLNPGM("... is_reload:", is_reload, " maxbeep:", max_beep_count DXC_SAY); - - bool nozzle_timed_out = false; - - show_continue_prompt(is_reload); - - first_impatient_beep(max_beep_count); - - // Start the heater idle timers - const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); - - HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); - - #if ENABLED(DUAL_X_CARRIAGE) - const int8_t saved_ext = active_extruder; - const bool saved_ext_dup_mode = extruder_duplication_enabled; - set_duplication_enabled(false, DXC_ext); - #endif - - // Wait for filament insert by user and press button - KEEPALIVE_STATE(PAUSED_FOR_USER); - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_NOZZLE_PARKED), FPSTR(CONTINUE_STR))); - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_NOZZLE_PARKED))); - wait_for_user = true; // LCD click or M108 will clear this - while (wait_for_user) { - impatient_beep(max_beep_count); - - // If the nozzle has timed out... - if (!nozzle_timed_out) - HOTEND_LOOP() nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; - - // Wait for the user to press the button to re-heat the nozzle, then - // re-heat the nozzle, re-show the continue prompt, restart idle timers, start over - if (nozzle_timed_out) { - ui.pause_show_message(PAUSE_MESSAGE_HEAT); - SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_HEAT)); - - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_HEATER_TIMEOUT), GET_TEXT_F(MSG_REHEAT))); - - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT))); - - TERN_(HAS_RESUME_CONTINUE, wait_for_user_response(0, true)); // Wait for LCD click or M108 - - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_INFO, GET_TEXT_F(MSG_REHEATING))); - - TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(GET_TEXT_F(MSG_REHEATING))); - - TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATING)); - - // Re-enable the heaters if they timed out - HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e); - - // Wait for the heaters to reach the target temperatures - ensure_safe_temperature(false); - - // Show the prompt to continue - show_continue_prompt(is_reload); - - // Start the heater idle timers - const millis_t nozzle_timeout = SEC_TO_MS(PAUSE_PARK_NOZZLE_TIMEOUT); - - HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout); - - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_REHEATDONE), FPSTR(CONTINUE_STR))); - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE))); - TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATDONE)); - - IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, wait_for_user = true); - - nozzle_timed_out = false; - first_impatient_beep(max_beep_count); - } - idle_no_sleep(); - } - #if ENABLED(DUAL_X_CARRIAGE) - set_duplication_enabled(saved_ext_dup_mode, saved_ext); - #endif -} - -/** - * Resume or Start print procedure - * - * - If not paused, do nothing and return - * - Reset heater idle timers - * - Load filament if specified, but only if: - * - a nozzle timed out, or - * - the nozzle is already heated. - * - Display "wait for print to resume" - * - Retract to prevent oozing - * - Move the nozzle back to resume_position - * - Unretract - * - Re-prime the nozzle... - * - FWRETRACT: Recover/prime from the prior G10. - * - !FWRETRACT: Retract by resume_position.e, if negative. - * Not sure how this logic comes into use. - * - Sync the planner E to resume_position.e - * - Send host action for resume, if configured - * - Resume the current SD print job, if any - */ -void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_length/*=0*/, const_float_t purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/, const celsius_t targetTemp/*=0*/ DXC_ARGS) { - DEBUG_SECTION(rp, "resume_print", true); - DEBUG_ECHOLNPGM("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", max_beep_count, " targetTemp:", targetTemp DXC_SAY); - - /* - SERIAL_ECHOLNPGM( - "start of resume_print()\ndual_x_carriage_mode:", dual_x_carriage_mode, - "\nextruder_duplication_enabled:", extruder_duplication_enabled, - "\nactive_extruder:", active_extruder, - "\n" - ); - //*/ - - if (!did_pause_print) return; - - // Re-enable the heaters if they timed out - bool nozzle_timed_out = false; - HOTEND_LOOP() { - nozzle_timed_out |= thermalManager.heater_idle[e].timed_out; - thermalManager.reset_hotend_idle_timer(e); - } - - if (targetTemp > thermalManager.degTargetHotend(active_extruder)) - thermalManager.setTargetHotend(targetTemp, active_extruder); - - // Load the new filament - load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_SAME DXC_PASS); - - if (targetTemp > 0) { - thermalManager.setTargetHotend(targetTemp, active_extruder); - thermalManager.wait_for_hotend(active_extruder, false); - } - - ui.pause_show_message(PAUSE_MESSAGE_RESUME); - - // Check Temperature before moving hotend - ensure_safe_temperature(DISABLED(BELTPRINTER)); - - // Retract to prevent oozing - unscaled_e_move(-(PAUSE_PARK_RETRACT_LENGTH), feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); - - if (!axes_should_home()) { - // Move XY back to saved position - destination.set(resume_position.x, resume_position.y, current_position.z, current_position.e); - prepare_internal_move_to_destination(NOZZLE_PARK_XY_FEEDRATE); - - // Move Z back to saved position - destination.z = resume_position.z; - prepare_internal_move_to_destination(NOZZLE_PARK_Z_FEEDRATE); - } - - #if ENABLED(AUTO_BED_LEVELING_UBL) - const bool leveling_was_enabled = planner.leveling_active; // save leveling state - set_bed_leveling_enabled(false); // turn off leveling - #endif - - // Unretract - unscaled_e_move(PAUSE_PARK_RETRACT_LENGTH, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); - - TERN_(AUTO_BED_LEVELING_UBL, set_bed_leveling_enabled(leveling_was_enabled)); // restore leveling - - // Intelligent resuming - #if ENABLED(FWRETRACT) - // If retracted before goto pause - if (fwretract.retracted[active_extruder]) - unscaled_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s); - #endif - - // If resume_position is negative - if (resume_position.e < 0) unscaled_e_move(resume_position.e, feedRate_t(PAUSE_PARK_RETRACT_FEEDRATE)); - #ifdef ADVANCED_PAUSE_RESUME_PRIME - if (ADVANCED_PAUSE_RESUME_PRIME != 0) - unscaled_e_move(ADVANCED_PAUSE_RESUME_PRIME, feedRate_t(ADVANCED_PAUSE_PURGE_FEEDRATE)); - #endif - - // Now all extrusion positions are resumed and ready to be confirmed - // Set extruder to saved position - planner.set_e_position_mm((destination.e = current_position.e = resume_position.e)); - - ui.pause_show_message(PAUSE_MESSAGE_STATUS); - - #ifdef ACTION_ON_RESUMED - hostui.resumed(); - #elif defined(ACTION_ON_RESUME) - hostui.resume(); - #endif - - --did_pause_print; - - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Resuming"), FPSTR(DISMISS_STR))); - - // Resume the print job timer if it was running - if (print_job_timer.isPaused()) print_job_timer.start(); - - #if ENABLED(SDSUPPORT) - if (did_pause_print) { - --did_pause_print; - card.startOrResumeFilePrinting(); - // Write PLR now to update the z axis value - TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true)); - } - #endif - - #if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN - thermalManager.set_fans_paused(false); - #endif - - TERN_(HAS_FILAMENT_SENSOR, runout.reset()); - - #if ENABLED(DWIN_LCD_PROUI) - DWIN_Print_Resume(); - HMI_ReturnScreen(); - #else - ui.reset_status(); - ui.return_to_status(); - #endif -} - -#endif // ADVANCED_PAUSE_FEATURE diff --git a/src/feature/pause.h b/src/feature/pause.h deleted file mode 100644 index 134b1d1..0000000 --- a/src/feature/pause.h +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/pause.h - Pause feature support functions - * This may be combined with related G-codes if features are consolidated. - */ - -typedef struct { - float unload_length, load_length; -} fil_change_settings_t; - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(ADVANCED_PAUSE_FEATURE) - -#include "../libs/nozzle.h" - -enum PauseMode : char { - PAUSE_MODE_SAME, - PAUSE_MODE_PAUSE_PRINT, - PAUSE_MODE_CHANGE_FILAMENT, - PAUSE_MODE_LOAD_FILAMENT, - PAUSE_MODE_UNLOAD_FILAMENT -}; - -enum PauseMessage : char { - PAUSE_MESSAGE_PARKING, - PAUSE_MESSAGE_CHANGING, - PAUSE_MESSAGE_WAITING, - PAUSE_MESSAGE_UNLOAD, - PAUSE_MESSAGE_INSERT, - PAUSE_MESSAGE_LOAD, - PAUSE_MESSAGE_PURGE, - PAUSE_MESSAGE_OPTION, - PAUSE_MESSAGE_RESUME, - PAUSE_MESSAGE_STATUS, - PAUSE_MESSAGE_HEAT, - PAUSE_MESSAGE_HEATING -}; - -#if M600_PURGE_MORE_RESUMABLE - enum PauseMenuResponse : char { - PAUSE_RESPONSE_WAIT_FOR, - PAUSE_RESPONSE_EXTRUDE_MORE, - PAUSE_RESPONSE_RESUME_PRINT - }; - extern PauseMenuResponse pause_menu_response; - extern PauseMode pause_mode; -#endif - -extern fil_change_settings_t fc_settings[EXTRUDERS]; - -extern uint8_t did_pause_print; - -#define DXC_PARAMS OPTARG(DUAL_X_CARRIAGE, const int8_t DXC_ext=-1) -#define DXC_ARGS OPTARG(DUAL_X_CARRIAGE, const int8_t DXC_ext) -#define DXC_PASS OPTARG(DUAL_X_CARRIAGE, DXC_ext) -#define DXC_SAY OPTARG(DUAL_X_CARRIAGE, " dxc:", int(DXC_ext)) - -// Pause the print. If unload_length is set, do a Filament Unload -bool pause_print( - const_float_t retract, // (mm) Retraction length - const xyz_pos_t &park_point, // Parking XY Position and Z Raise - const bool show_lcd=false, // Set LCD status messages? - const_float_t unload_length=0 // (mm) Filament Change Unload Length - 0 to skip - DXC_PARAMS // Dual-X-Carriage extruder index -); - -void wait_for_confirmation( - const bool is_reload=false, // Reload Filament? (otherwise Resume Print) - const int8_t max_beep_count=0 // Beep alert for attention - DXC_PARAMS // Dual-X-Carriage extruder index -); - -void resume_print( - const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move - const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move - const_float_t extrude_length=ADVANCED_PAUSE_PURGE_LENGTH, // (mm) Purge length - const int8_t max_beep_count=0, // Beep alert for attention - const celsius_t targetTemp=0 // (°C) A target temperature for the hotend - DXC_PARAMS // Dual-X-Carriage extruder index -); - -bool load_filament( - const_float_t slow_load_length=0, // (mm) Slow Load Length for finishing move - const_float_t fast_load_length=0, // (mm) Fast Load Length for initial move - const_float_t extrude_length=0, // (mm) Purge length - const int8_t max_beep_count=0, // Beep alert for attention - const bool show_lcd=false, // Set LCD status messages? - const bool pause_for_user=false, // Pause for user before returning? - const PauseMode mode=PAUSE_MODE_PAUSE_PRINT // Pause Mode to apply - DXC_PARAMS // Dual-X-Carriage extruder index -); - -bool unload_filament( - const_float_t unload_length, // (mm) Filament Unload Length - 0 to skip - const bool show_lcd=false, // Set LCD status messages? - const PauseMode mode=PAUSE_MODE_PAUSE_PRINT // Pause Mode to apply - #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) - , const_float_t mix_multiplier=1.0f // Extrusion multiplier (for a Mixing Extruder) - #endif -); - -#else // !ADVANCED_PAUSE_FEATURE - - constexpr uint8_t did_pause_print = 0; - -#endif // !ADVANCED_PAUSE_FEATURE diff --git a/src/feature/power.cpp b/src/feature/power.cpp deleted file mode 100644 index 8a16628..0000000 --- a/src/feature/power.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * power.cpp - power control - */ - -#include "../inc/MarlinConfigPre.h" - -#if EITHER(PSU_CONTROL, AUTO_POWER_CONTROL) - -#include "power.h" -#include "../module/planner.h" -#include "../module/stepper/indirection.h" // for restore_stepper_drivers -#include "../module/temperature.h" -#include "../MarlinCore.h" - -#if ENABLED(PS_OFF_SOUND) - #include "../libs/buzzer.h" -#endif - -#if defined(PSU_POWERUP_GCODE) || defined(PSU_POWEROFF_GCODE) - #include "../gcode/gcode.h" -#endif - -Power powerManager; -bool Power::psu_on; - -#if ENABLED(AUTO_POWER_CONTROL) - #include "../module/stepper.h" - #include "../module/temperature.h" - - #if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN) - #include "controllerfan.h" - #endif - - millis_t Power::lastPowerOn; -#endif - -/** - * Initialize pins & state for the power manager. - * - */ -void Power::init() { - psu_on = ENABLED(PSU_DEFAULT_OFF); // Set opposite state to get full power_off/on - TERN(PSU_DEFAULT_OFF, power_off(), power_on()); -} - -/** - * Power on if the power is currently off. - * Restores stepper drivers and processes any PSU_POWERUP_GCODE. - * - */ -void Power::power_on() { - #if ENABLED(AUTO_POWER_CONTROL) - const millis_t now = millis(); - lastPowerOn = now + !now; - #endif - - if (psu_on) return; - - #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN) - cancelAutoPowerOff(); - #endif - - OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_STATE); - psu_on = true; - safe_delay(PSU_POWERUP_DELAY); - restore_stepper_drivers(); - TERN_(HAS_TRINAMIC_CONFIG, safe_delay(PSU_POWERUP_DELAY)); - - #ifdef PSU_POWERUP_GCODE - gcode.process_subcommands_now(F(PSU_POWERUP_GCODE)); - #endif -} - -/** - * Power off if the power is currently on. - * Processes any PSU_POWEROFF_GCODE and makes a PS_OFF_SOUND if enabled. - */ -void Power::power_off() { - SERIAL_ECHOLNPGM(STR_POWEROFF); - - TERN_(HAS_SUICIDE, suicide()); - - if (!psu_on) return; - - #ifdef PSU_POWEROFF_GCODE - gcode.process_subcommands_now(F(PSU_POWEROFF_GCODE)); - #endif - - #if ENABLED(PS_OFF_SOUND) - BUZZ(1000, 659); - #endif - - OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_STATE); - psu_on = false; - - #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN) - cancelAutoPowerOff(); - #endif -} - -#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN) - - bool Power::is_cooling_needed() { - #if HAS_HOTEND && AUTO_POWER_E_TEMP - HOTEND_LOOP() if (thermalManager.degHotend(e) >= (AUTO_POWER_E_TEMP)) return true; - #endif - - #if HAS_HEATED_CHAMBER && AUTO_POWER_CHAMBER_TEMP - if (thermalManager.degChamber() >= (AUTO_POWER_CHAMBER_TEMP)) return true; - #endif - - #if HAS_COOLER && AUTO_POWER_COOLER_TEMP - if (thermalManager.degCooler() >= (AUTO_POWER_COOLER_TEMP)) return true; - #endif - - return false; - } - -#endif - -#if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN) - - #if ENABLED(POWER_OFF_TIMER) - millis_t Power::power_off_time = 0; - void Power::setPowerOffTimer(const millis_t delay_ms) { power_off_time = millis() + delay_ms; } - #endif - - #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) - bool Power::power_off_on_cooldown = false; - void Power::setPowerOffOnCooldown(const bool ena) { power_off_on_cooldown = ena; } - #endif - - void Power::cancelAutoPowerOff() { - TERN_(POWER_OFF_TIMER, power_off_time = 0); - TERN_(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown = false); - } - - void Power::checkAutoPowerOff() { - if (TERN1(POWER_OFF_TIMER, !power_off_time) && TERN1(POWER_OFF_WAIT_FOR_COOLDOWN, !power_off_on_cooldown)) return; - if (TERN0(POWER_OFF_WAIT_FOR_COOLDOWN, power_off_on_cooldown && is_cooling_needed())) return; - if (TERN0(POWER_OFF_TIMER, power_off_time && PENDING(millis(), power_off_time))) return; - power_off(); - } - -#endif // POWER_OFF_TIMER || POWER_OFF_WAIT_FOR_COOLDOWN - -#if ENABLED(AUTO_POWER_CONTROL) - - #ifndef POWER_TIMEOUT - #define POWER_TIMEOUT 0 - #endif - - /** - * Check all conditions that would signal power needing to be on. - * - * @returns bool if power is needed - */ - bool Power::is_power_needed() { - - // If any of the stepper drivers are enabled... - if (stepper.axis_enabled.bits) return true; - - if (printJobOngoing() || printingIsPaused()) return true; - - #if ENABLED(AUTO_POWER_FANS) - FANS_LOOP(i) if (thermalManager.fan_speed[i]) return true; - #endif - - #if ENABLED(AUTO_POWER_E_FANS) - HOTEND_LOOP() if (thermalManager.autofan_speed[e]) return true; - #endif - - #if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN) - if (controllerFan.state()) return true; - #endif - - if (TERN0(AUTO_POWER_CHAMBER_FAN, thermalManager.chamberfan_speed)) - return true; - - if (TERN0(AUTO_POWER_COOLER_FAN, thermalManager.coolerfan_speed)) - return true; - - #if HAS_HOTEND - HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0 || thermalManager.temp_hotend[e].soft_pwm_amount > 0) return true; - #endif - - if (TERN0(HAS_HEATED_BED, thermalManager.degTargetBed() > 0 || thermalManager.temp_bed.soft_pwm_amount > 0)) return true; - - return is_cooling_needed(); - } - - /** - * Check if we should power off automatically (POWER_TIMEOUT elapsed, !is_power_needed). - * - * @param pause pause the 'timer' - */ - void Power::check(const bool pause) { - static millis_t nextPowerCheck = 0; - const millis_t now = millis(); - #if POWER_TIMEOUT > 0 - static bool _pause = false; - if (pause != _pause) { - lastPowerOn = now + !now; - _pause = pause; - } - if (pause) return; - #endif - if (ELAPSED(now, nextPowerCheck)) { - nextPowerCheck = now + 2500UL; - if (is_power_needed()) - power_on(); - else if (!lastPowerOn || (POWER_TIMEOUT > 0 && ELAPSED(now, lastPowerOn + SEC_TO_MS(POWER_TIMEOUT)))) - power_off(); - } - } - - #if POWER_OFF_DELAY > 0 - - /** - * Power off with a delay. Power off is triggered by check() after the delay. - */ - void Power::power_off_soon() { - lastPowerOn = millis() - SEC_TO_MS(POWER_TIMEOUT) + SEC_TO_MS(POWER_OFF_DELAY); - } - - #endif - -#endif // AUTO_POWER_CONTROL - -#endif // PSU_CONTROL || AUTO_POWER_CONTROL diff --git a/src/feature/power.h b/src/feature/power.h deleted file mode 100644 index 839366c..0000000 --- a/src/feature/power.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * power.h - power control - */ - -#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_TIMER) - #include "../core/millis_t.h" -#endif - -class Power { - public: - static bool psu_on; - - static void init(); - static void power_on(); - static void power_off(); - - #if EITHER(POWER_OFF_TIMER, POWER_OFF_WAIT_FOR_COOLDOWN) - #if ENABLED(POWER_OFF_TIMER) - static millis_t power_off_time; - static void setPowerOffTimer(const millis_t delay_ms); - #endif - #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) - static bool power_off_on_cooldown; - static void setPowerOffOnCooldown(const bool ena); - #endif - static void cancelAutoPowerOff(); - static void checkAutoPowerOff(); - #endif - - #if ENABLED(AUTO_POWER_CONTROL) && POWER_OFF_DELAY > 0 - static void power_off_soon(); - #else - static void power_off_soon() { power_off(); } - #endif - - #if ENABLED(AUTO_POWER_CONTROL) - static void check(const bool pause); - - private: - static millis_t lastPowerOn; - static bool is_power_needed(); - static bool is_cooling_needed(); - #elif ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) - private: - static bool is_cooling_needed(); - #endif -}; - -extern Power powerManager; diff --git a/src/feature/power_monitor.cpp b/src/feature/power_monitor.cpp deleted file mode 100644 index 5a9db1e..0000000 --- a/src/feature/power_monitor.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if HAS_POWER_MONITOR - -#include "power_monitor.h" - -#if HAS_MARLINUI_MENU - #include "../lcd/marlinui.h" - #include "../lcd/lcdprint.h" -#endif - -#include "../libs/numtostr.h" - -uint8_t PowerMonitor::flags; // = 0 - -#if ENABLED(POWER_MONITOR_CURRENT) - pm_lpf_t PowerMonitor::amps; -#endif -#if ENABLED(POWER_MONITOR_VOLTAGE) - pm_lpf_t PowerMonitor::volts; -#endif - -millis_t PowerMonitor::display_item_ms; -uint8_t PowerMonitor::display_item; - -PowerMonitor power_monitor; // Single instance - this calls the constructor - -#if HAS_MARLINUI_U8GLIB - - #if ENABLED(POWER_MONITOR_CURRENT) - void PowerMonitor::draw_current() { - const float amps = getAmps(); - lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps)); - lcd_put_lchar('A'); - } - #endif - - #if ENABLED(POWER_MONITOR_VOLTAGE) - void PowerMonitor::draw_voltage() { - const float volts = getVolts(); - lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts)); - lcd_put_lchar('V'); - } - #endif - - #if HAS_POWER_MONITOR_WATTS - void PowerMonitor::draw_power() { - const float power = getPower(); - lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power)); - lcd_put_lchar('W'); - } - #endif - -#endif // HAS_MARLINUI_U8GLIB - -#endif // HAS_POWER_MONITOR diff --git a/src/feature/power_monitor.h b/src/feature/power_monitor.h deleted file mode 100644 index fa06909..0000000 --- a/src/feature/power_monitor.h +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -#define PM_SAMPLE_RANGE HAL_ADC_RANGE -#define PM_K_VALUE 6 -#define PM_K_SCALE 6 - -template -struct pm_lpf_t { - uint32_t filter_buf; - float value; - void add_sample(const uint16_t sample) { - filter_buf += (uint32_t(sample) << K_SCALE) - (filter_buf >> K_VALUE); - } - void capture() { - value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE)))); - } - void reset(uint16_t reset_value = 0) { - filter_buf = uint32_t(reset_value) << (K_VALUE + K_SCALE); - capture(); - } -}; - -class PowerMonitor { -private: - #if ENABLED(POWER_MONITOR_CURRENT) - static constexpr float amps_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_AMP * PM_SAMPLE_RANGE); - static pm_lpf_t amps; - #endif - #if ENABLED(POWER_MONITOR_VOLTAGE) - static constexpr float volts_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_VOLT * PM_SAMPLE_RANGE); - static pm_lpf_t volts; - #endif - -public: - static uint8_t flags; // M430 flags to display current - - static millis_t display_item_ms; - static uint8_t display_item; - - PowerMonitor() { reset(); } - - enum PM_Display_Bit : uint8_t { - PM_DISP_BIT_I, // Current display enable bit - PM_DISP_BIT_V, // Voltage display enable bit - PM_DISP_BIT_P // Power display enable bit - }; - - #if ENABLED(POWER_MONITOR_CURRENT) - FORCE_INLINE static float getAmps() { return amps.value + (POWER_MONITOR_CURRENT_OFFSET); } - void add_current_sample(const uint16_t value) { amps.add_sample(value); } - #endif - - #if ENABLED(POWER_MONITOR_VOLTAGE) - FORCE_INLINE static float getVolts() { return volts.value + (POWER_MONITOR_VOLTAGE_OFFSET); } - void add_voltage_sample(const uint16_t value) { volts.add_sample(value); } - #else - FORCE_INLINE static float getVolts() { return POWER_MONITOR_FIXED_VOLTAGE; } - #endif - - #if HAS_POWER_MONITOR_WATTS - FORCE_INLINE static float getPower() { return getAmps() * getVolts(); } - #endif - - #if HAS_WIRED_LCD - #if HAS_MARLINUI_U8GLIB && DISABLED(LIGHTWEIGHT_UI) - FORCE_INLINE static bool display_enabled() { return flags != 0x00; } - #endif - #if ENABLED(POWER_MONITOR_CURRENT) - static void draw_current(); - FORCE_INLINE static bool current_display_enabled() { return TEST(flags, PM_DISP_BIT_I); } - FORCE_INLINE static void set_current_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_I, b); } - FORCE_INLINE static void toggle_current_display() { TBI(flags, PM_DISP_BIT_I); } - #endif - #if ENABLED(POWER_MONITOR_VOLTAGE) - static void draw_voltage(); - FORCE_INLINE static bool voltage_display_enabled() { return TEST(flags, PM_DISP_BIT_V); } - FORCE_INLINE static void set_voltage_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_V, b); } - FORCE_INLINE static void toggle_voltage_display() { TBI(flags, PM_DISP_BIT_V); } - #endif - #if HAS_POWER_MONITOR_WATTS - static void draw_power(); - FORCE_INLINE static bool power_display_enabled() { return TEST(flags, PM_DISP_BIT_P); } - FORCE_INLINE static void set_power_display(const bool b) { SET_BIT_TO(flags, PM_DISP_BIT_P, b); } - FORCE_INLINE static void toggle_power_display() { TBI(flags, PM_DISP_BIT_P); } - #endif - #endif - - static void reset() { - flags = 0x00; - - #if ENABLED(POWER_MONITOR_CURRENT) - amps.reset(); - #endif - - #if ENABLED(POWER_MONITOR_VOLTAGE) - volts.reset(); - #endif - - #if ENABLED(SDSUPPORT) - display_item_ms = 0; - display_item = 0; - #endif - } - - static void capture_values() { - #if ENABLED(POWER_MONITOR_CURRENT) - amps.capture(); - #endif - #if ENABLED(POWER_MONITOR_VOLTAGE) - volts.capture(); - #endif - } -}; - -extern PowerMonitor power_monitor; diff --git a/src/feature/powerloss.cpp b/src/feature/powerloss.cpp deleted file mode 100644 index d4450ad..0000000 --- a/src/feature/powerloss.cpp +++ /dev/null @@ -1,712 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/powerloss.cpp - Resume an SD print after power-loss - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(POWER_LOSS_RECOVERY) - -#include "powerloss.h" -#include "../core/macros.h" - -bool PrintJobRecovery::enabled; // Initialized by settings.load() - -SdFile PrintJobRecovery::file; -job_recovery_info_t PrintJobRecovery::info; -const char PrintJobRecovery::filename[5] = "/PLR"; -uint8_t PrintJobRecovery::queue_index_r; -uint32_t PrintJobRecovery::cmd_sdpos, // = 0 - PrintJobRecovery::sdpos[BUFSIZE]; - -#if HAS_DWIN_E3V2_BASIC - bool PrintJobRecovery::dwin_flag; // = false -#endif - -#include "../sd/cardreader.h" -#include "../lcd/marlinui.h" -#include "../gcode/queue.h" -#include "../gcode/gcode.h" -#include "../module/motion.h" -#include "../module/planner.h" -#include "../module/printcounter.h" -#include "../module/temperature.h" -#include "../core/serial.h" - -#if HOMING_Z_WITH_PROBE - #include "../module/probe.h" -#endif - -#if ENABLED(FWRETRACT) - #include "fwretract.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_POWER_LOSS_RECOVERY) -#include "../core/debug_out.h" - -PrintJobRecovery recovery; - -#ifndef POWER_LOSS_PURGE_LEN - #define POWER_LOSS_PURGE_LEN 0 -#endif - -#if DISABLED(BACKUP_POWER_SUPPLY) - #undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power -#endif -#ifndef POWER_LOSS_RETRACT_LEN - #define POWER_LOSS_RETRACT_LEN 0 -#endif - -/** - * Clear the recovery info - */ -void PrintJobRecovery::init() { memset(&info, 0, sizeof(info)); } - -/** - * Enable or disable then call changed() - */ -void PrintJobRecovery::enable(const bool onoff) { - enabled = onoff; - changed(); -} - -/** - * The enabled state was changed: - * - Enabled: Purge the job recovery file - * - Disabled: Write the job recovery file - */ -void PrintJobRecovery::changed() { - if (!enabled) - purge(); - else if (IS_SD_PRINTING()) - save(true); -} - -/** - * Check for Print Job Recovery during setup() - * - * If a saved state exists send 'M1000 S' to initiate job recovery. - */ -bool PrintJobRecovery::check() { - //if (!card.isMounted()) card.mount(); - bool success = false; - if (card.isMounted()) { - load(); - success = valid(); - if (!success) - cancel(); - else - queue.inject(F("M1000S")); - } - return success; -} - -/** - * Delete the recovery file and clear the recovery data - */ -void PrintJobRecovery::purge() { - init(); - card.removeJobRecoveryFile(); -} - -/** - * Load the recovery data, if it exists - */ -void PrintJobRecovery::load() { - if (exists()) { - open(true); - (void)file.read(&info, sizeof(info)); - close(); - } - debug(F("Load")); -} - -/** - * Set info fields that won't change - */ -void PrintJobRecovery::prepare() { - card.getAbsFilenameInCWD(info.sd_filename); // SD filename - cmd_sdpos = 0; -} - -/** - * Save the current machine state to the power-loss recovery file - */ -void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POWER_LOSS_ZRAISE*/, const bool raised/*=false*/) { - - // We don't check IS_SD_PRINTING here so a save may occur during a pause - - #if SAVE_INFO_INTERVAL_MS > 0 - static millis_t next_save_ms; // = 0 - millis_t ms = millis(); - #endif - - #ifndef POWER_LOSS_MIN_Z_CHANGE - #define POWER_LOSS_MIN_Z_CHANGE 0.05 // Vase-mode-friendly out of the box - #endif - - // Did Z change since the last call? - if (force - #if DISABLED(SAVE_EACH_CMD_MODE) // Always save state when enabled - #if SAVE_INFO_INTERVAL_MS > 0 // Save if interval is elapsed - || ELAPSED(ms, next_save_ms) - #endif - // Save if Z is above the last-saved position by some minimum height - || current_position.z > info.current_position.z + POWER_LOSS_MIN_Z_CHANGE - #endif - ) { - - #if SAVE_INFO_INTERVAL_MS > 0 - next_save_ms = ms + SAVE_INFO_INTERVAL_MS; - #endif - - // Set Head and Foot to matching non-zero values - if (!++info.valid_head) ++info.valid_head; // non-zero in sequence - //if (!IS_SD_PRINTING()) info.valid_head = 0; - info.valid_foot = info.valid_head; - - // Machine state - // info.sdpos and info.current_position are pre-filled from the Stepper ISR - - info.feedrate = uint16_t(MMS_TO_MMM(feedrate_mm_s)); - info.zraise = zraise; - info.flag.raised = raised; // Was Z raised before power-off? - - TERN_(GCODE_REPEAT_MARKERS, info.stored_repeat = repeat); - TERN_(HAS_HOME_OFFSET, info.home_offset = home_offset); - TERN_(HAS_POSITION_SHIFT, info.position_shift = position_shift); - E_TERN_(info.active_extruder = active_extruder); - - #if DISABLED(NO_VOLUMETRICS) - info.flag.volumetric_enabled = parser.volumetric_enabled; - #if HAS_MULTI_EXTRUDER - EXTRUDER_LOOP() info.filament_size[e] = planner.filament_size[e]; - #else - if (parser.volumetric_enabled) info.filament_size[0] = planner.filament_size[active_extruder]; - #endif - #endif - - #if HAS_EXTRUDERS - HOTEND_LOOP() info.target_temperature[e] = thermalManager.degTargetHotend(e); - #endif - - TERN_(HAS_HEATED_BED, info.target_temperature_bed = thermalManager.degTargetBed()); - - #if HAS_FAN - COPY(info.fan_speed, thermalManager.fan_speed); - #endif - - #if HAS_LEVELING - info.flag.leveling = planner.leveling_active; - info.fade = TERN0(ENABLE_LEVELING_FADE_HEIGHT, planner.z_fade_height); - #endif - - TERN_(GRADIENT_MIX, memcpy(&info.gradient, &mixer.gradient, sizeof(info.gradient))); - - #if ENABLED(FWRETRACT) - COPY(info.retract, fwretract.current_retract); - info.retract_hop = fwretract.current_hop; - #endif - - // Elapsed print job time - info.print_job_elapsed = print_job_timer.duration(); - - // Relative axis modes - info.axis_relative = gcode.axis_relative; - - // Misc. Marlin flags - info.flag.dryrun = !!(marlin_debug_flags & MARLIN_DEBUG_DRYRUN); - info.flag.allow_cold_extrusion = TERN0(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude); - - write(); - } -} - -#if PIN_EXISTS(POWER_LOSS) - - #if ENABLED(BACKUP_POWER_SUPPLY) - - void PrintJobRecovery::retract_and_lift(const_float_t zraise) { - #if POWER_LOSS_RETRACT_LEN || POWER_LOSS_ZRAISE - - gcode.set_relative_mode(true); // Use relative coordinates - - #if POWER_LOSS_RETRACT_LEN - // Retract filament now - gcode.process_subcommands_now(F("G1 F3000 E-" STRINGIFY(POWER_LOSS_RETRACT_LEN))); - #endif - - #if POWER_LOSS_ZRAISE - // Raise the Z axis now - if (zraise) { - char cmd[20], str_1[16]; - sprintf_P(cmd, PSTR("G0Z%s"), dtostrf(zraise, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - } - #else - UNUSED(zraise); - #endif - - //gcode.axis_relative = info.axis_relative; - planner.synchronize(); - #endif - } - - #endif - -#endif // POWER_LOSS_PIN - -#if PIN_EXISTS(POWER_LOSS) || ENABLED(DEBUG_POWER_LOSS_RECOVERY) - - /** - * An outage was detected by a sensor pin. - * - If not SD printing, let the machine turn off on its own with no "KILL" screen - * - Disable all heaters first to save energy - * - Save the recovery data for the current instant - * - If backup power is available Retract E and Raise Z - * - Go to the KILL screen - */ - void PrintJobRecovery::_outage(TERN_(DEBUG_POWER_LOSS_RECOVERY, const bool simulated/*=false*/)) { - #if ENABLED(BACKUP_POWER_SUPPLY) - static bool lock = false; - if (lock) return; // No re-entrance from idle() during retract_and_lift() - lock = true; - #endif - - #if POWER_LOSS_ZRAISE - // Get the limited Z-raise to do now or on resume - const float zraise = _MAX(0, _MIN(current_position.z + POWER_LOSS_ZRAISE, Z_MAX_POS - 1) - current_position.z); - #else - constexpr float zraise = 0; - #endif - - // Save the current position, distance that Z was (or should be) raised, - // and a flag whether the raise was already done here. - if (IS_SD_PRINTING()) save(true, zraise, ENABLED(BACKUP_POWER_SUPPLY)); - - // Disable all heaters to reduce power loss - thermalManager.disable_all_heaters(); - - #if ENABLED(BACKUP_POWER_SUPPLY) - // Do a hard-stop of the steppers (with possibly a loud thud) - quickstop_stepper(); - // With backup power a retract and raise can be done now - retract_and_lift(zraise); - #endif - - if (TERN0(DEBUG_POWER_LOSS_RECOVERY, simulated)) { - card.fileHasFinished(); - current_position.reset(); - sync_plan_position(); - } - else - kill(GET_TEXT_F(MSG_OUTAGE_RECOVERY)); - } - -#endif // POWER_LOSS_PIN || DEBUG_POWER_LOSS_RECOVERY - -/** - * Save the recovery info the recovery file - */ -void PrintJobRecovery::write() { - - debug(F("Write")); - - open(false); - file.seekSet(0); - const int16_t ret = file.write(&info, sizeof(info)); - if (ret == -1) DEBUG_ECHOLNPGM("Power-loss file write failed."); - if (!file.close()) DEBUG_ECHOLNPGM("Power-loss file close failed."); -} - -/** - * Resume the saved print job - */ -void PrintJobRecovery::resume() { - - char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16]; - - const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it - - // Apply the dry-run flag if enabled - if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN; - - // Restore cold extrusion permission - TERN_(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag.allow_cold_extrusion); - - #if HAS_LEVELING - // Make sure leveling is off before any G92 and G28 - gcode.process_subcommands_now(F("M420 S0 Z0")); - #endif - - #if HAS_HEATED_BED - const celsius_t bt = info.target_temperature_bed; - if (bt) { - // Restore the bed temperature - sprintf_P(cmd, PSTR("M190S%i"), bt); - gcode.process_subcommands_now(cmd); - } - #endif - - // Heat hotend enough to soften material - #if HAS_HOTEND - HOTEND_LOOP() { - const celsius_t et = _MAX(info.target_temperature[e], 180); - if (et) { - #if HAS_MULTI_HOTEND - sprintf_P(cmd, PSTR("T%iS"), e); - gcode.process_subcommands_now(cmd); - #endif - sprintf_P(cmd, PSTR("M109S%i"), et); - gcode.process_subcommands_now(cmd); - } - } - #endif - - // Interpret the saved Z according to flags - const float z_print = info.current_position.z, - z_raised = z_print + info.zraise; - - // - // Home the axes that can safely be homed, and - // establish the current position as best we can. - // - - gcode.process_subcommands_now(F("G92.9E0")); // Reset E to 0 - - #if Z_HOME_TO_MAX - - float z_now = z_raised; - - // If Z homing goes to max then just move back to the "raised" position - sprintf_P(cmd, PSTR( - "G28R0\n" // Home all axes (no raise) - "G1Z%sF1200" // Move Z down to (raised) height - ), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - - #elif DISABLED(BELTPRINTER) - - #if ENABLED(POWER_LOSS_RECOVER_ZHOME) && defined(POWER_LOSS_ZHOME_POS) - #define HOMING_Z_DOWN 1 - #endif - - float z_now = info.flag.raised ? z_raised : z_print; - - #if !HOMING_Z_DOWN - // Set Z to the real position - sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - #endif - - // Does Z need to be raised now? It should be raised before homing XY. - if (z_raised > z_now) { - z_now = z_raised; - sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - } - - // Home XY with no Z raise - gcode.process_subcommands_now(F("G28R0XY")); // No raise during G28 - - #endif - - #if HOMING_Z_DOWN - // Move to a safe XY position and home Z while avoiding the print. - const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy); - sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28HZ"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2)); - gcode.process_subcommands_now(cmd); - #endif - - // Mark all axes as having been homed (no effect on current_position) - set_all_homed(); - - #if HAS_LEVELING - // Restore Z fade and possibly re-enable bed leveling compensation. - // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. - // TODO: Add a G28 parameter to leave leveling disabled. - sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1)); - gcode.process_subcommands_now(cmd); - - #if !HOMING_Z_DOWN - // The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9. - sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1)); - gcode.process_subcommands_now(cmd); - #endif - #endif - - #if ENABLED(POWER_LOSS_RECOVER_ZHOME) - // Z was homed down to the bed, so move up to the raised height. - z_now = z_raised; - sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - #endif - - // Recover volumetric extrusion state - #if DISABLED(NO_VOLUMETRICS) - #if HAS_MULTI_EXTRUDER - EXTRUDER_LOOP() { - sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - } - if (!info.flag.volumetric_enabled) { - sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder); - gcode.process_subcommands_now(cmd); - } - #else - if (info.flag.volumetric_enabled) { - sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - } - #endif - #endif - - // Restore all hotend temperatures - #if HAS_HOTEND - HOTEND_LOOP() { - const celsius_t et = info.target_temperature[e]; - if (et) { - #if HAS_MULTI_HOTEND - sprintf_P(cmd, PSTR("T%iS"), e); - gcode.process_subcommands_now(cmd); - #endif - sprintf_P(cmd, PSTR("M109S%i"), et); - gcode.process_subcommands_now(cmd); - } - } - #endif - - // Restore the previously active tool (with no_move) - #if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND - sprintf_P(cmd, PSTR("T%i S"), info.active_extruder); - gcode.process_subcommands_now(cmd); - #endif - - // Restore print cooling fan speeds - #if HAS_FAN - FANS_LOOP(i) { - const int f = info.fan_speed[i]; - if (f) { - sprintf_P(cmd, PSTR("M106P%iS%i"), i, f); - gcode.process_subcommands_now(cmd); - } - } - #endif - - // Restore retract and hop state from an active `G10` command - #if ENABLED(FWRETRACT) - EXTRUDER_LOOP() { - if (info.retract[e] != 0.0) { - fwretract.current_retract[e] = info.retract[e]; - fwretract.retracted.set(e); - } - } - fwretract.current_hop = info.retract_hop; - #endif - - #if ENABLED(GRADIENT_MIX) - memcpy(&mixer.gradient, &info.gradient, sizeof(info.gradient)); - #endif - - // Un-retract if there was a retract at outage - #if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0 - gcode.process_subcommands_now(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN))); - #endif - - // Additional purge on resume if configured - #if POWER_LOSS_PURGE_LEN - sprintf_P(cmd, PSTR("G1F3000E%d"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN)); - gcode.process_subcommands_now(cmd); - #endif - - #if ENABLED(NOZZLE_CLEAN_FEATURE) - gcode.process_subcommands_now(F("G12")); - #endif - - // Move back over to the saved XY - sprintf_P(cmd, PSTR("G1X%sY%sF3000"), - dtostrf(info.current_position.x, 1, 3, str_1), - dtostrf(info.current_position.y, 1, 3, str_2) - ); - gcode.process_subcommands_now(cmd); - - // Move back down to the saved Z for printing - sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_print, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - - // Restore the feedrate - sprintf_P(cmd, PSTR("G1F%d"), info.feedrate); - gcode.process_subcommands_now(cmd); - - // Restore E position with G92.9 - sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); - - TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat); - TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset); - TERN_(HAS_POSITION_SHIFT, position_shift = info.position_shift); - #if HAS_HOME_OFFSET || HAS_POSITION_SHIFT - LOOP_NUM_AXES(i) update_workspace_offset((AxisEnum)i); - #endif - - // Relative axis modes - gcode.axis_relative = info.axis_relative; - - #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - const uint8_t old_flags = marlin_debug_flags; - marlin_debug_flags |= MARLIN_DEBUG_ECHO; - #endif - - // Continue to apply PLR when a file is resumed! - enable(true); - - // Resume the SD file from the last position - char *fn = info.sd_filename; - sprintf_P(cmd, M23_STR, fn); - gcode.process_subcommands_now(cmd); - sprintf_P(cmd, PSTR("M24S%ldT%ld"), resume_sdpos, info.print_job_elapsed); - gcode.process_subcommands_now(cmd); - - TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags = old_flags); -} - -#if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - - void PrintJobRecovery::debug(FSTR_P const prefix) { - DEBUG_ECHOF(prefix); - DEBUG_ECHOLNPGM(" Job Recovery Info...\nvalid_head:", info.valid_head, " valid_foot:", info.valid_foot); - if (info.valid_head) { - if (info.valid_head == info.valid_foot) { - DEBUG_ECHOPGM("current_position: "); - LOOP_LOGICAL_AXES(i) { - if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.current_position[i]); - } - DEBUG_EOL(); - - DEBUG_ECHOLNPGM("feedrate: ", info.feedrate); - - DEBUG_ECHOLNPGM("zraise: ", info.zraise, " ", info.flag.raised ? "(before)" : ""); - - #if ENABLED(GCODE_REPEAT_MARKERS) - DEBUG_ECHOLNPGM("repeat index: ", info.stored_repeat.index); - LOOP_L_N(i, info.stored_repeat.index) - DEBUG_ECHOLNPGM("..... sdpos: ", info.stored_repeat.marker.sdpos, " count: ", info.stored_repeat.marker.counter); - #endif - - #if HAS_HOME_OFFSET - DEBUG_ECHOPGM("home_offset: "); - LOOP_NUM_AXES(i) { - if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.home_offset[i]); - } - DEBUG_EOL(); - #endif - - #if HAS_POSITION_SHIFT - DEBUG_ECHOPGM("position_shift: "); - LOOP_NUM_AXES(i) { - if (i) DEBUG_CHAR(','); - DEBUG_DECIMAL(info.position_shift[i]); - } - DEBUG_EOL(); - #endif - - #if HAS_MULTI_EXTRUDER - DEBUG_ECHOLNPGM("active_extruder: ", info.active_extruder); - #endif - - #if DISABLED(NO_VOLUMETRICS) - DEBUG_ECHOPGM("filament_size:"); - EXTRUDER_LOOP() DEBUG_ECHOLNPGM(" ", info.filament_size[e]); - DEBUG_EOL(); - #endif - - #if HAS_HOTEND - DEBUG_ECHOPGM("target_temperature: "); - HOTEND_LOOP() { - DEBUG_ECHO(info.target_temperature[e]); - if (e < HOTENDS - 1) DEBUG_CHAR(','); - } - DEBUG_EOL(); - #endif - - #if HAS_HEATED_BED - DEBUG_ECHOLNPGM("target_temperature_bed: ", info.target_temperature_bed); - #endif - - #if HAS_FAN - DEBUG_ECHOPGM("fan_speed: "); - FANS_LOOP(i) { - DEBUG_ECHO(info.fan_speed[i]); - if (i < FAN_COUNT - 1) DEBUG_CHAR(','); - } - DEBUG_EOL(); - #endif - - #if HAS_LEVELING - DEBUG_ECHOLNPGM("leveling: ", info.flag.leveling ? "ON" : "OFF", " fade: ", info.fade); - #endif - - #if ENABLED(FWRETRACT) - DEBUG_ECHOPGM("retract: "); - EXTRUDER_LOOP() { - DEBUG_ECHO(info.retract[e]); - if (e < EXTRUDERS - 1) DEBUG_CHAR(','); - } - DEBUG_EOL(); - DEBUG_ECHOLNPGM("retract_hop: ", info.retract_hop); - #endif - - // Mixing extruder and gradient - #if BOTH(MIXING_EXTRUDER, GRADIENT_MIX) - DEBUG_ECHOLNPGM("gradient: ", info.gradient.enabled ? "ON" : "OFF"); - #endif - - DEBUG_ECHOLNPGM("sd_filename: ", info.sd_filename); - DEBUG_ECHOLNPGM("sdpos: ", info.sdpos); - DEBUG_ECHOLNPGM("print_job_elapsed: ", info.print_job_elapsed); - - DEBUG_ECHOPGM("axis_relative:"); - if (TEST(info.axis_relative, REL_X)) DEBUG_ECHOPGM(" REL_X"); - if (TEST(info.axis_relative, REL_Y)) DEBUG_ECHOPGM(" REL_Y"); - if (TEST(info.axis_relative, REL_Z)) DEBUG_ECHOPGM(" REL_Z"); - if (TEST(info.axis_relative, REL_E)) DEBUG_ECHOPGM(" REL_E"); - if (TEST(info.axis_relative, E_MODE_ABS)) DEBUG_ECHOPGM(" E_MODE_ABS"); - if (TEST(info.axis_relative, E_MODE_REL)) DEBUG_ECHOPGM(" E_MODE_REL"); - DEBUG_EOL(); - - DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun)); - DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion)); - DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); - } - else - DEBUG_ECHOLNPGM("INVALID DATA"); - } - DEBUG_ECHOLNPGM("---"); - } - -#endif // DEBUG_POWER_LOSS_RECOVERY - -#endif // POWER_LOSS_RECOVERY diff --git a/src/feature/powerloss.h b/src/feature/powerloss.h deleted file mode 100644 index 33d9dc0..0000000 --- a/src/feature/powerloss.h +++ /dev/null @@ -1,225 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/powerloss.h - Resume an SD print after power-loss - */ - -#include "../sd/cardreader.h" -#include "../gcode/gcode.h" - -#include "../inc/MarlinConfig.h" - -#if ENABLED(GCODE_REPEAT_MARKERS) - #include "../feature/repeat.h" -#endif - -#if ENABLED(MIXING_EXTRUDER) - #include "../feature/mixing.h" -#endif - -#if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS) - #define POWER_LOSS_STATE HIGH -#endif - -#ifndef POWER_LOSS_ZRAISE - #define POWER_LOSS_ZRAISE 2 -#endif - -//#define DEBUG_POWER_LOSS_RECOVERY -//#define SAVE_EACH_CMD_MODE -//#define SAVE_INFO_INTERVAL_MS 0 - -typedef struct { - uint8_t valid_head; - - // Machine state - xyze_pos_t current_position; - uint16_t feedrate; - - float zraise; - - // Repeat information - #if ENABLED(GCODE_REPEAT_MARKERS) - Repeat stored_repeat; - #endif - - #if HAS_HOME_OFFSET - xyz_pos_t home_offset; - #endif - #if HAS_POSITION_SHIFT - xyz_pos_t position_shift; - #endif - #if HAS_MULTI_EXTRUDER - uint8_t active_extruder; - #endif - - #if DISABLED(NO_VOLUMETRICS) - float filament_size[EXTRUDERS]; - #endif - - #if HAS_HOTEND - celsius_t target_temperature[HOTENDS]; - #endif - #if HAS_HEATED_BED - celsius_t target_temperature_bed; - #endif - #if HAS_FAN - uint8_t fan_speed[FAN_COUNT]; - #endif - - #if HAS_LEVELING - float fade; - #endif - - #if ENABLED(FWRETRACT) - float retract[EXTRUDERS], retract_hop; - #endif - - // Mixing extruder and gradient - #if ENABLED(MIXING_EXTRUDER) - //uint_fast8_t selected_vtool; - //mixer_comp_t color[NR_MIXING_VIRTUAL_TOOLS][MIXING_STEPPERS]; - #if ENABLED(GRADIENT_MIX) - gradient_t gradient; - #endif - #endif - - // SD Filename and position - char sd_filename[MAXPATHNAMELENGTH]; - volatile uint32_t sdpos; - - // Job elapsed time - millis_t print_job_elapsed; - - // Relative axis modes - uint8_t axis_relative; - - // Misc. Marlin flags - struct { - bool raised:1; // Raised before saved - bool dryrun:1; // M111 S8 - bool allow_cold_extrusion:1; // M302 P1 - #if HAS_LEVELING - bool leveling:1; // M420 S - #endif - #if DISABLED(NO_VOLUMETRICS) - bool volumetric_enabled:1; // M200 S D - #endif - } flag; - - uint8_t valid_foot; - - bool valid() { return valid_head && valid_head == valid_foot; } - -} job_recovery_info_t; - -class PrintJobRecovery { - public: - static const char filename[5]; - - static SdFile file; - static job_recovery_info_t info; - - static uint8_t queue_index_r; //!< Queue index of the active command - static uint32_t cmd_sdpos, //!< SD position of the next command - sdpos[BUFSIZE]; //!< SD positions of queued commands - - #if HAS_DWIN_E3V2_BASIC - static bool dwin_flag; - #endif - - static void init(); - static void prepare(); - - static void setup() { - #if PIN_EXISTS(POWER_LOSS) - #if ENABLED(POWER_LOSS_PULLUP) - SET_INPUT_PULLUP(POWER_LOSS_PIN); - #elif ENABLED(POWER_LOSS_PULLDOWN) - SET_INPUT_PULLDOWN(POWER_LOSS_PIN); - #else - SET_INPUT(POWER_LOSS_PIN); - #endif - #endif - } - - // Track each command's file offsets - static uint32_t command_sdpos() { return sdpos[queue_index_r]; } - static void commit_sdpos(const uint8_t index_w) { sdpos[index_w] = cmd_sdpos; } - - static bool enabled; - static void enable(const bool onoff); - static void changed(); - - static bool exists() { return card.jobRecoverFileExists(); } - static void open(const bool read) { card.openJobRecoveryFile(read); } - static void close() { file.close(); } - - static bool check(); - static void resume(); - static void purge(); - - static void cancel() { purge(); } - - static void load(); - static void save(const bool force=ENABLED(SAVE_EACH_CMD_MODE), const float zraise=POWER_LOSS_ZRAISE, const bool raised=false); - - #if PIN_EXISTS(POWER_LOSS) - static void outage() { - static constexpr uint8_t OUTAGE_THRESHOLD = 3; - static uint8_t outage_counter = 0; - if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE) { - outage_counter++; - if (outage_counter >= OUTAGE_THRESHOLD) _outage(); - } - else - outage_counter = 0; - } - #endif - - // The referenced file exists - static bool interrupted_file_exists() { return card.fileExists(info.sd_filename); } - - static bool valid() { return info.valid() && interrupted_file_exists(); } - - #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - static void debug(FSTR_P const prefix); - #else - static void debug(FSTR_P const) {} - #endif - - private: - static void write(); - - #if ENABLED(BACKUP_POWER_SUPPLY) - static void retract_and_lift(const_float_t zraise); - #endif - - #if PIN_EXISTS(POWER_LOSS) || ENABLED(DEBUG_POWER_LOSS_RECOVERY) - friend class GcodeSuite; - static void _outage(TERN_(DEBUG_POWER_LOSS_RECOVERY, const bool simulated=false)); - #endif -}; - -extern PrintJobRecovery recovery; diff --git a/src/feature/probe_temp_comp.cpp b/src/feature/probe_temp_comp.cpp deleted file mode 100644 index b5f636e..0000000 --- a/src/feature/probe_temp_comp.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if HAS_PTC - -//#define DEBUG_PTC // Print extra debug output with 'M871' - -#include "probe_temp_comp.h" -#include -#include "../module/temperature.h" - -ProbeTempComp ptc; - -#if ENABLED(PTC_PROBE) - constexpr int16_t z_offsets_probe_default[PTC_PROBE_COUNT] = PTC_PROBE_ZOFFS; - int16_t ProbeTempComp::z_offsets_probe[PTC_PROBE_COUNT] = PTC_PROBE_ZOFFS; -#endif - -#if ENABLED(PTC_BED) - constexpr int16_t z_offsets_bed_default[PTC_BED_COUNT] = PTC_BED_ZOFFS; - int16_t ProbeTempComp::z_offsets_bed[PTC_BED_COUNT] = PTC_BED_ZOFFS; -#endif - -#if ENABLED(PTC_HOTEND) - constexpr int16_t z_offsets_hotend_default[PTC_HOTEND_COUNT] = PTC_HOTEND_ZOFFS; - int16_t ProbeTempComp::z_offsets_hotend[PTC_HOTEND_COUNT] = PTC_HOTEND_ZOFFS; -#endif - -int16_t *ProbeTempComp::sensor_z_offsets[TSI_COUNT] = { - #if ENABLED(PTC_PROBE) - ProbeTempComp::z_offsets_probe, - #endif - #if ENABLED(PTC_BED) - ProbeTempComp::z_offsets_bed, - #endif - #if ENABLED(PTC_HOTEND) - ProbeTempComp::z_offsets_hotend, - #endif -}; - -constexpr temp_calib_t ProbeTempComp::cali_info[TSI_COUNT]; - -uint8_t ProbeTempComp::calib_idx; // = 0 -float ProbeTempComp::init_measurement; // = 0.0 -bool ProbeTempComp::enabled = true; - -void ProbeTempComp::reset() { - TERN_(PTC_PROBE, LOOP_L_N(i, PTC_PROBE_COUNT) z_offsets_probe[i] = z_offsets_probe_default[i]); - TERN_(PTC_BED, LOOP_L_N(i, PTC_BED_COUNT) z_offsets_bed[i] = z_offsets_bed_default[i]); - TERN_(PTC_HOTEND, LOOP_L_N(i, PTC_HOTEND_COUNT) z_offsets_hotend[i] = z_offsets_hotend_default[i]); -} - -void ProbeTempComp::clear_offsets(const TempSensorID tsi) { - LOOP_L_N(i, cali_info[tsi].measurements) - sensor_z_offsets[tsi][i] = 0; - calib_idx = 0; -} - -bool ProbeTempComp::set_offset(const TempSensorID tsi, const uint8_t idx, const int16_t offset) { - if (idx >= cali_info[tsi].measurements) return false; - sensor_z_offsets[tsi][idx] = offset; - return true; -} - -void ProbeTempComp::print_offsets() { - LOOP_L_N(s, TSI_COUNT) { - celsius_t temp = cali_info[s].start_temp; - for (int16_t i = -1; i < cali_info[s].measurements; ++i) { - SERIAL_ECHOF( - TERN_(PTC_BED, s == TSI_BED ? F("Bed") :) - TERN_(PTC_HOTEND, s == TSI_EXT ? F("Extruder") :) - F("Probe") - ); - SERIAL_ECHOLNPGM( - " temp: ", temp, - "C; Offset: ", i < 0 ? 0.0f : sensor_z_offsets[s][i], " um" - ); - temp += cali_info[s].temp_resolution; - } - } - #if ENABLED(DEBUG_PTC) - float meas[4] = { 0, 0, 0, 0 }; - compensate_measurement(TSI_PROBE, 27.5, meas[0]); - compensate_measurement(TSI_PROBE, 32.5, meas[1]); - compensate_measurement(TSI_PROBE, 77.5, meas[2]); - compensate_measurement(TSI_PROBE, 82.5, meas[3]); - SERIAL_ECHOLNPGM("DEBUG_PTC 27.5:", meas[0], " 32.5:", meas[1], " 77.5:", meas[2], " 82.5:", meas[3]); - #endif -} - -void ProbeTempComp::prepare_new_calibration(const_float_t init_meas_z) { - calib_idx = 0; - init_measurement = init_meas_z; -} - -void ProbeTempComp::push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z) { - if (calib_idx >= cali_info[tsi].measurements) return; - sensor_z_offsets[tsi][calib_idx++] = static_cast((meas_z - init_measurement) * 1000.0f); -} - -bool ProbeTempComp::finish_calibration(const TempSensorID tsi) { - if (!calib_idx) { - SERIAL_ECHOLNPGM("!No measurements."); - clear_offsets(tsi); - return false; - } - - const uint8_t measurements = cali_info[tsi].measurements; - const celsius_t start_temp = cali_info[tsi].start_temp, - res_temp = cali_info[tsi].temp_resolution; - int16_t * const data = sensor_z_offsets[tsi]; - - // Extrapolate - float k, d; - if (calib_idx < measurements) { - SERIAL_ECHOLNPGM("Got ", calib_idx, " measurements. "); - if (linear_regression(tsi, k, d)) { - SERIAL_ECHOPGM("Applying linear extrapolation"); - for (; calib_idx < measurements; ++calib_idx) { - const celsius_float_t temp = start_temp + float(calib_idx + 1) * res_temp; - data[calib_idx] = static_cast(k * temp + d); - } - } - else { - // Simply use the last measured value for higher temperatures - SERIAL_ECHOPGM("Failed to extrapolate"); - const int16_t last_val = data[calib_idx-1]; - for (; calib_idx < measurements; ++calib_idx) - data[calib_idx] = last_val; - } - SERIAL_ECHOLNPGM(" for higher temperatures."); - } - - // Sanity check - for (calib_idx = 0; calib_idx < measurements; ++calib_idx) { - // Restrict the max. offset - if (ABS(data[calib_idx]) > 2000) { - SERIAL_ECHOLNPGM("!Invalid Z-offset detected (0-2)."); - clear_offsets(tsi); - return false; - } - // Restrict the max. offset difference between two probings - if (calib_idx > 0 && ABS(data[calib_idx - 1] - data[calib_idx]) > 800) { - SERIAL_ECHOLNPGM("!Invalid Z-offset between two probings detected (0-0.8)."); - clear_offsets(tsi); - return false; - } - } - - return true; -} - -void ProbeTempComp::apply_compensation(float &meas_z) { - if (!enabled) return; - TERN_(PTC_BED, compensate_measurement(TSI_BED, thermalManager.degBed(), meas_z)); - TERN_(PTC_PROBE, compensate_measurement(TSI_PROBE, thermalManager.degProbe(), meas_z)); - TERN_(PTC_HOTEND, compensate_measurement(TSI_EXT, thermalManager.degHotend(0), meas_z)); -} - -void ProbeTempComp::compensate_measurement(const TempSensorID tsi, const celsius_t temp, float &meas_z) { - const uint8_t measurements = cali_info[tsi].measurements; - const celsius_t start_temp = cali_info[tsi].start_temp, - res_temp = cali_info[tsi].temp_resolution, - end_temp = start_temp + measurements * res_temp; - const int16_t * const data = sensor_z_offsets[tsi]; - - // Given a data index, return { celsius, zoffset } in the form { x, y } - auto tpoint = [&](uint8_t i) -> xy_float_t { - return xy_float_t({ static_cast(start_temp) + i * res_temp, i ? static_cast(data[i - 1]) : 0.0f }); - }; - - // Interpolate Z based on a temperature being within a given range - auto linear_interp = [](const_float_t x, xy_float_t p1, xy_float_t p2) { - // zoffs1 + zoffset_per_toffset * toffset - return p1.y + (p2.y - p1.y) / (p2.x - p1.x) * (x - p1.x); - }; - - // offset in µm - float offset = 0.0f; - - #if PTC_LINEAR_EXTRAPOLATION - if (temp < start_temp) - offset = linear_interp(temp, tpoint(0), tpoint(PTC_LINEAR_EXTRAPOLATION)); - else if (temp >= end_temp) - offset = linear_interp(temp, tpoint(measurements - PTC_LINEAR_EXTRAPOLATION), tpoint(measurements)); - #else - if (temp < start_temp) - offset = 0.0f; - else if (temp >= end_temp) - offset = static_cast(data[measurements - 1]); - #endif - else { - // Linear interpolation - const int8_t idx = static_cast((temp - start_temp) / res_temp); - offset = linear_interp(temp, tpoint(idx), tpoint(idx + 1)); - } - - // convert offset to mm and apply it - meas_z -= offset / 1000.0f; -} - -bool ProbeTempComp::linear_regression(const TempSensorID tsi, float &k, float &d) { - if (!WITHIN(calib_idx, 1, cali_info[tsi].measurements)) return false; - - const celsius_t start_temp = cali_info[tsi].start_temp, - res_temp = cali_info[tsi].temp_resolution; - const int16_t * const data = sensor_z_offsets[tsi]; - - float sum_x = start_temp, - sum_x2 = sq(start_temp), - sum_xy = 0, sum_y = 0; - - float xi = static_cast(start_temp); - LOOP_L_N(i, calib_idx) { - const float yi = static_cast(data[i]); - xi += res_temp; - sum_x += xi; - sum_x2 += sq(xi); - sum_xy += xi * yi; - sum_y += yi; - } - - const float denom = static_cast(calib_idx + 1) * sum_x2 - sq(sum_x); - if (fabs(denom) <= 10e-5) { - // Singularity - unable to solve - k = d = 0.0; - return false; - } - - k = (static_cast(calib_idx + 1) * sum_xy - sum_x * sum_y) / denom; - d = (sum_y - k * sum_x) / static_cast(calib_idx + 1); - - return true; -} - -#endif // HAS_PTC diff --git a/src/feature/probe_temp_comp.h b/src/feature/probe_temp_comp.h deleted file mode 100644 index 42348db..0000000 --- a/src/feature/probe_temp_comp.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" - -enum TempSensorID : uint8_t { - #if ENABLED(PTC_PROBE) - TSI_PROBE, - #endif - #if ENABLED(PTC_BED) - TSI_BED, - #endif - #if ENABLED(PTC_HOTEND) - TSI_EXT, - #endif - TSI_COUNT -}; - -typedef struct { - uint8_t measurements; // Max. number of measurements to be stored (35 - 80°C) - celsius_t temp_resolution, // Resolution in °C between measurements - start_temp; // Base measurement; z-offset == 0 -} temp_calib_t; - -/** - * Probe temperature compensation implementation. - * Z-probes like the P.I.N.D.A V2 allow for compensation of - * measurement errors/shifts due to changed temperature. - */ - -class ProbeTempComp { - public: - - static constexpr temp_calib_t cali_info[TSI_COUNT] = { - #if ENABLED(PTC_PROBE) - { PTC_PROBE_COUNT, PTC_PROBE_RES, PTC_PROBE_START }, // Probe - #endif - #if ENABLED(PTC_BED) - { PTC_BED_COUNT, PTC_BED_RES, PTC_BED_START }, // Bed - #endif - #if ENABLED(PTC_HOTEND) - { PTC_HOTEND_COUNT, PTC_HOTEND_RES, PTC_HOTEND_START }, // Extruder - #endif - }; - - static int16_t *sensor_z_offsets[TSI_COUNT]; - #if ENABLED(PTC_PROBE) - static int16_t z_offsets_probe[PTC_PROBE_COUNT]; // (µm) - #endif - #if ENABLED(PTC_BED) - static int16_t z_offsets_bed[PTC_BED_COUNT]; // (µm) - #endif - #if ENABLED(PTC_HOTEND) - static int16_t z_offsets_hotend[PTC_HOTEND_COUNT]; // (µm) - #endif - - static void reset_index() { calib_idx = 0; }; - static uint8_t get_index() { return calib_idx; } - static void reset(); - static void clear_all_offsets() { - TERN_(PTC_PROBE, clear_offsets(TSI_PROBE)); - TERN_(PTC_BED, clear_offsets(TSI_BED)); - TERN_(PTC_HOTEND, clear_offsets(TSI_EXT)); - } - static bool set_offset(const TempSensorID tsi, const uint8_t idx, const int16_t offset); - static void print_offsets(); - static void prepare_new_calibration(const_float_t init_meas_z); - static void push_back_new_measurement(const TempSensorID tsi, const_float_t meas_z); - static bool finish_calibration(const TempSensorID tsi); - static void set_enabled(const bool ena) { enabled = ena; } - - // Apply all temperature compensation adjustments - static void apply_compensation(float &meas_z); - - private: - static uint8_t calib_idx; - static bool enabled; - - static void clear_offsets(const TempSensorID tsi); - - /** - * Base value. Temperature compensation values will be deltas - * to this value, set at first probe. - */ - static float init_measurement; - - /** - * Fit a linear function in measured temperature offsets - * to allow generating values of higher temperatures. - */ - static bool linear_regression(const TempSensorID tsi, float &k, float &d); - - static void compensate_measurement(const TempSensorID tsi, const celsius_t temp, float &meas_z); -}; - -extern ProbeTempComp ptc; diff --git a/src/feature/repeat.cpp b/src/feature/repeat.cpp deleted file mode 100644 index 165f71f..0000000 --- a/src/feature/repeat.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(GCODE_REPEAT_MARKERS) - -//#define DEBUG_GCODE_REPEAT_MARKERS - -#include "repeat.h" - -#include "../gcode/gcode.h" -#include "../sd/cardreader.h" - -#define DEBUG_OUT ENABLED(DEBUG_GCODE_REPEAT_MARKERS) -#include "../core/debug_out.h" - -repeat_marker_t Repeat::marker[MAX_REPEAT_NESTING]; -uint8_t Repeat::index; - -void Repeat::add_marker(const uint32_t sdpos, const uint16_t count) { - if (index >= MAX_REPEAT_NESTING) - SERIAL_ECHO_MSG("!Too many markers."); - else { - marker[index].sdpos = sdpos; - marker[index].counter = count ?: -1; - index++; - DEBUG_ECHOLNPGM("Add Marker ", index, " at ", sdpos, " (", count, ")"); - } -} - -void Repeat::loop() { - if (!index) // No marker? - SERIAL_ECHO_MSG("!No marker set."); // Inform the user. - else { - const uint8_t ind = index - 1; // Active marker's index - if (!marker[ind].counter) { // Did its counter run out? - DEBUG_ECHOLNPGM("Pass Marker ", index); - index--; // Carry on. Previous marker on the next 'M808'. - } - else { - card.setIndex(marker[ind].sdpos); // Loop back to the marker. - if (marker[ind].counter > 0) // Ignore a negative (or zero) counter. - --marker[ind].counter; // Decrement the counter. If zero this 'M808' will be skipped next time. - DEBUG_ECHOLNPGM("Goto Marker ", index, " at ", marker[ind].sdpos, " (", marker[ind].counter, ")"); - } - } -} - -void Repeat::cancel() { LOOP_L_N(i, index) marker[i].counter = 0; } - -void Repeat::early_parse_M808(char * const cmd) { - if (is_command_M808(cmd)) { - DEBUG_ECHOLNPGM("Parsing \"", cmd, "\""); - parser.parse(cmd); - if (parser.seen('L')) - add_marker(card.getIndex(), parser.value_ushort()); - else - Repeat::loop(); - } -} - -#endif // GCODE_REPEAT_MARKERS diff --git a/src/feature/repeat.h b/src/feature/repeat.h deleted file mode 100644 index fc11e4a..0000000 --- a/src/feature/repeat.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" -#include "../gcode/parser.h" - -#include - -#define MAX_REPEAT_NESTING 10 - -typedef struct { - uint32_t sdpos; // The repeat file position - int16_t counter; // The counter for looping -} repeat_marker_t; - -class Repeat { -private: - static repeat_marker_t marker[MAX_REPEAT_NESTING]; - static uint8_t index; -public: - static void reset() { index = 0; } - static bool is_active() { - LOOP_L_N(i, index) if (marker[i].counter) return true; - return false; - } - static bool is_command_M808(char * const cmd) { return cmd[0] == 'M' && cmd[1] == '8' && cmd[2] == '0' && cmd[3] == '8' && !NUMERIC(cmd[4]); } - static void early_parse_M808(char * const cmd); - static void add_marker(const uint32_t sdpos, const uint16_t count); - static void loop(); - static void cancel(); -}; - -extern Repeat repeat; diff --git a/src/feature/runout.cpp b/src/feature/runout.cpp deleted file mode 100644 index 98b6bd0..0000000 --- a/src/feature/runout.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/runout.cpp - Runout sensor support - */ - -#include "../inc/MarlinConfigPre.h" - -#if HAS_FILAMENT_SENSOR - -#include "runout.h" - -FilamentMonitor runout; - -bool FilamentMonitorBase::enabled = true, - FilamentMonitorBase::filament_ran_out; // = false - -#if ENABLED(HOST_ACTION_COMMANDS) - bool FilamentMonitorBase::host_handling; // = false -#endif - -#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) - #include "../module/tool_change.h" - #define DEBUG_OUT ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE) - #include "../core/debug_out.h" -#endif - -#if HAS_FILAMENT_RUNOUT_DISTANCE - float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM; - volatile float RunoutResponseDelayed::runout_mm_countdown[NUM_RUNOUT_SENSORS]; - #if ENABLED(FILAMENT_MOTION_SENSOR) - uint8_t FilamentSensorEncoder::motion_detected; - #endif -#else - int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0 -#endif - -// -// Filament Runout event handler -// -#include "../MarlinCore.h" -#include "../feature/pause.h" -#include "../gcode/queue.h" - -#if ENABLED(HOST_ACTION_COMMANDS) - #include "host_actions.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../lcd/e3v2/proui/dwin.h" -#endif - -void event_filament_runout(const uint8_t extruder) { - - if (did_pause_print) return; // Action already in progress. Purge triggered repeated runout. - - #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) - if (migration.in_progress) { - DEBUG_ECHOLNPGM("Migration Already In Progress"); - return; // Action already in progress. Purge triggered repeated runout. - } - if (migration.automode) { - DEBUG_ECHOLNPGM("Migration Starting"); - if (extruder_migration()) return; - } - #endif - - TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getTool(extruder))); - TERN_(DWIN_LCD_PROUI, DWIN_FilamentRunout(extruder)); - - #if ANY(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS, MULTI_FILAMENT_SENSOR) - const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, extruder); - #endif - - //action:out_of_filament - #if ENABLED(HOST_PROMPT_SUPPORT) - hostui.prompt_do(PROMPT_FILAMENT_RUNOUT, F("FilamentRunout T"), tool); //action:out_of_filament - #endif - - const bool run_runout_script = !runout.host_handling; - - #if ENABLED(HOST_ACTION_COMMANDS) - if (run_runout_script - && ( strstr(FILAMENT_RUNOUT_SCRIPT, "M600") - || strstr(FILAMENT_RUNOUT_SCRIPT, "M125") - || TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25")) - ) - ) { - hostui.paused(false); - } - else { - // Legacy Repetier command for use until newer version supports standard dialog - // To be removed later when pause command also triggers dialog - #ifdef ACTION_ON_FILAMENT_RUNOUT - hostui.action(F(ACTION_ON_FILAMENT_RUNOUT " T"), false); - SERIAL_CHAR(tool); - SERIAL_EOL(); - #endif - - hostui.pause(false); - } - SERIAL_ECHOPGM(" " ACTION_REASON_ON_FILAMENT_RUNOUT " "); - SERIAL_CHAR(tool); - SERIAL_EOL(); - #endif // HOST_ACTION_COMMANDS - - if (run_runout_script) { - #if MULTI_FILAMENT_SENSOR - char script[strlen(FILAMENT_RUNOUT_SCRIPT) + 1]; - sprintf_P(script, PSTR(FILAMENT_RUNOUT_SCRIPT), tool); - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - SERIAL_ECHOLNPGM("Runout Command: ", script); - #endif - queue.inject(script); - #else - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - SERIAL_ECHOPGM("Runout Command: "); - SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT); - #endif - queue.inject(F(FILAMENT_RUNOUT_SCRIPT)); - #endif - } -} - -#endif // HAS_FILAMENT_SENSOR diff --git a/src/feature/runout.h b/src/feature/runout.h deleted file mode 100644 index e74d857..0000000 --- a/src/feature/runout.h +++ /dev/null @@ -1,413 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/runout.h - Runout sensor support - */ - -#include "../sd/cardreader.h" -#include "../module/printcounter.h" -#include "../module/planner.h" -#include "../module/stepper.h" // for block_t -#include "../gcode/queue.h" -#include "../feature/pause.h" - -#include "../inc/MarlinConfig.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../lcd/extui/ui_api.h" -#endif - -//#define FILAMENT_RUNOUT_SENSOR_DEBUG -#ifndef FILAMENT_RUNOUT_THRESHOLD - #define FILAMENT_RUNOUT_THRESHOLD 5 -#endif - -void event_filament_runout(const uint8_t extruder); - -template -class TFilamentMonitor; -class FilamentSensorEncoder; -class FilamentSensorSwitch; -class RunoutResponseDelayed; -class RunoutResponseDebounced; - -/********************************* TEMPLATE SPECIALIZATION *********************************/ - -typedef TFilamentMonitor< - TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced), - TERN(FILAMENT_MOTION_SENSOR, FilamentSensorEncoder, FilamentSensorSwitch) - > FilamentMonitor; - -extern FilamentMonitor runout; - -/*******************************************************************************************/ - -class FilamentMonitorBase { - public: - static bool enabled, filament_ran_out; - - #if ENABLED(HOST_ACTION_COMMANDS) - static bool host_handling; - #else - static constexpr bool host_handling = false; - #endif -}; - -template -class TFilamentMonitor : public FilamentMonitorBase { - private: - typedef RESPONSE_T response_t; - typedef SENSOR_T sensor_t; - static response_t response; - static sensor_t sensor; - - public: - static void setup() { - sensor.setup(); - reset(); - } - - static void reset() { - filament_ran_out = false; - response.reset(); - } - - // Call this method when filament is present, - // so the response can reset its counter. - static void filament_present(const uint8_t extruder) { - response.filament_present(extruder); - } - - #if HAS_FILAMENT_RUNOUT_DISTANCE - static float& runout_distance() { return response.runout_distance_mm; } - static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; } - #endif - - // Handle a block completion. RunoutResponseDelayed uses this to - // add up the length of filament moved while the filament is out. - static void block_completed(const block_t * const b) { - if (enabled) { - response.block_completed(b); - sensor.block_completed(b); - } - } - - // Give the response a chance to update its counter. - static void run() { - if (enabled && !filament_ran_out && (printingIsActive() || did_pause_print)) { - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here - response.run(); - sensor.run(); - const uint8_t runout_flags = response.has_run_out(); - TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei()); - #if MULTI_FILAMENT_SENSOR - #if ENABLED(WATCH_ALL_RUNOUT_SENSORS) - const bool ran_out = !!runout_flags; // any sensor triggers - uint8_t extruder = 0; - if (ran_out) { - uint8_t bitmask = runout_flags; - while (!(bitmask & 1)) { - bitmask >>= 1; - extruder++; - } - } - #else - const bool ran_out = TEST(runout_flags, active_extruder); // suppress non active extruders - uint8_t extruder = active_extruder; - #endif - #else - const bool ran_out = !!runout_flags; - uint8_t extruder = active_extruder; - #endif - - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - if (runout_flags) { - SERIAL_ECHOPGM("Runout Sensors: "); - LOOP_L_N(i, 8) SERIAL_ECHO('0' + TEST(runout_flags, i)); - SERIAL_ECHOPGM(" -> ", extruder); - if (ran_out) SERIAL_ECHOPGM(" RUN OUT"); - SERIAL_EOL(); - } - #endif - - if (ran_out) { - filament_ran_out = true; - event_filament_runout(extruder); - planner.synchronize(); - } - } - } -}; - -/*************************** FILAMENT PRESENCE SENSORS ***************************/ - -class FilamentSensorBase { - protected: - /** - * Called by FilamentSensorSwitch::run when filament is detected. - * Called by FilamentSensorEncoder::block_completed when motion is detected. - */ - static void filament_present(const uint8_t extruder) { - runout.filament_present(extruder); // ...which calls response.filament_present(extruder) - } - - public: - static void setup() { - #define _INIT_RUNOUT_PIN(P,S,U,D) do{ if (ENABLED(U)) SET_INPUT_PULLUP(P); else if (ENABLED(D)) SET_INPUT_PULLDOWN(P); else SET_INPUT(P); }while(0) - #define INIT_RUNOUT_PIN(N) _INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN, FIL_RUNOUT##N##_STATE, FIL_RUNOUT##N##_PULLUP, FIL_RUNOUT##N##_PULLDOWN) - #if NUM_RUNOUT_SENSORS >= 1 - INIT_RUNOUT_PIN(1); - #endif - #if NUM_RUNOUT_SENSORS >= 2 - INIT_RUNOUT_PIN(2); - #endif - #if NUM_RUNOUT_SENSORS >= 3 - INIT_RUNOUT_PIN(3); - #endif - #if NUM_RUNOUT_SENSORS >= 4 - INIT_RUNOUT_PIN(4); - #endif - #if NUM_RUNOUT_SENSORS >= 5 - INIT_RUNOUT_PIN(5); - #endif - #if NUM_RUNOUT_SENSORS >= 6 - INIT_RUNOUT_PIN(6); - #endif - #if NUM_RUNOUT_SENSORS >= 7 - INIT_RUNOUT_PIN(7); - #endif - #if NUM_RUNOUT_SENSORS >= 8 - INIT_RUNOUT_PIN(8); - #endif - #undef _INIT_RUNOUT_PIN - #undef INIT_RUNOUT_PIN - } - - // Return a bitmask of runout pin states - static uint8_t poll_runout_pins() { - #define _OR_RUNOUT(N) | (READ(FIL_RUNOUT##N##_PIN) ? _BV((N) - 1) : 0) - return (0 REPEAT_1(NUM_RUNOUT_SENSORS, _OR_RUNOUT)); - #undef _OR_RUNOUT - } - - // Return a bitmask of runout flag states (1 bits always indicates runout) - static uint8_t poll_runout_states() { - return poll_runout_pins() ^ uint8_t(0 - #if NUM_RUNOUT_SENSORS >= 1 - | (FIL_RUNOUT1_STATE ? 0 : _BV(1 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 2 - | (FIL_RUNOUT2_STATE ? 0 : _BV(2 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 3 - | (FIL_RUNOUT3_STATE ? 0 : _BV(3 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 4 - | (FIL_RUNOUT4_STATE ? 0 : _BV(4 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 5 - | (FIL_RUNOUT5_STATE ? 0 : _BV(5 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 6 - | (FIL_RUNOUT6_STATE ? 0 : _BV(6 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 7 - | (FIL_RUNOUT7_STATE ? 0 : _BV(7 - 1)) - #endif - #if NUM_RUNOUT_SENSORS >= 8 - | (FIL_RUNOUT8_STATE ? 0 : _BV(8 - 1)) - #endif - ); - } -}; - -#if ENABLED(FILAMENT_MOTION_SENSOR) - - /** - * This sensor uses a magnetic encoder disc and a Hall effect - * sensor (or a slotted disc and optical sensor). The state - * will toggle between 0 and 1 on filament movement. It can detect - * filament runout and stripouts or jams. - */ - class FilamentSensorEncoder : public FilamentSensorBase { - private: - static uint8_t motion_detected; - - static void poll_motion_sensor() { - static uint8_t old_state; - const uint8_t new_state = poll_runout_pins(), - change = old_state ^ new_state; - old_state = new_state; - - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - if (change) { - SERIAL_ECHOPGM("Motion detected:"); - LOOP_L_N(e, NUM_RUNOUT_SENSORS) - if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e); - SERIAL_EOL(); - } - #endif - - motion_detected |= change; - } - - public: - static void block_completed(const block_t * const b) { - // If the sensor wheel has moved since the last call to - // this method reset the runout counter for the extruder. - if (TEST(motion_detected, b->extruder)) - filament_present(b->extruder); - - // Clear motion triggers for next block - motion_detected = 0; - } - - static void run() { poll_motion_sensor(); } - }; - -#else - - /** - * This is a simple endstop switch in the path of the filament. - * It can detect filament runout, but not stripouts or jams. - */ - class FilamentSensorSwitch : public FilamentSensorBase { - private: - static bool poll_runout_state(const uint8_t extruder) { - const uint8_t runout_states = poll_runout_states(); - #if MULTI_FILAMENT_SENSOR - if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating()) - && !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled) - ) return TEST(runout_states, extruder); // A specific extruder ran out - #else - UNUSED(extruder); - #endif - return !!runout_states; // Any extruder ran out - } - - public: - static void block_completed(const block_t * const) {} - - static void run() { - LOOP_L_N(s, NUM_RUNOUT_SENSORS) { - const bool out = poll_runout_state(s); - if (!out) filament_present(s); - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - static uint8_t was_out; // = 0 - if (out != TEST(was_out, s)) { - TBI(was_out, s); - SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN")); - } - #endif - } - } - }; - - -#endif // !FILAMENT_MOTION_SENSOR - -/********************************* RESPONSE TYPE *********************************/ - -#if HAS_FILAMENT_RUNOUT_DISTANCE - - // RunoutResponseDelayed triggers a runout event only if the length - // of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed - // during a runout condition. - class RunoutResponseDelayed { - private: - static volatile float runout_mm_countdown[NUM_RUNOUT_SENSORS]; - - public: - static float runout_distance_mm; - - static void reset() { - LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i); - } - - static void run() { - #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) - static millis_t t = 0; - const millis_t ms = millis(); - if (ELAPSED(ms, t)) { - t = millis() + 1000UL; - LOOP_L_N(i, NUM_RUNOUT_SENSORS) - SERIAL_ECHOF(i ? F(", ") : F("Remaining mm: "), runout_mm_countdown[i]); - SERIAL_EOL(); - } - #endif - } - - static uint8_t has_run_out() { - uint8_t runout_flags = 0; - LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_mm_countdown[i] < 0) SBI(runout_flags, i); - return runout_flags; - } - - static void filament_present(const uint8_t extruder) { - runout_mm_countdown[extruder] = runout_distance_mm; - } - - static void block_completed(const block_t * const b) { - if (b->steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state - // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. - const uint8_t e = b->extruder; - const int32_t steps = b->steps.e; - runout_mm_countdown[e] -= (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)]; - } - } - }; - -#else // !HAS_FILAMENT_RUNOUT_DISTANCE - - // RunoutResponseDebounced triggers a runout event after a runout - // condition has been detected runout_threshold times in a row. - - class RunoutResponseDebounced { - private: - static constexpr int8_t runout_threshold = FILAMENT_RUNOUT_THRESHOLD; - static int8_t runout_count[NUM_RUNOUT_SENSORS]; - - public: - static void reset() { - LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i); - } - - static void run() { - LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] >= 0) runout_count[i]--; - } - - static uint8_t has_run_out() { - uint8_t runout_flags = 0; - LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_count[i] < 0) SBI(runout_flags, i); - return runout_flags; - } - - static void block_completed(const block_t * const) { } - - static void filament_present(const uint8_t extruder) { - runout_count[extruder] = runout_threshold; - } - }; - -#endif // !HAS_FILAMENT_RUNOUT_DISTANCE diff --git a/src/feature/solenoid.cpp b/src/feature/solenoid.cpp deleted file mode 100644 index 861e44e..0000000 --- a/src/feature/solenoid.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL) - -#include "solenoid.h" - -#include "../module/motion.h" // for active_extruder -#include "../module/tool_change.h" - -// Used primarily with MANUAL_SOLENOID_CONTROL -static void set_solenoid(const uint8_t num, const uint8_t state) { - #define _SOL_CASE(N) case N: TERN_(HAS_SOLENOID_##N, OUT_WRITE(SOL##N##_PIN, state)); break; - switch (num) { - REPEAT(8, _SOL_CASE) - default: SERIAL_ECHO_MSG(STR_INVALID_SOLENOID); break; - } - - #if ENABLED(PARKING_EXTRUDER) - if (state == LOW && active_extruder == num) // If active extruder's solenoid is disabled, carriage is considered parked - parking_extruder_set_parked(true); - #endif -} - -// PARKING_EXTRUDER options alter the default behavior of solenoids to ensure compliance of M380-381 -void enable_solenoid(const uint8_t num) { set_solenoid(num, TERN1(PARKING_EXTRUDER, PE_MAGNET_ON_STATE)); } -void disable_solenoid(const uint8_t num) { set_solenoid(num, TERN0(PARKING_EXTRUDER, !PE_MAGNET_ON_STATE)); } - -void disable_all_solenoids() { - #define _SOL_DISABLE(N) TERN_(HAS_SOLENOID_##N, disable_solenoid(N)); - REPEAT(8, _SOL_DISABLE) -} - -#endif // EXT_SOLENOID || MANUAL_SOLENOID_CONTROL diff --git a/src/feature/solenoid.h b/src/feature/solenoid.h deleted file mode 100644 index 3131aeb..0000000 --- a/src/feature/solenoid.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -void disable_all_solenoids(); -void enable_solenoid(const uint8_t num); -void disable_solenoid(const uint8_t num); diff --git a/src/feature/spindle_laser.cpp b/src/feature/spindle_laser.cpp deleted file mode 100644 index da38646..0000000 --- a/src/feature/spindle_laser.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/spindle_laser.cpp - */ - -#include "../inc/MarlinConfig.h" - -#if HAS_CUTTER - -#include "spindle_laser.h" - -#if ENABLED(SPINDLE_SERVO) - #include "../module/servo.h" -#endif - -#if ENABLED(I2C_AMMETER) - #include "../feature/ammeter.h" -#endif - -SpindleLaser cutter; -bool SpindleLaser::enable_state; // Virtual enable state, controls enable pin if present and or apply power if > 0 -uint8_t SpindleLaser::power, // Actual power output 0-255 ocr or "0 = off" > 0 = "on" - SpindleLaser::last_power_applied; // = 0 // Basic power state tracking - -#if ENABLED(LASER_FEATURE) - cutter_test_pulse_t SpindleLaser::testPulse = 50; // (ms) Test fire pulse default duration - uint8_t SpindleLaser::last_block_power; // = 0 // Track power changes for dynamic inline power - feedRate_t SpindleLaser::feedrate_mm_m = 1500, - SpindleLaser::last_feedrate_mm_m; // = 0 // (mm/min) Track feedrate changes for dynamic power -#endif - -bool SpindleLaser::isReadyForUI = false; // Ready to apply power setting from the UI to OCR -CutterMode SpindleLaser::cutter_mode = CUTTER_MODE_STANDARD; // Default is standard mode - -constexpr cutter_cpower_t SpindleLaser::power_floor; -cutter_power_t SpindleLaser::menuPower = 0, // Power value via LCD menu in PWM, PERCENT, or RPM based on configured format set by CUTTER_POWER_UNIT. - SpindleLaser::unitPower = 0; // Unit power is in PWM, PERCENT, or RPM based on CUTTER_POWER_UNIT. - -cutter_frequency_t SpindleLaser::frequency; // PWM frequency setting; range: 2K - 50K - -#define SPINDLE_LASER_PWM_OFF TERN(SPINDLE_LASER_PWM_INVERT, 255, 0) - -/** - * Init the cutter to a safe OFF state - */ -void SpindleLaser::init() { - #if ENABLED(SPINDLE_SERVO) - servo[SPINDLE_SERVO_NR].move(SPINDLE_SERVO_MIN); - #else - OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init spindle to off - #endif - #if ENABLED(SPINDLE_CHANGE_DIR) - OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR); // Init rotation to clockwise (M3) - #endif - #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY - frequency = SPINDLE_LASER_FREQUENCY; - hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY); - #endif - #if ENABLED(SPINDLE_LASER_USE_PWM) - SET_PWM(SPINDLE_LASER_PWM_PIN); - hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed - #endif - #if ENABLED(AIR_EVACUATION) - OUT_WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); // Init Vacuum/Blower OFF - #endif - #if ENABLED(AIR_ASSIST) - OUT_WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); // Init Air Assist OFF - #endif - TERN_(I2C_AMMETER, ammeter.init()); // Init I2C Ammeter -} - -#if ENABLED(SPINDLE_LASER_USE_PWM) - /** - * Set the cutter PWM directly to the given ocr value - * - * @param ocr Power value - */ - void SpindleLaser::_set_ocr(const uint8_t ocr) { - #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY - hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); - #endif - hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF); - } - - void SpindleLaser::set_ocr(const uint8_t ocr) { - WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON - _set_ocr(ocr); - } - - void SpindleLaser::ocr_off() { - WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF - _set_ocr(0); - } -#endif // SPINDLE_LASER_USE_PWM - -/** - * Apply power for Laser or Spindle - * - * Apply cutter power value for PWM, Servo, and on/off pin. - * - * @param opwr Power value. Range 0 to MAX. - */ -void SpindleLaser::apply_power(const uint8_t opwr) { - if (enabled() || opwr == 0) { // 0 check allows us to disable where no ENA pin exists - // Test and set the last power used to improve performance - if (opwr == last_power_applied) return; - last_power_applied = opwr; - // Handle PWM driven or just simple on/off - #if ENABLED(SPINDLE_LASER_USE_PWM) - if (CUTTER_UNIT_IS(RPM) && unitPower == 0) - ocr_off(); - else if (ENABLED(CUTTER_POWER_RELATIVE) || enabled() || opwr == 0) { - set_ocr(opwr); - isReadyForUI = true; - } - else - ocr_off(); - #elif ENABLED(SPINDLE_SERVO) - MOVE_SERVO(SPINDLE_SERVO_NR, power); - #else - WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE); - isReadyForUI = true; - #endif - } - else { - #if PIN_EXISTS(SPINDLE_LASER_ENA) - WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); - #endif - isReadyForUI = false; // Only used for UI display updates. - TERN_(SPINDLE_LASER_USE_PWM, ocr_off()); - } -} - -#if ENABLED(SPINDLE_CHANGE_DIR) - /** - * Set the spindle direction and apply immediately - * Stop on direction change if SPINDLE_STOP_ON_DIR_CHANGE is enabled - */ - void SpindleLaser::set_reverse(const bool reverse) { - const bool dir_state = (reverse == SPINDLE_INVERT_DIR); // Forward (M3) HIGH when not inverted - if (TERN0(SPINDLE_STOP_ON_DIR_CHANGE, enabled()) && READ(SPINDLE_DIR_PIN) != dir_state) disable(); - WRITE(SPINDLE_DIR_PIN, dir_state); - } -#endif - -#if ENABLED(AIR_EVACUATION) - // Enable / disable Cutter Vacuum or Laser Blower motor - void SpindleLaser::air_evac_enable() { WRITE(AIR_EVACUATION_PIN, AIR_EVACUATION_ACTIVE); } // Turn ON - void SpindleLaser::air_evac_disable() { WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); } // Turn OFF - void SpindleLaser::air_evac_toggle() { TOGGLE(AIR_EVACUATION_PIN); } // Toggle state -#endif - -#if ENABLED(AIR_ASSIST) - // Enable / disable air assist - void SpindleLaser::air_assist_enable() { WRITE(AIR_ASSIST_PIN, AIR_ASSIST_ACTIVE); } // Turn ON - void SpindleLaser::air_assist_disable() { WRITE(AIR_ASSIST_PIN, !AIR_ASSIST_ACTIVE); } // Turn OFF - void SpindleLaser::air_assist_toggle() { TOGGLE(AIR_ASSIST_PIN); } // Toggle state -#endif - -#endif // HAS_CUTTER diff --git a/src/feature/spindle_laser.h b/src/feature/spindle_laser.h deleted file mode 100644 index c4923a0..0000000 --- a/src/feature/spindle_laser.h +++ /dev/null @@ -1,329 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/spindle_laser.h - * Support for Laser Power or Spindle Power & Direction - */ - -#include "../inc/MarlinConfig.h" - -#include "spindle_laser_types.h" - -#if HAS_BEEPER - #include "../libs/buzzer.h" -#endif - -// Inline laser power -#include "../module/planner.h" - -#define PCT_TO_PWM(X) ((X) * 255 / 100) -#define PCT_TO_SERVO(X) ((X) * 180 / 100) - -// Laser/Cutter operation mode -enum CutterMode : int8_t { - CUTTER_MODE_ERROR = -1, - CUTTER_MODE_STANDARD, // M3 power is applied directly and waits for planner moves to sync. - CUTTER_MODE_CONTINUOUS, // M3 or G1/2/3 move power is controlled within planner blocks, set with 'M3 I', cleared with 'M5 I'. - CUTTER_MODE_DYNAMIC // M4 laser power is proportional to the feed rate, set with 'M4 I', cleared with 'M5 I'. -}; - -class SpindleLaser { -public: - static CutterMode cutter_mode; - - static constexpr uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); } - - // cpower = configured values (e.g., SPEED_POWER_MAX) - // Convert configured power range to a percentage - static constexpr cutter_cpower_t power_floor = TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0); - static constexpr uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) { - return cpwr ? round(100.0f * (cpwr - power_floor) / (SPEED_POWER_MAX - power_floor)) : 0; - } - - // Convert config defines from RPM to %, angle or PWM when in Spindle mode - // and convert from PERCENT to PWM when in Laser mode - static constexpr cutter_power_t cpwr_to_upwr(const cutter_cpower_t cpwr) { // STARTUP power to Unit power - return ( - #if ENABLED(SPINDLE_FEATURE) - // Spindle configured define values are in RPM - #if CUTTER_UNIT_IS(RPM) - cpwr // to same - #elif CUTTER_UNIT_IS(PERCENT) - cpwr_to_pct(cpwr) // to Percent - #elif CUTTER_UNIT_IS(SERVO) - PCT_TO_SERVO(cpwr_to_pct(cpwr)) // to SERVO angle - #else - PCT_TO_PWM(cpwr_to_pct(cpwr)) // to PWM - #endif - #else - // Laser configured define values are in Percent - #if CUTTER_UNIT_IS(PWM255) - PCT_TO_PWM(cpwr) // to PWM - #else - cpwr // to same - #endif - #endif - ); - } - - static constexpr cutter_power_t mpower_min() { return cpwr_to_upwr(SPEED_POWER_MIN); } - static constexpr cutter_power_t mpower_max() { return cpwr_to_upwr(SPEED_POWER_MAX); } - - #if ENABLED(LASER_FEATURE) - static cutter_test_pulse_t testPulse; // (ms) Test fire pulse duration - static uint8_t last_block_power; // Track power changes for dynamic power - - static feedRate_t feedrate_mm_m, last_feedrate_mm_m; // (mm/min) Track feedrate changes for dynamic power - static bool laser_feedrate_changed() { - const bool changed = last_feedrate_mm_m != feedrate_mm_m; - if (changed) last_feedrate_mm_m = feedrate_mm_m; - return changed; - } - #endif - - static bool isReadyForUI; // Ready to apply power setting from the UI to OCR - static bool enable_state; - static uint8_t power, - last_power_applied; // Basic power state tracking - - static cutter_frequency_t frequency; // Set PWM frequency; range: 2K-50K - - static cutter_power_t menuPower, // Power as set via LCD menu in PWM, Percentage or RPM - unitPower; // Power as displayed status in PWM, Percentage or RPM - - static void init(); - - #if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY - static void refresh_frequency() { hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); } - #endif - - // Modifying this function should update everywhere - static bool enabled(const cutter_power_t opwr) { return opwr > 0; } - static bool enabled() { return enable_state; } - - static void apply_power(const uint8_t inpow); - - FORCE_INLINE static void refresh() { apply_power(power); } - - #if ENABLED(SPINDLE_LASER_USE_PWM) - - private: - - static void _set_ocr(const uint8_t ocr); - - public: - - static void set_ocr(const uint8_t ocr); - static void ocr_off(); - - /** - * Update output for power->OCR translation - */ - static uint8_t upower_to_ocr(const cutter_power_t upwr) { - return uint8_t( - #if CUTTER_UNIT_IS(PWM255) - upwr - #elif CUTTER_UNIT_IS(PERCENT) - pct_to_ocr(upwr) - #else - pct_to_ocr(cpwr_to_pct(upwr)) - #endif - ); - } - - #endif // SPINDLE_LASER_USE_PWM - - /** - * Correct power to configured range - */ - static cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit=_CUTTER_POWER(CUTTER_POWER_UNIT)) { - static constexpr float - min_pct = TERN(CUTTER_POWER_RELATIVE, 0, TERN(SPINDLE_FEATURE, round(100.0f * (SPEED_POWER_MIN) / (SPEED_POWER_MAX)), SPEED_POWER_MIN)), - max_pct = TERN(SPINDLE_FEATURE, 100, SPEED_POWER_MAX); - if (pwr <= 0) return 0; - cutter_power_t upwr; - switch (pwrUnit) { - case _CUTTER_POWER_PWM255: { // PWM - const uint8_t pmin = pct_to_ocr(min_pct), pmax = pct_to_ocr(max_pct); - upwr = cutter_power_t(constrain(pwr, pmin, pmax)); - } break; - case _CUTTER_POWER_PERCENT: // Percent - upwr = cutter_power_t(constrain(pwr, min_pct, max_pct)); - break; - case _CUTTER_POWER_RPM: // Calculate OCR value - upwr = cutter_power_t(constrain(pwr, SPEED_POWER_MIN, SPEED_POWER_MAX)); - break; - default: break; - } - return upwr; - } - - /** - * Enable Laser or Spindle output. - * It's important to prevent changing the power output value during inline cutter operation. - * Inline power is adjusted in the planner to support LASER_TRAP_POWER and CUTTER_MODE_DYNAMIC mode. - * - * This method accepts one of the following control states: - * - * - For CUTTER_MODE_STANDARD the cutter power is either full on/off or ocr-based and it will apply - * SPEED_POWER_STARTUP if no value is assigned. - * - * - For CUTTER_MODE_CONTINUOUS inline and power remains where last set and the cutter output enable flag is set. - * - * - CUTTER_MODE_DYNAMIC is also inline-based and it just sets the enable output flag. - * - * - For CUTTER_MODE_ERROR set the output enable_state flag directly and set power to 0 for any mode. - * This mode allows a global power shutdown action to occur. - */ - static void set_enabled(const bool enable) { - switch (cutter_mode) { - case CUTTER_MODE_STANDARD: - apply_power(enable ? TERN(SPINDLE_LASER_USE_PWM, (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)), 255) : 0); - break; - case CUTTER_MODE_CONTINUOUS: - TERN_(LASER_FEATURE, set_inline_enabled(enable)); - break; - case CUTTER_MODE_DYNAMIC: - TERN_(LASER_FEATURE, set_inline_enabled(enable)); - break; - case CUTTER_MODE_ERROR: // Error mode, no enable and kill power. - enable_state = false; - apply_power(0); - } - #if SPINDLE_LASER_ENA_PIN - WRITE(SPINDLE_LASER_ENA_PIN, enable ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE); - #endif - enable_state = enable; - } - - static void disable() { isReadyForUI = false; set_enabled(false); } - - // Wait for spindle/laser to startup or shutdown - static void power_delay(const bool on) { - safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY); - } - - #if ENABLED(SPINDLE_CHANGE_DIR) - static void set_reverse(const bool reverse); - static bool is_reverse() { return READ(SPINDLE_DIR_PIN) == SPINDLE_INVERT_DIR; } - #else - static void set_reverse(const bool) {} - static bool is_reverse() { return false; } - #endif - - #if ENABLED(AIR_EVACUATION) - static void air_evac_enable(); // Turn On Cutter Vacuum or Laser Blower motor - static void air_evac_disable(); // Turn Off Cutter Vacuum or Laser Blower motor - static void air_evac_toggle(); // Toggle Cutter Vacuum or Laser Blower motor - static bool air_evac_state() { // Get current state - return (READ(AIR_EVACUATION_PIN) == AIR_EVACUATION_ACTIVE); - } - #endif - - #if ENABLED(AIR_ASSIST) - static void air_assist_enable(); // Turn on air assist - static void air_assist_disable(); // Turn off air assist - static void air_assist_toggle(); // Toggle air assist - static bool air_assist_state() { // Get current state - return (READ(AIR_ASSIST_PIN) == AIR_ASSIST_ACTIVE); - } - #endif - - #if HAS_MARLINUI_MENU - - #if ENABLED(SPINDLE_FEATURE) - static void enable_with_dir(const bool reverse) { - isReadyForUI = true; - const uint8_t ocr = TERN(SPINDLE_LASER_USE_PWM, upower_to_ocr(menuPower), 255); - if (menuPower) - power = ocr; - else - menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP); - unitPower = menuPower; - set_reverse(reverse); - set_enabled(true); - } - FORCE_INLINE static void enable_forward() { enable_with_dir(false); } - FORCE_INLINE static void enable_reverse() { enable_with_dir(true); } - FORCE_INLINE static void enable_same_dir() { enable_with_dir(is_reverse()); } - #endif // SPINDLE_FEATURE - - #if ENABLED(SPINDLE_LASER_USE_PWM) - static void update_from_mpower() { - if (isReadyForUI) power = upower_to_ocr(menuPower); - unitPower = menuPower; - } - #endif - - #if ENABLED(LASER_FEATURE) - // Toggle the laser on/off with menuPower. Apply SPEED_POWER_STARTUP if it was 0 on entry. - static void laser_menu_toggle(const bool state) { - set_enabled(state); - if (state) { - if (!menuPower) menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP); - power = upower_to_ocr(menuPower); - apply_power(power); - } - } - - /** - * Test fire the laser using the testPulse ms duration - * Also fires with any PWM power that was previous set - * If not set defaults to 80% power - */ - static void test_fire_pulse() { - BUZZ(30, 3000); - cutter_mode = CUTTER_MODE_STANDARD;// Menu needs standard mode. - laser_menu_toggle(true); // Laser On - delay(testPulse); // Delay for time set by user in pulse ms menu screen. - laser_menu_toggle(false); // Laser Off - } - #endif // LASER_FEATURE - - #endif // HAS_MARLINUI_MENU - - #if ENABLED(LASER_FEATURE) - - // Dynamic mode rate calculation - static uint8_t calc_dynamic_power() { - if (feedrate_mm_m > 65535) return 255; // Too fast, go always on - uint16_t rate = uint16_t(feedrate_mm_m); // 16 bits from the G-code parser float input - rate >>= 8; // Take the G-code input e.g. F40000 and shift off the lower bits to get an OCR value from 1-255 - return uint8_t(rate); - } - - // Inline modes of all other functions; all enable planner inline power control - static void set_inline_enabled(const bool enable) { planner.laser_inline.status.isEnabled = enable;} - - // Set the power for subsequent movement blocks - static void inline_power(const cutter_power_t cpwr) { - TERN(SPINDLE_LASER_USE_PWM, power = planner.laser_inline.power = cpwr, planner.laser_inline.power = cpwr > 0 ? 255 : 0); - } - - #endif // LASER_FEATURE - - static void kill() { disable(); } -}; - -extern SpindleLaser cutter; diff --git a/src/feature/spindle_laser_types.h b/src/feature/spindle_laser_types.h deleted file mode 100644 index 2f36a68..0000000 --- a/src/feature/spindle_laser_types.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/spindle_laser_types.h - * Support for Laser Power or Spindle Power & Direction - */ - -#include "../inc/MarlinConfigPre.h" - -#define MSG_CUTTER(M) _MSG_CUTTER(M) - -#ifndef SPEED_POWER_INTERCEPT - #define SPEED_POWER_INTERCEPT 0 -#endif -#if ENABLED(SPINDLE_FEATURE) - #define _MSG_CUTTER(M) MSG_SPINDLE_##M - #ifndef SPEED_POWER_MIN - #define SPEED_POWER_MIN 5000 - #endif - #ifndef SPEED_POWER_MAX - #define SPEED_POWER_MAX 30000 - #endif - #ifndef SPEED_POWER_STARTUP - #define SPEED_POWER_STARTUP 25000 - #endif -#else - #define _MSG_CUTTER(M) MSG_LASER_##M - #ifndef SPEED_POWER_MIN - #define SPEED_POWER_MIN 0 - #endif - #ifndef SPEED_POWER_MAX - #define SPEED_POWER_MAX 255 - #endif - #ifndef SPEED_POWER_STARTUP - #define SPEED_POWER_STARTUP 255 - #endif -#endif - -typedef IF<(SPEED_POWER_MAX > 255), uint16_t, uint8_t>::type cutter_cpower_t; - -#if CUTTER_UNIT_IS(RPM) && SPEED_POWER_MAX > 255 - typedef uint16_t cutter_power_t; - #define CUTTER_MENU_POWER_TYPE uint16_5 - #define cutter_power2str ui16tostr5rj -#else - typedef uint8_t cutter_power_t; - #if CUTTER_UNIT_IS(PERCENT) - #define CUTTER_MENU_POWER_TYPE percent_3 - #define cutter_power2str pcttostrpctrj - #else - #define CUTTER_MENU_POWER_TYPE uint8 - #define cutter_power2str ui8tostr3rj - #endif -#endif - -typedef uint16_t cutter_frequency_t; - -#if ENABLED(LASER_FEATURE) - typedef uint16_t cutter_test_pulse_t; - #define CUTTER_MENU_PULSE_TYPE uint16_3 - #define CUTTER_MENU_FREQUENCY_TYPE uint16_5 -#endif diff --git a/src/feature/stepper_driver_safety.cpp b/src/feature/stepper_driver_safety.cpp deleted file mode 100644 index 11b9095..0000000 --- a/src/feature/stepper_driver_safety.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../inc/MarlinConfig.h" -#include "../lcd/marlinui.h" - -#if HAS_DRIVER_SAFE_POWER_PROTECT - -#include "stepper_driver_safety.h" - -static uint32_t axis_plug_backward = 0; - -void stepper_driver_backward_error(FSTR_P const fstr) { - SERIAL_ERROR_START(); - SERIAL_ECHOF(fstr); - SERIAL_ECHOLNPGM(" driver is backward!"); - ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD)); -} - -void stepper_driver_backward_check() { - - OUT_WRITE(SAFE_POWER_PIN, LOW); - - #define _TEST_BACKWARD(AXIS, BIT) do { \ - SET_INPUT(AXIS##_ENABLE_PIN); \ - OUT_WRITE(AXIS##_STEP_PIN, false); \ - delay(20); \ - if (READ(AXIS##_ENABLE_PIN) == false) { \ - SBI(axis_plug_backward, BIT); \ - stepper_driver_backward_error(F(STRINGIFY(AXIS))); \ - } \ - }while(0) - - #define TEST_BACKWARD(AXIS, BIT) TERN_(HAS_##AXIS##_ENABLE, _TEST_BACKWARD(AXIS, BIT)) - - TEST_BACKWARD(X, 0); - TEST_BACKWARD(X2, 1); - - TEST_BACKWARD(Y, 2); - TEST_BACKWARD(Y2, 3); - - TEST_BACKWARD(Z, 4); - TEST_BACKWARD(Z2, 5); - TEST_BACKWARD(Z3, 6); - TEST_BACKWARD(Z4, 7); - - TEST_BACKWARD(I, 8); - TEST_BACKWARD(J, 9); - TEST_BACKWARD(K, 10); - - TEST_BACKWARD(E0, 11); - TEST_BACKWARD(E1, 12); - TEST_BACKWARD(E2, 13); - TEST_BACKWARD(E3, 14); - TEST_BACKWARD(E4, 15); - TEST_BACKWARD(E5, 16); - TEST_BACKWARD(E6, 17); - TEST_BACKWARD(E7, 18); - - if (!axis_plug_backward) - WRITE(SAFE_POWER_PIN, HIGH); -} - -void stepper_driver_backward_report() { - if (!axis_plug_backward) return; - - auto _report_if_backward = [](FSTR_P const axis, uint8_t bit) { - if (TEST(axis_plug_backward, bit)) - stepper_driver_backward_error(axis); - }; - - #define REPORT_BACKWARD(axis, bit) TERN_(HAS_##axis##_ENABLE, _report_if_backward(F(STRINGIFY(axis)), bit)) - - REPORT_BACKWARD(X, 0); - REPORT_BACKWARD(X2, 1); - - REPORT_BACKWARD(Y, 2); - REPORT_BACKWARD(Y2, 3); - - REPORT_BACKWARD(Z, 4); - REPORT_BACKWARD(Z2, 5); - REPORT_BACKWARD(Z3, 6); - REPORT_BACKWARD(Z4, 7); - - REPORT_BACKWARD(I, 8); - REPORT_BACKWARD(J, 9); - REPORT_BACKWARD(K, 10); - - REPORT_BACKWARD(E0, 11); - REPORT_BACKWARD(E1, 12); - REPORT_BACKWARD(E2, 13); - REPORT_BACKWARD(E3, 14); - REPORT_BACKWARD(E4, 15); - REPORT_BACKWARD(E5, 16); - REPORT_BACKWARD(E6, 17); - REPORT_BACKWARD(E7, 18); -} - -#endif // HAS_DRIVER_SAFE_POWER_PROTECT diff --git a/src/feature/stepper_driver_safety.h b/src/feature/stepper_driver_safety.h deleted file mode 100644 index 46edf33..0000000 --- a/src/feature/stepper_driver_safety.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - - -#include "../inc/MarlinConfigPre.h" - -void stepper_driver_backward_check(); -void stepper_driver_backward_report(); diff --git a/src/feature/tmc_util.cpp b/src/feature/tmc_util.cpp deleted file mode 100644 index ef3fb3a..0000000 --- a/src/feature/tmc_util.cpp +++ /dev/null @@ -1,1336 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if HAS_TRINAMIC_CONFIG - -#include "tmc_util.h" -#include "../MarlinCore.h" - -#include "../module/stepper/indirection.h" -#include "../module/printcounter.h" -#include "../libs/duration_t.h" -#include "../gcode/gcode.h" - -#if ENABLED(TMC_DEBUG) - #include "../libs/hex_print.h" - #if ENABLED(MONITOR_DRIVER_STATUS) - static uint16_t report_tmc_status_interval; // = 0 - #endif -#endif - -/** - * Check for over temperature or short to ground error flags. - * Report and log warning of overtemperature condition. - * Reduce driver current in a persistent otpw condition. - * Keep track of otpw counter so we don't reduce current on a single instance, - * and so we don't repeatedly report warning before the condition is cleared. - */ -#if ENABLED(MONITOR_DRIVER_STATUS) - - struct TMC_driver_data { - uint32_t drv_status; - bool is_otpw:1, - is_ot:1, - is_s2g:1, - is_error:1 - #if ENABLED(TMC_DEBUG) - , is_stall:1 - , is_stealth:1 - , is_standstill:1 - #if HAS_STALLGUARD - , sg_result_reasonable:1 - #endif - #endif - ; - #if ENABLED(TMC_DEBUG) - #if HAS_TMCX1X0 || HAS_TMC220x - uint8_t cs_actual; - #endif - #if HAS_STALLGUARD - uint16_t sg_result; - #endif - #endif - }; - - #if HAS_TMCX1X0 - - #if ENABLED(TMC_DEBUG) - static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); } - #endif - - static TMC_driver_data get_driver_data(TMC2130Stepper &st) { - constexpr uint8_t OT_bp = 25, OTPW_bp = 26; - constexpr uint32_t S2G_bm = 0x18000000; - #if ENABLED(TMC_DEBUG) - constexpr uint16_t SG_RESULT_bm = 0x3FF; // 0:9 - constexpr uint8_t STEALTH_bp = 14; - constexpr uint32_t CS_ACTUAL_bm = 0x1F0000; // 16:20 - constexpr uint8_t STALL_GUARD_bp = 24; - constexpr uint8_t STST_bp = 31; - #endif - TMC_driver_data data; - const auto ds = data.drv_status = st.DRV_STATUS(); - #ifdef __AVR__ - - // 8-bit optimization saves up to 70 bytes of PROGMEM per axis - uint8_t spart; - #if ENABLED(TMC_DEBUG) - data.sg_result = ds & SG_RESULT_bm; - spart = ds >> 8; - data.is_stealth = TEST(spart, STEALTH_bp - 8); - spart = ds >> 16; - data.cs_actual = spart & (CS_ACTUAL_bm >> 16); - #endif - spart = ds >> 24; - data.is_ot = TEST(spart, OT_bp - 24); - data.is_otpw = TEST(spart, OTPW_bp - 24); - data.is_s2g = !!(spart & (S2G_bm >> 24)); - #if ENABLED(TMC_DEBUG) - data.is_stall = TEST(spart, STALL_GUARD_bp - 24); - data.is_standstill = TEST(spart, STST_bp - 24); - data.sg_result_reasonable = !data.is_standstill; // sg_result has no reasonable meaning while standstill - #endif - - #else // !__AVR__ - - data.is_ot = TEST(ds, OT_bp); - data.is_otpw = TEST(ds, OTPW_bp); - data.is_s2g = !!(ds & S2G_bm); - #if ENABLED(TMC_DEBUG) - constexpr uint8_t CS_ACTUAL_sb = 16; - data.sg_result = ds & SG_RESULT_bm; - data.is_stealth = TEST(ds, STEALTH_bp); - data.cs_actual = (ds & CS_ACTUAL_bm) >> CS_ACTUAL_sb; - data.is_stall = TEST(ds, STALL_GUARD_bp); - data.is_standstill = TEST(ds, STST_bp); - data.sg_result_reasonable = !data.is_standstill; // sg_result has no reasonable meaning while standstill - #endif - - #endif // !__AVR__ - - return data; - } - - #endif // HAS_TMCX1X0 - - #if HAS_TMC220x - - #if ENABLED(TMC_DEBUG) - static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); } - #endif - - static TMC_driver_data get_driver_data(TMC2208Stepper &st) { - constexpr uint8_t OTPW_bp = 0, OT_bp = 1; - constexpr uint8_t S2G_bm = 0b111100; // 2..5 - TMC_driver_data data; - const auto ds = data.drv_status = st.DRV_STATUS(); - data.is_otpw = TEST(ds, OTPW_bp); - data.is_ot = TEST(ds, OT_bp); - data.is_s2g = !!(ds & S2G_bm); - #if ENABLED(TMC_DEBUG) - constexpr uint32_t CS_ACTUAL_bm = 0x1F0000; // 16:20 - constexpr uint8_t STEALTH_bp = 30, STST_bp = 31; - #ifdef __AVR__ - // 8-bit optimization saves up to 12 bytes of PROGMEM per axis - uint8_t spart = ds >> 16; - data.cs_actual = spart & (CS_ACTUAL_bm >> 16); - spart = ds >> 24; - data.is_stealth = TEST(spart, STEALTH_bp - 24); - data.is_standstill = TEST(spart, STST_bp - 24); - #else - constexpr uint8_t CS_ACTUAL_sb = 16; - data.cs_actual = (ds & CS_ACTUAL_bm) >> CS_ACTUAL_sb; - data.is_stealth = TEST(ds, STEALTH_bp); - data.is_standstill = TEST(ds, STST_bp); - #endif - TERN_(HAS_STALLGUARD, data.sg_result_reasonable = false); - #endif - return data; - } - - #endif // TMC2208 || TMC2209 - - #if HAS_DRIVER(TMC2660) - - #if ENABLED(TMC_DEBUG) - static uint32_t get_pwm_scale(TMC2660Stepper) { return 0; } - #endif - - static TMC_driver_data get_driver_data(TMC2660Stepper &st) { - constexpr uint8_t OT_bp = 1, OTPW_bp = 2; - constexpr uint8_t S2G_bm = 0b11000; - TMC_driver_data data; - const auto ds = data.drv_status = st.DRVSTATUS(); - uint8_t spart = ds & 0xFF; - data.is_otpw = TEST(spart, OTPW_bp); - data.is_ot = TEST(spart, OT_bp); - data.is_s2g = !!(ds & S2G_bm); - #if ENABLED(TMC_DEBUG) - constexpr uint8_t STALL_GUARD_bp = 0; - constexpr uint8_t STST_bp = 7, SG_RESULT_sp = 10; - constexpr uint32_t SG_RESULT_bm = 0xFFC00; // 10:19 - data.is_stall = TEST(spart, STALL_GUARD_bp); - data.is_standstill = TEST(spart, STST_bp); - data.sg_result = (ds & SG_RESULT_bm) >> SG_RESULT_sp; - data.sg_result_reasonable = true; - #endif - return data; - } - - #endif // TMC2660 - - #if ENABLED(STOP_ON_ERROR) - void report_driver_error(const TMC_driver_data &data) { - SERIAL_ECHOPGM(" driver error detected: 0x"); - SERIAL_PRINTLN(data.drv_status, PrintBase::Hex); - if (data.is_ot) SERIAL_ECHOLNPGM("overtemperature"); - if (data.is_s2g) SERIAL_ECHOLNPGM("coil short circuit"); - TERN_(TMC_DEBUG, tmc_report_all()); - kill(F("Driver error")); - } - #endif - - template - void report_driver_otpw(TMC &st) { - char timestamp[14]; - duration_t elapsed = print_job_timer.duration(); - const bool has_days = (elapsed.value > 60*60*24L); - (void)elapsed.toDigital(timestamp, has_days); - SERIAL_EOL(); - SERIAL_ECHO(timestamp); - SERIAL_ECHOPGM(": "); - st.printLabel(); - SERIAL_ECHOLNPGM(" driver overtemperature warning! (", st.getMilliamps(), "mA)"); - } - - template - void report_polled_driver_data(TMC &st, const TMC_driver_data &data) { - const uint32_t pwm_scale = get_pwm_scale(st); - st.printLabel(); - SERIAL_CHAR(':'); SERIAL_ECHO(pwm_scale); - #if ENABLED(TMC_DEBUG) - #if HAS_TMCX1X0 || HAS_TMC220x - SERIAL_CHAR('/'); SERIAL_ECHO(data.cs_actual); - #endif - #if HAS_STALLGUARD - SERIAL_CHAR('/'); - if (data.sg_result_reasonable) - SERIAL_ECHO(data.sg_result); - else - SERIAL_CHAR('-'); - #endif - #endif - SERIAL_CHAR('|'); - if (st.error_count) SERIAL_CHAR('E'); // Error - if (data.is_ot) SERIAL_CHAR('O'); // Over-temperature - if (data.is_otpw) SERIAL_CHAR('W'); // over-temperature pre-Warning - #if ENABLED(TMC_DEBUG) - if (data.is_stall) SERIAL_CHAR('G'); // stallGuard - if (data.is_stealth) SERIAL_CHAR('T'); // stealthChop - if (data.is_standstill) SERIAL_CHAR('I'); // standstIll - #endif - if (st.flag_otpw) SERIAL_CHAR('F'); // otpw Flag - SERIAL_CHAR('|'); - if (st.otpw_count > 0) SERIAL_ECHO(st.otpw_count); - SERIAL_CHAR('\t'); - } - - #if CURRENT_STEP_DOWN > 0 - - template - void step_current_down(TMC &st) { - if (st.isEnabled()) { - const uint16_t I_rms = st.getMilliamps() - (CURRENT_STEP_DOWN); - if (I_rms > 50) { - st.rms_current(I_rms); - #if ENABLED(REPORT_CURRENT_CHANGE) - st.printLabel(); - SERIAL_ECHOLNPGM(" current decreased to ", I_rms); - #endif - } - } - } - - #else - - #define step_current_down(...) - - #endif - - template - bool monitor_tmc_driver(TMC &st, const bool need_update_error_counters, const bool need_debug_reporting) { - TMC_driver_data data = get_driver_data(st); - if (data.drv_status == 0xFFFFFFFF || data.drv_status == 0x0) return false; - - bool should_step_down = false; - - if (need_update_error_counters) { - if (data.is_ot | data.is_s2g) st.error_count++; - else if (st.error_count > 0) st.error_count--; - - #if ENABLED(STOP_ON_ERROR) - if (st.error_count >= 10) { - SERIAL_EOL(); - st.printLabel(); - report_driver_error(data); - } - #endif - - // Report if a warning was triggered - if (data.is_otpw && st.otpw_count == 0) - report_driver_otpw(st); - - #if CURRENT_STEP_DOWN > 0 - // Decrease current if is_otpw is true and driver is enabled and there's been more than 4 warnings - if (data.is_otpw && st.otpw_count > 4 && st.isEnabled()) - should_step_down = true; - #endif - - if (data.is_otpw) { - st.otpw_count++; - st.flag_otpw = true; - } - else if (st.otpw_count > 0) st.otpw_count = 0; - } - - #if ENABLED(TMC_DEBUG) - if (need_debug_reporting) report_polled_driver_data(st, data); - #endif - - return should_step_down; - } - - void monitor_tmc_drivers() { - const millis_t ms = millis(); - - // Poll TMC drivers at the configured interval - static millis_t next_poll = 0; - const bool need_update_error_counters = ELAPSED(ms, next_poll); - if (need_update_error_counters) next_poll = ms + MONITOR_DRIVER_STATUS_INTERVAL_MS; - - // Also poll at intervals for debugging - #if ENABLED(TMC_DEBUG) - static millis_t next_debug_reporting = 0; - const bool need_debug_reporting = report_tmc_status_interval && ELAPSED(ms, next_debug_reporting); - if (need_debug_reporting) next_debug_reporting = ms + report_tmc_status_interval; - #else - constexpr bool need_debug_reporting = false; - #endif - - if (need_update_error_counters || need_debug_reporting) { - - #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) - { - bool result = false; - #if AXIS_IS_TMC(X) - if (monitor_tmc_driver(stepperX, need_update_error_counters, need_debug_reporting)) result = true; - #endif - #if AXIS_IS_TMC(X2) - if (monitor_tmc_driver(stepperX2, need_update_error_counters, need_debug_reporting)) result = true; - #endif - if (result) { - #if AXIS_IS_TMC(X) - step_current_down(stepperX); - #endif - #if AXIS_IS_TMC(X2) - step_current_down(stepperX2); - #endif - } - } - #endif - - #if AXIS_IS_TMC(Y) || AXIS_IS_TMC(Y2) - { - bool result = false; - #if AXIS_IS_TMC(Y) - if (monitor_tmc_driver(stepperY, need_update_error_counters, need_debug_reporting)) result = true; - #endif - #if AXIS_IS_TMC(Y2) - if (monitor_tmc_driver(stepperY2, need_update_error_counters, need_debug_reporting)) result = true; - #endif - if (result) { - #if AXIS_IS_TMC(Y) - step_current_down(stepperY); - #endif - #if AXIS_IS_TMC(Y2) - step_current_down(stepperY2); - #endif - } - } - #endif - - #if AXIS_IS_TMC(Z) || AXIS_IS_TMC(Z2) || AXIS_IS_TMC(Z3) || AXIS_IS_TMC(Z4) - { - bool result = false; - #if AXIS_IS_TMC(Z) - if (monitor_tmc_driver(stepperZ, need_update_error_counters, need_debug_reporting)) result = true; - #endif - #if AXIS_IS_TMC(Z2) - if (monitor_tmc_driver(stepperZ2, need_update_error_counters, need_debug_reporting)) result = true; - #endif - #if AXIS_IS_TMC(Z3) - if (monitor_tmc_driver(stepperZ3, need_update_error_counters, need_debug_reporting)) result = true; - #endif - #if AXIS_IS_TMC(Z4) - if (monitor_tmc_driver(stepperZ4, need_update_error_counters, need_debug_reporting)) result = true; - #endif - if (result) { - #if AXIS_IS_TMC(Z) - step_current_down(stepperZ); - #endif - #if AXIS_IS_TMC(Z2) - step_current_down(stepperZ2); - #endif - #if AXIS_IS_TMC(Z3) - step_current_down(stepperZ3); - #endif - #if AXIS_IS_TMC(Z4) - step_current_down(stepperZ4); - #endif - } - } - #endif - - #if AXIS_IS_TMC(I) - if (monitor_tmc_driver(stepperI, need_update_error_counters, need_debug_reporting)) - step_current_down(stepperI); - #endif - #if AXIS_IS_TMC(J) - if (monitor_tmc_driver(stepperJ, need_update_error_counters, need_debug_reporting)) - step_current_down(stepperJ); - #endif - #if AXIS_IS_TMC(K) - if (monitor_tmc_driver(stepperK, need_update_error_counters, need_debug_reporting)) - step_current_down(stepperK); - #endif - - #if AXIS_IS_TMC(E0) - (void)monitor_tmc_driver(stepperE0, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E1) - (void)monitor_tmc_driver(stepperE1, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E2) - (void)monitor_tmc_driver(stepperE2, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E3) - (void)monitor_tmc_driver(stepperE3, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E4) - (void)monitor_tmc_driver(stepperE4, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E5) - (void)monitor_tmc_driver(stepperE5, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E6) - (void)monitor_tmc_driver(stepperE6, need_update_error_counters, need_debug_reporting); - #endif - #if AXIS_IS_TMC(E7) - (void)monitor_tmc_driver(stepperE7, need_update_error_counters, need_debug_reporting); - #endif - - if (TERN0(TMC_DEBUG, need_debug_reporting)) SERIAL_EOL(); - } - } - -#endif // MONITOR_DRIVER_STATUS - -#if ENABLED(TMC_DEBUG) - - /** - * M122 [S<0|1>] [Pnnn] Enable periodic status reports - */ - #if ENABLED(MONITOR_DRIVER_STATUS) - void tmc_set_report_interval(const uint16_t update_interval) { - if ((report_tmc_status_interval = update_interval)) - SERIAL_ECHOLNPGM("axis:pwm_scale" - TERN_(HAS_STEALTHCHOP, "/curr_scale") - TERN_(HAS_STALLGUARD, "/mech_load") - "|flags|warncount" - ); - } - #endif - - enum TMC_debug_enum : char { - TMC_CODES, - TMC_UART_ADDR, - TMC_ENABLED, - TMC_CURRENT, - TMC_RMS_CURRENT, - TMC_MAX_CURRENT, - TMC_IRUN, - TMC_IHOLD, - TMC_GLOBAL_SCALER, - TMC_CS_ACTUAL, - TMC_PWM_SCALE, - TMC_PWM_SCALE_SUM, - TMC_PWM_SCALE_AUTO, - TMC_PWM_OFS_AUTO, - TMC_PWM_GRAD_AUTO, - TMC_VSENSE, - TMC_STEALTHCHOP, - TMC_MICROSTEPS, - TMC_TSTEP, - TMC_TPWMTHRS, - TMC_TPWMTHRS_MMS, - TMC_OTPW, - TMC_OTPW_TRIGGERED, - TMC_TOFF, - TMC_TBL, - TMC_HEND, - TMC_HSTRT, - TMC_SGT, - TMC_MSCNT, - TMC_INTERPOLATE - }; - enum TMC_drv_status_enum : char { - TMC_DRV_CODES, - TMC_STST, - TMC_OLB, - TMC_OLA, - TMC_S2GB, - TMC_S2GA, - TMC_DRV_OTPW, - TMC_OT, - TMC_STALLGUARD, - TMC_DRV_CS_ACTUAL, - TMC_FSACTIVE, - TMC_SG_RESULT, - TMC_DRV_STATUS_HEX, - TMC_T157, - TMC_T150, - TMC_T143, - TMC_T120, - TMC_STEALTH, - TMC_S2VSB, - TMC_S2VSA - }; - enum TMC_get_registers_enum : char { - TMC_AXIS_CODES, - TMC_GET_GCONF, - TMC_GET_IHOLD_IRUN, - TMC_GET_GSTAT, - TMC_GET_IOIN, - TMC_GET_TPOWERDOWN, - TMC_GET_TSTEP, - TMC_GET_TPWMTHRS, - TMC_GET_TCOOLTHRS, - TMC_GET_THIGH, - TMC_GET_CHOPCONF, - TMC_GET_COOLCONF, - TMC_GET_PWMCONF, - TMC_GET_PWM_SCALE, - TMC_GET_DRV_STATUS, - TMC_GET_DRVCONF, - TMC_GET_DRVCTRL, - TMC_GET_DRVSTATUS, - TMC_GET_SGCSCONF, - TMC_GET_SMARTEN - }; - - template - static void print_vsense(TMC &st) { SERIAL_ECHOF(st.vsense() ? F("1=.18") : F("0=.325")); } - - #if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC5130) - static void _tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) { - switch (i) { - case TMC_PWM_SCALE: SERIAL_ECHO(st.PWM_SCALE()); break; - case TMC_SGT: SERIAL_ECHO(st.sgt()); break; - case TMC_STEALTHCHOP: serialprint_truefalse(st.en_pwm_mode()); break; - case TMC_INTERPOLATE: serialprint_truefalse(st.intpol()); break; - default: break; - } - } - #endif - #if HAS_TMCX1X0 - static void _tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) { - switch (i) { - case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break; - case TMC_SG_RESULT: SERIAL_ECHO(st.sg_result()); break; - case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('*'); break; - case TMC_DRV_CS_ACTUAL: SERIAL_ECHO(st.cs_actual()); break; - default: break; - } - } - #endif - - #if HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5160) - template - void print_vsense(TMCMarlin &) { } - - template - void print_vsense(TMCMarlin &) { } - - static void _tmc_status(TMC2160Stepper &st, const TMC_debug_enum i) { - switch (i) { - case TMC_PWM_SCALE: SERIAL_ECHO(st.PWM_SCALE()); break; - case TMC_SGT: SERIAL_ECHO(st.sgt()); break; - case TMC_STEALTHCHOP: serialprint_truefalse(st.en_pwm_mode()); break; - case TMC_GLOBAL_SCALER: - { - uint16_t value = st.GLOBAL_SCALER(); - SERIAL_ECHO(value ? value : 256); - SERIAL_ECHOPGM("/256"); - } - break; - case TMC_INTERPOLATE: serialprint_truefalse(st.intpol()); break; - default: break; - } - } - #endif - - #if HAS_TMC220x - static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) { - switch (i) { - case TMC_PWM_SCALE_SUM: SERIAL_ECHO(st.pwm_scale_sum()); break; - case TMC_PWM_SCALE_AUTO: SERIAL_ECHO(st.pwm_scale_auto()); break; - case TMC_PWM_OFS_AUTO: SERIAL_ECHO(st.pwm_ofs_auto()); break; - case TMC_PWM_GRAD_AUTO: SERIAL_ECHO(st.pwm_grad_auto()); break; - case TMC_STEALTHCHOP: serialprint_truefalse(st.stealth()); break; - case TMC_INTERPOLATE: serialprint_truefalse(st.intpol()); break; - default: break; - } - } - - #if HAS_DRIVER(TMC2209) - template - static void _tmc_status(TMCMarlin &st, const TMC_debug_enum i) { - switch (i) { - case TMC_SGT: SERIAL_ECHO(st.SGTHRS()); break; - case TMC_UART_ADDR: SERIAL_ECHO(st.get_address()); break; - default: - TMC2208Stepper *parent = &st; - _tmc_status(*parent, i); - break; - } - } - #endif - - static void _tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) { - switch (i) { - case TMC_T157: if (st.t157()) SERIAL_CHAR('*'); break; - case TMC_T150: if (st.t150()) SERIAL_CHAR('*'); break; - case TMC_T143: if (st.t143()) SERIAL_CHAR('*'); break; - case TMC_T120: if (st.t120()) SERIAL_CHAR('*'); break; - case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break; - case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break; - case TMC_DRV_CS_ACTUAL: SERIAL_ECHO(st.cs_actual()); break; - default: break; - } - } - - #if HAS_DRIVER(TMC2209) - static void _tmc_parse_drv_status(TMC2209Stepper &st, const TMC_drv_status_enum i) { - switch (i) { - case TMC_SG_RESULT: SERIAL_ECHO(st.SG_RESULT()); break; - default: _tmc_parse_drv_status(static_cast(st), i); break; - } - } - #endif - #endif - - #if HAS_DRIVER(TMC2660) - static void _tmc_parse_drv_status(TMC2660Stepper, const TMC_drv_status_enum) { } - static void _tmc_status(TMC2660Stepper &st, const TMC_debug_enum i) { - switch (i) { - case TMC_INTERPOLATE: serialprint_truefalse(st.intpol()); break; - default: break; - } - } - #endif - - template - static void tmc_status(TMC &st, const TMC_debug_enum i) { - SERIAL_CHAR('\t'); - switch (i) { - case TMC_CODES: st.printLabel(); break; - case TMC_ENABLED: serialprint_truefalse(st.isEnabled()); break; - case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break; - case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break; - case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current() * 1.41, 0); break; - case TMC_IRUN: - SERIAL_ECHO(st.irun()); - SERIAL_ECHOPGM("/31"); - break; - case TMC_IHOLD: - SERIAL_ECHO(st.ihold()); - SERIAL_ECHOPGM("/31"); - break; - case TMC_CS_ACTUAL: - SERIAL_ECHO(st.cs_actual()); - SERIAL_ECHOPGM("/31"); - break; - case TMC_VSENSE: print_vsense(st); break; - case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break; - case TMC_TSTEP: { - const uint32_t tstep_value = st.TSTEP(); - if (tstep_value != 0xFFFFF) SERIAL_ECHO(tstep_value); else SERIAL_ECHOPGM("max"); - } break; - #if ENABLED(HYBRID_THRESHOLD) - case TMC_TPWMTHRS: SERIAL_ECHO(uint32_t(st.TPWMTHRS())); break; - case TMC_TPWMTHRS_MMS: { - const uint32_t tpwmthrs_val = st.get_pwm_thrs(); - if (tpwmthrs_val) SERIAL_ECHO(tpwmthrs_val); else SERIAL_CHAR('-'); - } break; - #endif - case TMC_OTPW: serialprint_truefalse(st.otpw()); break; - #if ENABLED(MONITOR_DRIVER_STATUS) - case TMC_OTPW_TRIGGERED: serialprint_truefalse(st.getOTPW()); break; - #endif - case TMC_TOFF: SERIAL_ECHO(st.toff()); break; - case TMC_TBL: SERIAL_ECHO(st.blank_time()); break; - case TMC_HEND: SERIAL_ECHO(st.hysteresis_end()); break; - case TMC_HSTRT: SERIAL_ECHO(st.hysteresis_start()); break; - case TMC_MSCNT: SERIAL_ECHO(st.get_microstep_counter()); break; - default: _tmc_status(st, i); break; - } - } - - #if HAS_DRIVER(TMC2660) - template - void tmc_status(TMCMarlin &st, const TMC_debug_enum i) { - SERIAL_CHAR('\t'); - switch (i) { - case TMC_CODES: st.printLabel(); break; - case TMC_ENABLED: serialprint_truefalse(st.isEnabled()); break; - case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break; - case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break; - case TMC_MAX_CURRENT: SERIAL_PRINT((float)st.rms_current() * 1.41, 0); break; - case TMC_IRUN: - SERIAL_ECHO(st.cs()); - SERIAL_ECHOPGM("/31"); - break; - case TMC_VSENSE: SERIAL_ECHOF(st.vsense() ? F("1=.165") : F("0=.310")); break; - case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break; - //case TMC_OTPW: serialprint_truefalse(st.otpw()); break; - //case TMC_OTPW_TRIGGERED: serialprint_truefalse(st.getOTPW()); break; - case TMC_SGT: SERIAL_ECHO(st.sgt()); break; - case TMC_TOFF: SERIAL_ECHO(st.toff()); break; - case TMC_TBL: SERIAL_ECHO(st.blank_time()); break; - case TMC_HEND: SERIAL_ECHO(st.hysteresis_end()); break; - case TMC_HSTRT: SERIAL_ECHO(st.hysteresis_start()); break; - default: break; - } - } - #endif - - template - static void tmc_parse_drv_status(TMC &st, const TMC_drv_status_enum i) { - SERIAL_CHAR('\t'); - switch (i) { - case TMC_DRV_CODES: st.printLabel(); break; - case TMC_STST: if (!st.stst()) SERIAL_CHAR('*'); break; - case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break; - case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break; - case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break; - case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break; - case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('*'); break; - case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break; - case TMC_DRV_STATUS_HEX: { - const uint32_t drv_status = st.DRV_STATUS(); - SERIAL_CHAR('\t'); - st.printLabel(); - SERIAL_CHAR('\t'); - print_hex_long(drv_status, ':'); - if (drv_status == 0xFFFFFFFF || drv_status == 0) SERIAL_ECHOPGM("\t Bad response!"); - SERIAL_EOL(); - break; - } - default: _tmc_parse_drv_status(st, i); break; - } - } - - static void tmc_debug_loop(const TMC_debug_enum n, LOGICAL_AXIS_ARGS(const bool)) { - if (x) { - #if AXIS_IS_TMC(X) - tmc_status(stepperX, n); - #endif - #if AXIS_IS_TMC(X2) - tmc_status(stepperX2, n); - #endif - } - - if (TERN0(HAS_Y_AXIS, y)) { - #if AXIS_IS_TMC(Y) - tmc_status(stepperY, n); - #endif - #if AXIS_IS_TMC(Y2) - tmc_status(stepperY2, n); - #endif - } - - if (TERN0(HAS_Z_AXIS, z)) { - #if AXIS_IS_TMC(Z) - tmc_status(stepperZ, n); - #endif - #if AXIS_IS_TMC(Z2) - tmc_status(stepperZ2, n); - #endif - #if AXIS_IS_TMC(Z3) - tmc_status(stepperZ3, n); - #endif - #if AXIS_IS_TMC(Z4) - tmc_status(stepperZ4, n); - #endif - } - - #if AXIS_IS_TMC(I) - if (i) tmc_status(stepperI, n); - #endif - #if AXIS_IS_TMC(J) - if (j) tmc_status(stepperJ, n); - #endif - #if AXIS_IS_TMC(K) - if (k) tmc_status(stepperK, n); - #endif - - if (TERN0(HAS_EXTRUDERS, e)) { - #if AXIS_IS_TMC(E0) - tmc_status(stepperE0, n); - #endif - #if AXIS_IS_TMC(E1) - tmc_status(stepperE1, n); - #endif - #if AXIS_IS_TMC(E2) - tmc_status(stepperE2, n); - #endif - #if AXIS_IS_TMC(E3) - tmc_status(stepperE3, n); - #endif - #if AXIS_IS_TMC(E4) - tmc_status(stepperE4, n); - #endif - #if AXIS_IS_TMC(E5) - tmc_status(stepperE5, n); - #endif - #if AXIS_IS_TMC(E6) - tmc_status(stepperE6, n); - #endif - #if AXIS_IS_TMC(E7) - tmc_status(stepperE7, n); - #endif - } - - SERIAL_EOL(); - } - - static void drv_status_loop(const TMC_drv_status_enum n, LOGICAL_AXIS_ARGS(const bool)) { - if (x) { - #if AXIS_IS_TMC(X) - tmc_parse_drv_status(stepperX, n); - #endif - #if AXIS_IS_TMC(X2) - tmc_parse_drv_status(stepperX2, n); - #endif - } - - if (TERN0(HAS_Y_AXIS, y)) { - #if AXIS_IS_TMC(Y) - tmc_parse_drv_status(stepperY, n); - #endif - #if AXIS_IS_TMC(Y2) - tmc_parse_drv_status(stepperY2, n); - #endif - } - - if (TERN0(HAS_Z_AXIS, z)) { - #if AXIS_IS_TMC(Z) - tmc_parse_drv_status(stepperZ, n); - #endif - #if AXIS_IS_TMC(Z2) - tmc_parse_drv_status(stepperZ2, n); - #endif - #if AXIS_IS_TMC(Z3) - tmc_parse_drv_status(stepperZ3, n); - #endif - #if AXIS_IS_TMC(Z4) - tmc_parse_drv_status(stepperZ4, n); - #endif - } - - #if AXIS_IS_TMC(I) - if (i) tmc_parse_drv_status(stepperI, n); - #endif - #if AXIS_IS_TMC(J) - if (j) tmc_parse_drv_status(stepperJ, n); - #endif - #if AXIS_IS_TMC(K) - if (k) tmc_parse_drv_status(stepperK, n); - #endif - - if (TERN0(HAS_EXTRUDERS, e)) { - #if AXIS_IS_TMC(E0) - tmc_parse_drv_status(stepperE0, n); - #endif - #if AXIS_IS_TMC(E1) - tmc_parse_drv_status(stepperE1, n); - #endif - #if AXIS_IS_TMC(E2) - tmc_parse_drv_status(stepperE2, n); - #endif - #if AXIS_IS_TMC(E3) - tmc_parse_drv_status(stepperE3, n); - #endif - #if AXIS_IS_TMC(E4) - tmc_parse_drv_status(stepperE4, n); - #endif - #if AXIS_IS_TMC(E5) - tmc_parse_drv_status(stepperE5, n); - #endif - #if AXIS_IS_TMC(E6) - tmc_parse_drv_status(stepperE6, n); - #endif - #if AXIS_IS_TMC(E7) - tmc_parse_drv_status(stepperE7, n); - #endif - } - - SERIAL_EOL(); - } - - /** - * M122 report functions - */ - - void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) { - #define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) - #define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) - - TMC_REPORT("\t", TMC_CODES); - #if HAS_DRIVER(TMC2209) - TMC_REPORT("Address\t", TMC_UART_ADDR); - #endif - TMC_REPORT("Enabled\t", TMC_ENABLED); - TMC_REPORT("Set current", TMC_CURRENT); - TMC_REPORT("RMS current", TMC_RMS_CURRENT); - TMC_REPORT("MAX current", TMC_MAX_CURRENT); - TMC_REPORT("Run current", TMC_IRUN); - TMC_REPORT("Hold current", TMC_IHOLD); - #if HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5160) - TMC_REPORT("Global scaler", TMC_GLOBAL_SCALER); - #endif - TMC_REPORT("CS actual", TMC_CS_ACTUAL); - TMC_REPORT("PWM scale", TMC_PWM_SCALE); - #if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2224) || HAS_DRIVER(TMC2660) || HAS_TMC220x - TMC_REPORT("vsense\t", TMC_VSENSE); - #endif - TMC_REPORT("stealthChop", TMC_STEALTHCHOP); - TMC_REPORT("msteps\t", TMC_MICROSTEPS); - TMC_REPORT("interp\t", TMC_INTERPOLATE); - TMC_REPORT("tstep\t", TMC_TSTEP); - TMC_REPORT("PWM thresh.", TMC_TPWMTHRS); - TMC_REPORT("[mm/s]\t", TMC_TPWMTHRS_MMS); - TMC_REPORT("OT prewarn", TMC_OTPW); - #if ENABLED(MONITOR_DRIVER_STATUS) - TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED); - #endif - - #if HAS_TMC220x - TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); - TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); - TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); - TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); - #endif - - TMC_REPORT("off time", TMC_TOFF); - TMC_REPORT("blank time", TMC_TBL); - TMC_REPORT("hysteresis\n -end\t", TMC_HEND); - TMC_REPORT(" -start\t", TMC_HSTRT); - TMC_REPORT("Stallguard thrs", TMC_SGT); - TMC_REPORT("uStep count", TMC_MSCNT); - DRV_REPORT("DRVSTATUS", TMC_DRV_CODES); - #if HAS_TMCX1X0 || HAS_TMC220x - DRV_REPORT("sg_result", TMC_SG_RESULT); - #endif - #if HAS_TMCX1X0 - DRV_REPORT("stallguard", TMC_STALLGUARD); - DRV_REPORT("fsactive", TMC_FSACTIVE); - #endif - DRV_REPORT("stst\t", TMC_STST); - DRV_REPORT("olb\t", TMC_OLB); - DRV_REPORT("ola\t", TMC_OLA); - DRV_REPORT("s2gb\t", TMC_S2GB); - DRV_REPORT("s2ga\t", TMC_S2GA); - DRV_REPORT("otpw\t", TMC_DRV_OTPW); - DRV_REPORT("ot\t", TMC_OT); - #if HAS_TMC220x - DRV_REPORT("157C\t", TMC_T157); - DRV_REPORT("150C\t", TMC_T150); - DRV_REPORT("143C\t", TMC_T143); - DRV_REPORT("120C\t", TMC_T120); - DRV_REPORT("s2vsa\t", TMC_S2VSA); - DRV_REPORT("s2vsb\t", TMC_S2VSB); - #endif - DRV_REPORT("Driver registers:\n",TMC_DRV_STATUS_HEX); - SERIAL_EOL(); - } - - #define PRINT_TMC_REGISTER(REG_CASE) case TMC_GET_##REG_CASE: print_hex_long(st.REG_CASE(), ':'); break - - #if HAS_TMCX1X0 - static void tmc_get_ic_registers(TMC2130Stepper &st, const TMC_get_registers_enum i) { - switch (i) { - PRINT_TMC_REGISTER(TCOOLTHRS); - PRINT_TMC_REGISTER(THIGH); - PRINT_TMC_REGISTER(COOLCONF); - default: SERIAL_CHAR('\t'); break; - } - } - #endif - #if HAS_TMC220x - static void tmc_get_ic_registers(TMC2208Stepper, const TMC_get_registers_enum) { SERIAL_CHAR('\t'); } - #endif - - #if HAS_TRINAMIC_CONFIG - template - static void tmc_get_registers(TMC &st, const TMC_get_registers_enum i) { - switch (i) { - case TMC_AXIS_CODES: SERIAL_CHAR('\t'); st.printLabel(); break; - PRINT_TMC_REGISTER(GCONF); - PRINT_TMC_REGISTER(IHOLD_IRUN); - PRINT_TMC_REGISTER(GSTAT); - PRINT_TMC_REGISTER(IOIN); - PRINT_TMC_REGISTER(TPOWERDOWN); - PRINT_TMC_REGISTER(TSTEP); - PRINT_TMC_REGISTER(TPWMTHRS); - PRINT_TMC_REGISTER(CHOPCONF); - PRINT_TMC_REGISTER(PWMCONF); - PRINT_TMC_REGISTER(PWM_SCALE); - PRINT_TMC_REGISTER(DRV_STATUS); - default: tmc_get_ic_registers(st, i); break; - } - SERIAL_CHAR('\t'); - } - #endif - #if HAS_DRIVER(TMC2660) - template - static void tmc_get_registers(TMCMarlin &st, const TMC_get_registers_enum i) { - switch (i) { - case TMC_AXIS_CODES: SERIAL_CHAR('\t'); st.printLabel(); break; - PRINT_TMC_REGISTER(DRVCONF); - PRINT_TMC_REGISTER(DRVCTRL); - PRINT_TMC_REGISTER(CHOPCONF); - PRINT_TMC_REGISTER(DRVSTATUS); - PRINT_TMC_REGISTER(SGCSCONF); - PRINT_TMC_REGISTER(SMARTEN); - default: SERIAL_CHAR('\t'); break; - } - SERIAL_CHAR('\t'); - } - #endif - - static void tmc_get_registers(TMC_get_registers_enum n, LOGICAL_AXIS_ARGS(const bool)) { - if (x) { - #if AXIS_IS_TMC(X) - tmc_get_registers(stepperX, n); - #endif - #if AXIS_IS_TMC(X2) - tmc_get_registers(stepperX2, n); - #endif - } - - if (TERN0(HAS_Y_AXIS, y)) { - #if AXIS_IS_TMC(Y) - tmc_get_registers(stepperY, n); - #endif - #if AXIS_IS_TMC(Y2) - tmc_get_registers(stepperY2, n); - #endif - } - - if (TERN0(HAS_Z_AXIS, z)) { - #if AXIS_IS_TMC(Z) - tmc_get_registers(stepperZ, n); - #endif - #if AXIS_IS_TMC(Z2) - tmc_get_registers(stepperZ2, n); - #endif - #if AXIS_IS_TMC(Z3) - tmc_get_registers(stepperZ3, n); - #endif - #if AXIS_IS_TMC(Z4) - tmc_get_registers(stepperZ4, n); - #endif - } - - #if AXIS_IS_TMC(I) - if (i) tmc_get_registers(stepperI, n); - #endif - #if AXIS_IS_TMC(J) - if (j) tmc_get_registers(stepperJ, n); - #endif - #if AXIS_IS_TMC(K) - if (k) tmc_get_registers(stepperK, n); - #endif - - if (TERN0(HAS_EXTRUDERS, e)) { - #if AXIS_IS_TMC(E0) - tmc_get_registers(stepperE0, n); - #endif - #if AXIS_IS_TMC(E1) - tmc_get_registers(stepperE1, n); - #endif - #if AXIS_IS_TMC(E2) - tmc_get_registers(stepperE2, n); - #endif - #if AXIS_IS_TMC(E3) - tmc_get_registers(stepperE3, n); - #endif - #if AXIS_IS_TMC(E4) - tmc_get_registers(stepperE4, n); - #endif - #if AXIS_IS_TMC(E5) - tmc_get_registers(stepperE5, n); - #endif - #if AXIS_IS_TMC(E6) - tmc_get_registers(stepperE6, n); - #endif - #if AXIS_IS_TMC(E7) - tmc_get_registers(stepperE7, n); - #endif - } - - SERIAL_EOL(); - } - - void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) { - #define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, LOGICAL_AXIS_ARGS()); }while(0) - #define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME) - _TMC_GET_REG("\t", TMC_AXIS_CODES); - TMC_GET_REG(GCONF, "\t\t"); - TMC_GET_REG(IHOLD_IRUN, "\t"); - TMC_GET_REG(GSTAT, "\t\t"); - TMC_GET_REG(IOIN, "\t\t"); - TMC_GET_REG(TPOWERDOWN, "\t"); - TMC_GET_REG(TSTEP, "\t\t"); - TMC_GET_REG(TPWMTHRS, "\t"); - TMC_GET_REG(TCOOLTHRS, "\t"); - TMC_GET_REG(THIGH, "\t\t"); - TMC_GET_REG(CHOPCONF, "\t"); - TMC_GET_REG(COOLCONF, "\t"); - TMC_GET_REG(PWMCONF, "\t"); - TMC_GET_REG(PWM_SCALE, "\t"); - TMC_GET_REG(DRV_STATUS, "\t"); - } - -#endif // TMC_DEBUG - -#if USE_SENSORLESS - - bool tmc_enable_stallguard(TMC2130Stepper &st) { - const bool stealthchop_was_enabled = st.en_pwm_mode(); - - st.TCOOLTHRS(0xFFFFF); - st.en_pwm_mode(false); - st.diag1_stall(true); - - return stealthchop_was_enabled; - } - void tmc_disable_stallguard(TMC2130Stepper &st, const bool restore_stealth) { - st.TCOOLTHRS(0); - st.en_pwm_mode(restore_stealth); - st.diag1_stall(false); - } - - bool tmc_enable_stallguard(TMC2209Stepper &st) { - const bool stealthchop_was_enabled = !st.en_spreadCycle(); - - st.TCOOLTHRS(0xFFFFF); - st.en_spreadCycle(false); - return stealthchop_was_enabled; - } - void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth) { - st.en_spreadCycle(!restore_stealth); - st.TCOOLTHRS(0); - } - - bool tmc_enable_stallguard(TMC2660Stepper) { - // TODO - return false; - } - void tmc_disable_stallguard(TMC2660Stepper, const bool) {}; - -#endif // USE_SENSORLESS - -template -static bool test_connection(TMC &st) { - SERIAL_ECHOPGM("Testing "); - st.printLabel(); - SERIAL_ECHOPGM(" connection... "); - const uint8_t test_result = st.test_connection(); - - if (test_result > 0) SERIAL_ECHOPGM("Error: All "); - - FSTR_P stat; - switch (test_result) { - default: - case 0: stat = F("OK"); break; - case 1: stat = F("HIGH"); break; - case 2: stat = F("LOW"); break; - } - SERIAL_ECHOLNF(stat); - - return test_result; -} - -void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) { - uint8_t axis_connection = 0; - - if (x) { - #if AXIS_IS_TMC(X) - axis_connection += test_connection(stepperX); - #endif - #if AXIS_IS_TMC(X2) - axis_connection += test_connection(stepperX2); - #endif - } - - if (TERN0(HAS_Y_AXIS, y)) { - #if AXIS_IS_TMC(Y) - axis_connection += test_connection(stepperY); - #endif - #if AXIS_IS_TMC(Y2) - axis_connection += test_connection(stepperY2); - #endif - } - - if (TERN0(HAS_Z_AXIS, z)) { - #if AXIS_IS_TMC(Z) - axis_connection += test_connection(stepperZ); - #endif - #if AXIS_IS_TMC(Z2) - axis_connection += test_connection(stepperZ2); - #endif - #if AXIS_IS_TMC(Z3) - axis_connection += test_connection(stepperZ3); - #endif - #if AXIS_IS_TMC(Z4) - axis_connection += test_connection(stepperZ4); - #endif - } - - #if AXIS_IS_TMC(I) - if (i) axis_connection += test_connection(stepperI); - #endif - #if AXIS_IS_TMC(J) - if (j) axis_connection += test_connection(stepperJ); - #endif - #if AXIS_IS_TMC(K) - if (k) axis_connection += test_connection(stepperK); - #endif - - if (TERN0(HAS_EXTRUDERS, e)) { - #if AXIS_IS_TMC(E0) - axis_connection += test_connection(stepperE0); - #endif - #if AXIS_IS_TMC(E1) - axis_connection += test_connection(stepperE1); - #endif - #if AXIS_IS_TMC(E2) - axis_connection += test_connection(stepperE2); - #endif - #if AXIS_IS_TMC(E3) - axis_connection += test_connection(stepperE3); - #endif - #if AXIS_IS_TMC(E4) - axis_connection += test_connection(stepperE4); - #endif - #if AXIS_IS_TMC(E5) - axis_connection += test_connection(stepperE5); - #endif - #if AXIS_IS_TMC(E6) - axis_connection += test_connection(stepperE6); - #endif - #if AXIS_IS_TMC(E7) - axis_connection += test_connection(stepperE7); - #endif - } - - if (axis_connection) LCD_MESSAGE(MSG_ERROR_TMC); -} - -#endif // HAS_TRINAMIC_CONFIG - -#if HAS_TMC_SPI - #define SET_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH) - void tmc_init_cs_pins() { - #if AXIS_HAS_SPI(X) - SET_CS_PIN(X); - #endif - #if AXIS_HAS_SPI(Y) - SET_CS_PIN(Y); - #endif - #if AXIS_HAS_SPI(Z) - SET_CS_PIN(Z); - #endif - #if AXIS_HAS_SPI(X2) - SET_CS_PIN(X2); - #endif - #if AXIS_HAS_SPI(Y2) - SET_CS_PIN(Y2); - #endif - #if AXIS_HAS_SPI(Z2) - SET_CS_PIN(Z2); - #endif - #if AXIS_HAS_SPI(Z3) - SET_CS_PIN(Z3); - #endif - #if AXIS_HAS_SPI(Z4) - SET_CS_PIN(Z4); - #endif - #if AXIS_HAS_SPI(I) - SET_CS_PIN(I); - #endif - #if AXIS_HAS_SPI(J) - SET_CS_PIN(J); - #endif - #if AXIS_HAS_SPI(K) - SET_CS_PIN(K); - #endif - #if AXIS_HAS_SPI(E0) - SET_CS_PIN(E0); - #endif - #if AXIS_HAS_SPI(E1) - SET_CS_PIN(E1); - #endif - #if AXIS_HAS_SPI(E2) - SET_CS_PIN(E2); - #endif - #if AXIS_HAS_SPI(E3) - SET_CS_PIN(E3); - #endif - #if AXIS_HAS_SPI(E4) - SET_CS_PIN(E4); - #endif - #if AXIS_HAS_SPI(E5) - SET_CS_PIN(E5); - #endif - #if AXIS_HAS_SPI(E6) - SET_CS_PIN(E6); - #endif - #if AXIS_HAS_SPI(E7) - SET_CS_PIN(E7); - #endif - } -#endif // HAS_TMC_SPI diff --git a/src/feature/tmc_util.h b/src/feature/tmc_util.h deleted file mode 100644 index c10bab6..0000000 --- a/src/feature/tmc_util.h +++ /dev/null @@ -1,389 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" -#include "../lcd/marlinui.h" - -#if HAS_TRINAMIC_CONFIG - -#include -#include "../module/planner.h" - -#define CHOPPER_DEFAULT_12V { 3, -1, 1 } -#define CHOPPER_DEFAULT_19V { 4, 1, 1 } -#define CHOPPER_DEFAULT_24V { 4, 2, 1 } -#define CHOPPER_DEFAULT_36V { 5, 2, 4 } -#define CHOPPER_PRUSAMK3_24V { 3, -2, 6 } -#define CHOPPER_MARLIN_119 { 5, 2, 3 } -#define CHOPPER_09STEP_24V { 3, -1, 5 } - -#if ENABLED(MONITOR_DRIVER_STATUS) && !defined(MONITOR_DRIVER_STATUS_INTERVAL_MS) - #define MONITOR_DRIVER_STATUS_INTERVAL_MS 500U -#endif - -constexpr uint16_t _tmc_thrs(const uint16_t msteps, const uint32_t thrs, const uint32_t spmm) { - return 12650000UL * msteps / (256 * thrs * spmm); -} - -typedef struct { - uint8_t toff; - int8_t hend; - uint8_t hstrt; -} chopper_timing_t; - -template -class TMCStorage { - protected: - // Only a child class has access to constructor => Don't create on its own! "Poor man's abstract class" - TMCStorage() {} - - public: - uint16_t val_mA = 0; - - #if ENABLED(MONITOR_DRIVER_STATUS) - uint8_t otpw_count = 0, - error_count = 0; - bool flag_otpw = false; - bool getOTPW() { return flag_otpw; } - void clear_otpw() { flag_otpw = 0; } - #endif - - uint16_t getMilliamps() { return val_mA; } - - void printLabel() { - SERIAL_CHAR(AXIS_LETTER); - if (DRIVER_ID > '0') SERIAL_CHAR(DRIVER_ID); - } - - struct { - OPTCODE(HAS_STEALTHCHOP, bool stealthChop_enabled = false) - OPTCODE(HYBRID_THRESHOLD, uint8_t hybrid_thrs = 0) - OPTCODE(USE_SENSORLESS, int16_t homing_thrs = 0) - } stored; -}; - -template -class TMCMarlin : public TMC, public TMCStorage { - public: - TMCMarlin(const uint16_t cs_pin, const float RS) : - TMC(cs_pin, RS) - {} - TMCMarlin(const uint16_t cs_pin, const float RS, const uint8_t axis_chain_index) : - TMC(cs_pin, RS, axis_chain_index) - {} - TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK) : - TMC(CS, RS, pinMOSI, pinMISO, pinSCK) - {} - TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK, const uint8_t axis_chain_index) : - TMC(CS, RS, pinMOSI, pinMISO, pinSCK, axis_chain_index) - {} - uint16_t rms_current() { return TMC::rms_current(); } - void rms_current(uint16_t mA) { - this->val_mA = mA; - TMC::rms_current(mA); - } - void rms_current(const uint16_t mA, const float mult) { - this->val_mA = mA; - TMC::rms_current(mA, mult); - } - uint16_t get_microstep_counter() { return TMC::MSCNT(); } - - #if HAS_STEALTHCHOP - bool get_stealthChop() { return this->en_pwm_mode(); } - bool get_stored_stealthChop() { return this->stored.stealthChop_enabled; } - void refresh_stepping_mode() { this->en_pwm_mode(this->stored.stealthChop_enabled); } - void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); } - bool toggle_stepping_mode() { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); } - #endif - - void set_chopper_times(const chopper_timing_t &ct) { - TMC::toff(ct.toff); - TMC::hysteresis_end(ct.hend); - TMC::hysteresis_start(ct.hstrt); - } - - #if ENABLED(HYBRID_THRESHOLD) - uint32_t get_pwm_thrs() { - return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]); - } - void set_pwm_thrs(const uint32_t thrs) { - TMC::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - TERN_(HAS_MARLINUI_MENU, this->stored.hybrid_thrs = thrs); - } - #endif - - #if USE_SENSORLESS - int16_t homing_threshold() { return TMC::sgt(); } - void homing_threshold(int16_t sgt_val) { - sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); - TMC::sgt(sgt_val); - TERN_(HAS_MARLINUI_MENU, this->stored.homing_thrs = sgt_val); - } - #if ENABLED(SPI_ENDSTOPS) - bool test_stall_status(); - #endif - #endif - - #if HAS_MARLINUI_MENU - void refresh_stepper_current() { rms_current(this->val_mA); } - - #if ENABLED(HYBRID_THRESHOLD) - void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); } - #endif - #if USE_SENSORLESS - void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } - #endif - #endif - - static constexpr int8_t sgt_min = -64, - sgt_max = 63; -}; - -template -class TMCMarlin : public TMC2208Stepper, public TMCStorage { - public: - TMCMarlin(Stream * SerialPort, const float RS, const uint8_t) : - TMC2208Stepper(SerialPort, RS) - {} - TMCMarlin(Stream * SerialPort, const float RS, uint8_t addr, const uint16_t mul_pin1, const uint16_t mul_pin2) : - TMC2208Stepper(SerialPort, RS, addr, mul_pin1, mul_pin2) - {} - TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t) : - TMC2208Stepper(RX, TX, RS) - {} - - uint16_t rms_current() { return TMC2208Stepper::rms_current(); } - void rms_current(const uint16_t mA) { - this->val_mA = mA; - TMC2208Stepper::rms_current(mA); - } - void rms_current(const uint16_t mA, const float mult) { - this->val_mA = mA; - TMC2208Stepper::rms_current(mA, mult); - } - uint16_t get_microstep_counter() { return TMC2208Stepper::MSCNT(); } - - #if HAS_STEALTHCHOP - bool get_stealthChop() { return !this->en_spreadCycle(); } - bool get_stored_stealthChop() { return this->stored.stealthChop_enabled; } - void refresh_stepping_mode() { this->en_spreadCycle(!this->stored.stealthChop_enabled); } - void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); } - bool toggle_stepping_mode() { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); } - #endif - - void set_chopper_times(const chopper_timing_t &ct) { - TMC2208Stepper::toff(ct.toff); - TMC2208Stepper::hysteresis_end(ct.hend); - TMC2208Stepper::hysteresis_start(ct.hstrt); - } - - #if ENABLED(HYBRID_THRESHOLD) - uint32_t get_pwm_thrs() { - return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]); - } - void set_pwm_thrs(const uint32_t thrs) { - TMC2208Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - TERN_(HAS_MARLINUI_MENU, this->stored.hybrid_thrs = thrs); - } - #endif - - #if HAS_MARLINUI_MENU - void refresh_stepper_current() { rms_current(this->val_mA); } - - #if ENABLED(HYBRID_THRESHOLD) - void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); } - #endif - #endif -}; - -template -class TMCMarlin : public TMC2209Stepper, public TMCStorage { - public: - TMCMarlin(Stream * SerialPort, const float RS, const uint8_t addr) : - TMC2209Stepper(SerialPort, RS, addr) - {} - TMCMarlin(const uint16_t RX, const uint16_t TX, const float RS, const uint8_t addr) : - TMC2209Stepper(RX, TX, RS, addr) - {} - uint8_t get_address() { return slave_address; } - uint16_t rms_current() { return TMC2209Stepper::rms_current(); } - void rms_current(const uint16_t mA) { - this->val_mA = mA; - TMC2209Stepper::rms_current(mA); - } - void rms_current(const uint16_t mA, const float mult) { - this->val_mA = mA; - TMC2209Stepper::rms_current(mA, mult); - } - uint16_t get_microstep_counter() { return TMC2209Stepper::MSCNT(); } - - #if HAS_STEALTHCHOP - bool get_stealthChop() { return !this->en_spreadCycle(); } - bool get_stored_stealthChop() { return this->stored.stealthChop_enabled; } - void refresh_stepping_mode() { this->en_spreadCycle(!this->stored.stealthChop_enabled); } - void set_stealthChop(const bool stch) { this->stored.stealthChop_enabled = stch; refresh_stepping_mode(); } - bool toggle_stepping_mode() { set_stealthChop(!this->stored.stealthChop_enabled); return get_stealthChop(); } - #endif - - void set_chopper_times(const chopper_timing_t &ct) { - TMC2209Stepper::toff(ct.toff); - TMC2209Stepper::hysteresis_end(ct.hend); - TMC2209Stepper::hysteresis_start(ct.hstrt); - } - - #if ENABLED(HYBRID_THRESHOLD) - uint32_t get_pwm_thrs() { - return _tmc_thrs(this->microsteps(), this->TPWMTHRS(), planner.settings.axis_steps_per_mm[AXIS_ID]); - } - void set_pwm_thrs(const uint32_t thrs) { - TMC2209Stepper::TPWMTHRS(_tmc_thrs(this->microsteps(), thrs, planner.settings.axis_steps_per_mm[AXIS_ID])); - TERN_(HAS_MARLINUI_MENU, this->stored.hybrid_thrs = thrs); - } - #endif - #if USE_SENSORLESS - int16_t homing_threshold() { return TMC2209Stepper::SGTHRS(); } - void homing_threshold(int16_t sgt_val) { - sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); - TMC2209Stepper::SGTHRS(sgt_val); - TERN_(HAS_MARLINUI_MENU, this->stored.homing_thrs = sgt_val); - } - #endif - - #if HAS_MARLINUI_MENU - void refresh_stepper_current() { rms_current(this->val_mA); } - - #if ENABLED(HYBRID_THRESHOLD) - void refresh_hybrid_thrs() { set_pwm_thrs(this->stored.hybrid_thrs); } - #endif - #if USE_SENSORLESS - void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } - #endif - #endif - - static constexpr uint8_t sgt_min = 0, - sgt_max = 255; -}; - -template -class TMCMarlin : public TMC2660Stepper, public TMCStorage { - public: - TMCMarlin(const uint16_t cs_pin, const float RS, const uint8_t) : - TMC2660Stepper(cs_pin, RS) - {} - TMCMarlin(const uint16_t CS, const float RS, const uint16_t pinMOSI, const uint16_t pinMISO, const uint16_t pinSCK, const uint8_t) : - TMC2660Stepper(CS, RS, pinMOSI, pinMISO, pinSCK) - {} - uint16_t rms_current() { return TMC2660Stepper::rms_current(); } - void rms_current(const uint16_t mA) { - this->val_mA = mA; - TMC2660Stepper::rms_current(mA); - } - uint16_t get_microstep_counter() { return TMC2660Stepper::mstep(); } - - void set_chopper_times(const chopper_timing_t &ct) { - TMC2660Stepper::toff(ct.toff); - TMC2660Stepper::hysteresis_end(ct.hend); - TMC2660Stepper::hysteresis_start(ct.hstrt); - } - - #if USE_SENSORLESS - int16_t homing_threshold() { return TMC2660Stepper::sgt(); } - void homing_threshold(int16_t sgt_val) { - sgt_val = (int16_t)constrain(sgt_val, sgt_min, sgt_max); - TMC2660Stepper::sgt(sgt_val); - TERN_(HAS_MARLINUI_MENU, this->stored.homing_thrs = sgt_val); - } - #endif - - #if HAS_MARLINUI_MENU - void refresh_stepper_current() { rms_current(this->val_mA); } - - #if USE_SENSORLESS - void refresh_homing_thrs() { homing_threshold(this->stored.homing_thrs); } - #endif - #endif - - static constexpr int8_t sgt_min = -64, - sgt_max = 63; -}; - -void monitor_tmc_drivers(); -void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true)); - -#if ENABLED(TMC_DEBUG) - #if ENABLED(MONITOR_DRIVER_STATUS) - void tmc_set_report_interval(const uint16_t update_interval); - #endif - void tmc_report_all(LOGICAL_AXIS_DECL(const bool, true)); - void tmc_get_registers(LOGICAL_AXIS_ARGS(const bool)); -#endif - -/** - * TMC2130-specific sensorless homing using stallGuard2. - * stallGuard2 only works when in spreadCycle mode. - * spreadCycle and stealthChop are mutually-exclusive. - * - * Defined here because of limitations with templates and headers. - */ -#if USE_SENSORLESS - - // Track enabled status of stealthChop and only re-enable where applicable - struct sensorless_t { bool NUM_AXIS_ARGS(), x2, y2, z2, z3, z4; }; - - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - extern millis_t sg_guard_period; - constexpr uint16_t default_sg_guard_duration = 400; - #endif - - bool tmc_enable_stallguard(TMC2130Stepper &st); - void tmc_disable_stallguard(TMC2130Stepper &st, const bool restore_stealth); - - bool tmc_enable_stallguard(TMC2209Stepper &st); - void tmc_disable_stallguard(TMC2209Stepper &st, const bool restore_stealth); - - bool tmc_enable_stallguard(TMC2660Stepper); - void tmc_disable_stallguard(TMC2660Stepper, const bool); - - #if ENABLED(SPI_ENDSTOPS) - - template - bool TMCMarlin::test_stall_status() { - this->switchCSpin(LOW); - - // read stallGuard flag from TMC library, will handle HW and SW SPI - TMC2130_n::DRV_STATUS_t drv_status{0}; - drv_status.sr = this->DRV_STATUS(); - - this->switchCSpin(HIGH); - - return drv_status.stallGuard; - } - #endif // SPI_ENDSTOPS - -#endif // USE_SENSORLESS - -#endif // HAS_TRINAMIC_CONFIG - -#if HAS_TMC_SPI - void tmc_init_cs_pins(); -#endif diff --git a/src/feature/tramming.cpp b/src/feature/tramming.cpp deleted file mode 100644 index d03f0cf..0000000 --- a/src/feature/tramming.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(ASSISTED_TRAMMING) - -#include "tramming.h" - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../core/debug_out.h" - -PGMSTR(point_name_1, TRAMMING_POINT_NAME_1); -PGMSTR(point_name_2, TRAMMING_POINT_NAME_2); -PGMSTR(point_name_3, TRAMMING_POINT_NAME_3); -#ifdef TRAMMING_POINT_NAME_4 - PGMSTR(point_name_4, TRAMMING_POINT_NAME_4); - #ifdef TRAMMING_POINT_NAME_5 - PGMSTR(point_name_5, TRAMMING_POINT_NAME_5); - #ifdef TRAMMING_POINT_NAME_6 - PGMSTR(point_name_6, TRAMMING_POINT_NAME_6); - #endif - #endif -#endif - -PGM_P const tramming_point_name[] PROGMEM = { - point_name_1, point_name_2, point_name_3 - #ifdef TRAMMING_POINT_NAME_4 - , point_name_4 - #ifdef TRAMMING_POINT_NAME_5 - , point_name_5 - #ifdef TRAMMING_POINT_NAME_6 - , point_name_6 - #endif - #endif - #endif -}; - -#ifdef ASSISTED_TRAMMING_WAIT_POSITION - - // Move to the defined wait position - void move_to_tramming_wait_pos() { - constexpr xyz_pos_t wait_pos = ASSISTED_TRAMMING_WAIT_POSITION; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Moving away"); - do_blocking_move_to(wait_pos, XY_PROBE_FEEDRATE_MM_S); - } - -#endif - -#endif // ASSISTED_TRAMMING diff --git a/src/feature/tramming.h b/src/feature/tramming.h deleted file mode 100644 index 925659e..0000000 --- a/src/feature/tramming.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfig.h" -#include "../module/probe.h" - -#if !WITHIN(TRAMMING_SCREW_THREAD, 30, 51) || TRAMMING_SCREW_THREAD % 10 > 1 - #error "TRAMMING_SCREW_THREAD must be equal to 30, 31, 40, 41, 50, or 51." -#endif - -constexpr xy_pos_t tramming_points[] = TRAMMING_POINT_XY; - -#define G35_PROBE_COUNT COUNT(tramming_points) -static_assert(WITHIN(G35_PROBE_COUNT, 3, 6), "TRAMMING_POINT_XY requires between 3 and 6 XY positions."); - -#define VALIDATE_TRAMMING_POINT(N) static_assert(N >= G35_PROBE_COUNT || Probe::build_time::can_reach(tramming_points[N]), \ - "TRAMMING_POINT_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.") -VALIDATE_TRAMMING_POINT(0); VALIDATE_TRAMMING_POINT(1); VALIDATE_TRAMMING_POINT(2); VALIDATE_TRAMMING_POINT(3); VALIDATE_TRAMMING_POINT(4); VALIDATE_TRAMMING_POINT(5); - -extern const char point_name_1[], point_name_2[], point_name_3[] - #ifdef TRAMMING_POINT_NAME_4 - , point_name_4[] - #ifdef TRAMMING_POINT_NAME_5 - , point_name_5[] - #ifdef TRAMMING_POINT_NAME_6 - , point_name_6[] - #endif - #endif - #endif -; - -#define _NR_TRAM_NAMES 2 -#ifdef TRAMMING_POINT_NAME_3 - #undef _NR_TRAM_NAMES - #define _NR_TRAM_NAMES 3 - #ifdef TRAMMING_POINT_NAME_4 - #undef _NR_TRAM_NAMES - #define _NR_TRAM_NAMES 4 - #ifdef TRAMMING_POINT_NAME_5 - #undef _NR_TRAM_NAMES - #define _NR_TRAM_NAMES 5 - #ifdef TRAMMING_POINT_NAME_6 - #undef _NR_TRAM_NAMES - #define _NR_TRAM_NAMES 6 - #endif - #endif - #endif -#endif -static_assert(_NR_TRAM_NAMES >= G35_PROBE_COUNT, "Define enough TRAMMING_POINT_NAME_s for all TRAMMING_POINT_XY entries."); -#undef _NR_TRAM_NAMES - -extern PGM_P const tramming_point_name[]; - -#ifdef ASSISTED_TRAMMING_WAIT_POSITION - void move_to_tramming_wait_pos(); -#else - inline void move_to_tramming_wait_pos() {} -#endif diff --git a/src/feature/twibus.cpp b/src/feature/twibus.cpp deleted file mode 100644 index 9aec6b0..0000000 --- a/src/feature/twibus.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../inc/MarlinConfig.h" - -#if ENABLED(EXPERIMENTAL_I2CBUS) - -#include "twibus.h" - -#include - -#include "../libs/hex_print.h" - -TWIBus i2c; - -TWIBus::TWIBus() { - #if I2C_SLAVE_ADDRESS == 0 - - #if PINS_EXIST(I2C_SCL, I2C_SDA) && DISABLED(SOFT_I2C_EEPROM) - Wire.setSDA(pin_t(I2C_SDA_PIN)); - Wire.setSCL(pin_t(I2C_SCL_PIN)); - #endif - - Wire.begin(); // No address joins the BUS as the master - - #else - - Wire.begin(I2C_SLAVE_ADDRESS); // Join the bus as a slave - - #endif - reset(); -} - -void TWIBus::reset() { - buffer_s = 0; - buffer[0] = 0x00; -} - -void TWIBus::address(const uint8_t adr) { - if (!WITHIN(adr, 8, 127)) - SERIAL_ECHO_MSG("Bad I2C address (8-127)"); - - addr = adr; - - debug(F("address"), adr); -} - -void TWIBus::addbyte(const char c) { - if (buffer_s >= COUNT(buffer)) return; - buffer[buffer_s++] = c; - debug(F("addbyte"), c); -} - -void TWIBus::addbytes(char src[], uint8_t bytes) { - debug(F("addbytes"), bytes); - while (bytes--) addbyte(*src++); -} - -void TWIBus::addstring(char str[]) { - debug(F("addstring"), str); - while (char c = *str++) addbyte(c); -} - -void TWIBus::send() { - debug(F("send"), addr); - - Wire.beginTransmission(I2C_ADDRESS(addr)); - Wire.write(buffer, buffer_s); - Wire.endTransmission(); - - reset(); -} - -// static -void TWIBus::echoprefix(uint8_t bytes, FSTR_P const pref, uint8_t adr) { - SERIAL_ECHO_START(); - SERIAL_ECHOF(pref); - SERIAL_ECHOPGM(": from:", adr, " bytes:", bytes, " data:"); -} - -// static -void TWIBus::echodata(uint8_t bytes, FSTR_P const pref, uint8_t adr, const uint8_t style/*=0*/) { - union TwoBytesToInt16 { uint8_t bytes[2]; int16_t integervalue; }; - TwoBytesToInt16 ConversionUnion; - - echoprefix(bytes, pref, adr); - - while (bytes-- && Wire.available()) { - int value = Wire.read(); - switch (style) { - - // Style 1, HEX DUMP - case 1: - SERIAL_CHAR(hex_nybble((value & 0xF0) >> 4)); - SERIAL_CHAR(hex_nybble(value & 0x0F)); - if (bytes) SERIAL_CHAR(' '); - break; - - // Style 2, signed two byte integer (int16) - case 2: - if (bytes == 1) - ConversionUnion.bytes[1] = (uint8_t)value; - else if (bytes == 0) { - ConversionUnion.bytes[0] = (uint8_t)value; - // Output value in base 10 (standard decimal) - SERIAL_ECHO(ConversionUnion.integervalue); - } - break; - - // Style 3, unsigned byte, base 10 (uint8) - case 3: - SERIAL_ECHO(value); - if (bytes) SERIAL_CHAR(' '); - break; - - // Default style (zero), raw serial output - default: - // This can cause issues with some serial consoles, Pronterface is an example where things go wrong - SERIAL_CHAR(value); - break; - } - } - - SERIAL_EOL(); -} - -void TWIBus::echobuffer(FSTR_P const prefix, uint8_t adr) { - echoprefix(buffer_s, prefix, adr); - LOOP_L_N(i, buffer_s) SERIAL_CHAR(buffer[i]); - SERIAL_EOL(); -} - -bool TWIBus::request(const uint8_t bytes) { - if (!addr) return false; - - debug(F("request"), bytes); - - // requestFrom() is a blocking function - if (Wire.requestFrom(I2C_ADDRESS(addr), bytes) == 0) { - debug(F("request fail"), I2C_ADDRESS(addr)); - return false; - } - - return true; -} - -void TWIBus::relay(const uint8_t bytes, const uint8_t style/*=0*/) { - debug(F("relay"), bytes); - - if (request(bytes)) - echodata(bytes, F("i2c-reply"), addr, style); -} - -uint8_t TWIBus::capture(char *dst, const uint8_t bytes) { - reset(); - uint8_t count = 0; - while (count < bytes && Wire.available()) - dst[count++] = Wire.read(); - - debug(F("capture"), count); - - return count; -} - -// static -void TWIBus::flush() { - while (Wire.available()) Wire.read(); -} - -#if I2C_SLAVE_ADDRESS > 0 - - void TWIBus::receive(uint8_t bytes) { - debug(F("receive"), bytes); - echodata(bytes, F("i2c-receive"), 0); - } - - void TWIBus::reply(char str[]/*=nullptr*/) { - debug(F("reply"), str); - - if (str) { - reset(); - addstring(str); - } - - Wire.write(buffer, buffer_s); - - reset(); - } - - 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 ENABLED(DEBUG_TWIBUS) - - // static - void TWIBus::prefix(FSTR_P const func) { - SERIAL_ECHOPGM("TWIBus::", func, ": "); - } - void TWIBus::debug(FSTR_P const func, uint32_t adr) { - if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(adr); } - } - void TWIBus::debug(FSTR_P const func, char c) { - if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(c); } - } - void TWIBus::debug(FSTR_P const func, char str[]) { - if (DEBUGGING(INFO)) { prefix(func); SERIAL_ECHOLN(str); } - } - -#endif - -#endif // EXPERIMENTAL_I2CBUS diff --git a/src/feature/twibus.h b/src/feature/twibus.h deleted file mode 100644 index 806e2a1..0000000 --- a/src/feature/twibus.h +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../core/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)(); - -/** - * For a light i2c protocol that runs on two boards running Marlin see: - * See https://github.com/MarlinFirmware/Marlin/issues/4776#issuecomment-246262879 - */ -#if I2C_SLAVE_ADDRESS > 0 - - void i2c_on_receive(int bytes); // Demo i2c onReceive handler - void i2c_on_request(); // Demo i2c onRequest handler - -#endif - -#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 - * - https://marlinfw.org/docs/gcode/M260.html - * - https://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. - */ - uint8_t 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, FSTR_P const 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 - * @param style Output format for the bytes, 0 = Raw byte [default], 1 = Hex characters, 2 = uint16_t - */ - static void echodata(uint8_t bytes, FSTR_P const prefix, uint8_t adr, const uint8_t style=0); - - /** - * @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(FSTR_P const 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. - * @style Output format for the bytes, 0 = raw byte [default], 1 = Hex characters, 2 = uint16_t - * - * @param bytes the number of bytes to request - */ - void relay(const uint8_t bytes, const uint8_t style=0); - - #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[]=nullptr); - inline void reply(const char str[]) { 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(FSTR_P const func); - static void debug(FSTR_P const func, uint32_t adr); - static void debug(FSTR_P const func, char c); - static void debug(FSTR_P const func, char adr[]); - #else - static void debug(FSTR_P const, uint32_t) {} - static void debug(FSTR_P const, char) {} - static void debug(FSTR_P const, char[]) {} - #endif - static void debug(FSTR_P const func, uint8_t v) { debug(func, (uint32_t)v); } -}; - -extern TWIBus i2c; diff --git a/src/feature/x_twist.cpp b/src/feature/x_twist.cpp deleted file mode 100644 index b5ad25c..0000000 --- a/src/feature/x_twist.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "../inc/MarlinConfig.h" - -#if ENABLED(X_AXIS_TWIST_COMPENSATION) - -#include "x_twist.h" -#include "../module/probe.h" - -XATC xatc; - -bool XATC::enabled; -float XATC::spacing, XATC::start; -xatc_array_t XATC::z_offset; // Initialized by settings.load() - -void XATC::reset() { - constexpr float xzo[] = XATC_Z_OFFSETS; - static_assert(COUNT(xzo) == XATC_MAX_POINTS, "XATC_Z_OFFSETS is the wrong size."); - COPY(z_offset, xzo); - start = probe.min_x(); - spacing = (probe.max_x() - start) / (XATC_MAX_POINTS - 1); - enabled = true; -} - -void XATC::print_points() { - SERIAL_ECHOLNPGM(" X-Twist Correction:"); - LOOP_L_N(x, XATC_MAX_POINTS) { - SERIAL_CHAR(' '); - if (!isnan(z_offset[x])) - serial_offset(z_offset[x]); - else - LOOP_L_N(i, 6) SERIAL_CHAR(i ? '=' : ' '); - } - SERIAL_EOL(); -} - -float lerp(const_float_t t, const_float_t a, const_float_t b) { return a + t * (b - a); } - -float XATC::compensation(const xy_pos_t &raw) { - if (!enabled) return 0; - if (NEAR_ZERO(spacing)) return 0; - float t = (raw.x - start) / spacing; - const int i = constrain(FLOOR(t), 0, XATC_MAX_POINTS - 2); - t -= i; - return lerp(t, z_offset[i], z_offset[i + 1]); -} - -#endif // X_AXIS_TWIST_COMPENSATION diff --git a/src/feature/x_twist.h b/src/feature/x_twist.h deleted file mode 100644 index 6a2ff27..0000000 --- a/src/feature/x_twist.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -#include "../inc/MarlinConfigPre.h" - -typedef float xatc_array_t[XATC_MAX_POINTS]; - -class XATC { - static bool enabled; -public: - static float spacing, start; - static xatc_array_t z_offset; - - static void reset(); - static void set_enabled(const bool ena) { enabled = ena; } - static float compensation(const xy_pos_t &raw); - static void print_points(); -}; - -extern XATC xatc; diff --git a/src/feature/z_stepper_align.cpp b/src/feature/z_stepper_align.cpp deleted file mode 100644 index 9dba21d..0000000 --- a/src/feature/z_stepper_align.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * feature/z_stepper_align.cpp - */ - -#include "../inc/MarlinConfigPre.h" - -#if ENABLED(Z_STEPPER_AUTO_ALIGN) - -#include "z_stepper_align.h" -#include "../module/probe.h" - -ZStepperAlign z_stepper_align; - -xy_pos_t ZStepperAlign::xy[NUM_Z_STEPPERS]; - -#if HAS_Z_STEPPER_ALIGN_STEPPER_XY - xy_pos_t ZStepperAlign::stepper_xy[NUM_Z_STEPPERS]; -#endif - -void ZStepperAlign::reset_to_default() { - #ifdef Z_STEPPER_ALIGN_XY - - constexpr xy_pos_t xy_init[] = Z_STEPPER_ALIGN_XY; - static_assert(COUNT(xy_init) == NUM_Z_STEPPERS, - "Z_STEPPER_ALIGN_XY requires " - #if NUM_Z_STEPPERS == 4 - "four {X,Y} entries (Z, Z2, Z3, and Z4)." - #elif NUM_Z_STEPPERS == 3 - "three {X,Y} entries (Z, Z2, and Z3)." - #else - "two {X,Y} entries (Z and Z2)." - #endif - ); - - #define VALIDATE_ALIGN_POINT(N) static_assert(N >= NUM_Z_STEPPERS || Probe::build_time::can_reach(xy_init[N]), \ - "Z_STEPPER_ALIGN_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.") - VALIDATE_ALIGN_POINT(0); VALIDATE_ALIGN_POINT(1); VALIDATE_ALIGN_POINT(2); VALIDATE_ALIGN_POINT(3); - - #else // !Z_STEPPER_ALIGN_XY - - const xy_pos_t xy_init[] = { - #if NUM_Z_STEPPERS >= 3 // First probe point... - #if !Z_STEPPERS_ORIENTATION - { probe.min_x(), probe.min_y() }, // SW - #elif Z_STEPPERS_ORIENTATION == 1 - { probe.min_x(), probe.max_y() }, // NW - #elif Z_STEPPERS_ORIENTATION == 2 - { probe.max_x(), probe.max_y() }, // NE - #elif Z_STEPPERS_ORIENTATION == 3 - { probe.max_x(), probe.min_y() }, // SE - #else - #error "Z_STEPPERS_ORIENTATION must be from 0 to 3 (first point SW, NW, NE, SE)." - #endif - #if NUM_Z_STEPPERS == 4 // 3 more points... - #if !Z_STEPPERS_ORIENTATION - { probe.min_x(), probe.max_y() }, { probe.max_x(), probe.max_y() }, { probe.max_x(), probe.min_y() } // SW - #elif Z_STEPPERS_ORIENTATION == 1 - { probe.max_x(), probe.max_y() }, { probe.max_x(), probe.min_y() }, { probe.min_x(), probe.min_y() } // NW - #elif Z_STEPPERS_ORIENTATION == 2 - { probe.max_x(), probe.min_y() }, { probe.min_x(), probe.min_y() }, { probe.min_x(), probe.max_y() } // NE - #elif Z_STEPPERS_ORIENTATION == 3 - { probe.min_x(), probe.min_y() }, { probe.min_x(), probe.max_y() }, { probe.max_x(), probe.max_y() } // SE - #endif - #elif !Z_STEPPERS_ORIENTATION // or 2 more points... - { probe.max_x(), probe.min_y() }, { X_CENTER, probe.max_y() } // SW - #elif Z_STEPPERS_ORIENTATION == 1 - { probe.min_x(), probe.min_y() }, { probe.max_x(), Y_CENTER } // NW - #elif Z_STEPPERS_ORIENTATION == 2 - { probe.min_x(), probe.max_y() }, { X_CENTER, probe.min_y() } // NE - #elif Z_STEPPERS_ORIENTATION == 3 - { probe.max_x(), probe.max_y() }, { probe.min_x(), Y_CENTER } // SE - #endif - #elif Z_STEPPERS_ORIENTATION - { X_CENTER, probe.min_y() }, { X_CENTER, probe.max_y() } - #else - { probe.min_x(), Y_CENTER }, { probe.max_x(), Y_CENTER } - #endif - }; - - #endif // !Z_STEPPER_ALIGN_XY - - COPY(xy, xy_init); - - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - constexpr xy_pos_t stepper_xy_init[] = Z_STEPPER_ALIGN_STEPPER_XY; - static_assert( - COUNT(stepper_xy_init) == NUM_Z_STEPPERS, - "Z_STEPPER_ALIGN_STEPPER_XY requires " - #if NUM_Z_STEPPERS == 4 - "four {X,Y} entries (Z, Z2, Z3, and Z4)." - #elif NUM_Z_STEPPERS == 3 - "three {X,Y} entries (Z, Z2, and Z3)." - #endif - ); - COPY(stepper_xy, stepper_xy_init); - #endif -} - -#endif // Z_STEPPER_AUTO_ALIGN diff --git a/src/feature/z_stepper_align.h b/src/feature/z_stepper_align.h deleted file mode 100644 index f3f9abb..0000000 --- a/src/feature/z_stepper_align.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#pragma once - -/** - * feature/z_stepper_align.h - */ - -#include "../inc/MarlinConfig.h" - -class ZStepperAlign { - public: - static xy_pos_t xy[NUM_Z_STEPPERS]; - - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - static xy_pos_t stepper_xy[NUM_Z_STEPPERS]; - #endif - - static void reset_to_default(); -}; - -extern ZStepperAlign z_stepper_align; diff --git a/src/gcode/bedlevel/G26.cpp b/src/gcode/bedlevel/G26.cpp deleted file mode 100644 index aa6e0c1..0000000 --- a/src/gcode/bedlevel/G26.cpp +++ /dev/null @@ -1,876 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * 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 behavior 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. - * - * I # Preset Heat the Nozzle and Bed based on a Material Preset (if material presets are defined). - * - * F # Filament Used to specify the diameter of the filament being used. If not specified - * 1.75mm filament is assumed. If you are not getting acceptable results by using the - * 'correct' numbers, you can scale this number up or down a little bit to change the amount - * 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.) During G26 retraction will use the length - * specified by this parameter (1mm by default). Recover will be 1.2x the retract distance. - * - * 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 - * un-drawn circle is still done. But the distance to the location for each circle has a - * random number of the specified size added to it. Specifying S50 will give an interesting - * deviation from the normal behavior 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. - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(G26_MESH_VALIDATION) - -#define G26_OK false -#define G26_ERR true - -#include "../../gcode/gcode.h" -#include "../../feature/bedlevel/bedlevel.h" - -#include "../../MarlinCore.h" -#include "../../module/planner.h" -#include "../../module/motion.h" -#include "../../module/tool_change.h" -#include "../../module/temperature.h" -#include "../../lcd/marlinui.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#endif - -#if ENABLED(UBL_HILBERT_CURVE) - #include "../../feature/bedlevel/hilbert_curve.h" -#endif - -#define EXTRUSION_MULTIPLIER 1.0 -#define PRIME_LENGTH 10.0 -#define OOZE_AMOUNT 0.3 - -#define INTERSECTION_CIRCLE_RADIUS 5 -#define CROSSHAIRS_SIZE 3 - -#ifndef G26_RETRACT_MULTIPLIER - #define G26_RETRACT_MULTIPLIER 1.0 // x 1mm -#endif - -#ifndef G26_XY_FEEDRATE - #define G26_XY_FEEDRATE (PLANNER_XY_FEEDRATE() / 3.0) -#endif - -#ifndef G26_XY_FEEDRATE_TRAVEL - #define G26_XY_FEEDRATE_TRAVEL (PLANNER_XY_FEEDRATE() / 1.5) -#endif - -#if CROSSHAIRS_SIZE >= INTERSECTION_CIRCLE_RADIUS - #error "CROSSHAIRS_SIZE must be less than INTERSECTION_CIRCLE_RADIUS." -#endif - -#define G26_OK false -#define G26_ERR true - -#if ENABLED(ARC_SUPPORT) - void plan_arc(const xyze_pos_t&, const ab_float_t&, const bool, const uint8_t); -#endif - -constexpr float g26_e_axis_feedrate = 0.025; - -static MeshFlags circle_flags; -float g26_random_deviation = 0.0; - -#if HAS_MARLINUI_MENU - - /** - * If the LCD is clicked, cancel, wait for release, return true - */ - bool user_canceled() { - if (!ui.button_pressed()) return false; // Return if the button isn't pressed - ui.set_status(GET_TEXT_F(MSG_G26_CANCELED), 99); - TERN_(HAS_MARLINUI_MENU, ui.quick_feedback()); - ui.wait_for_release(); - return true; - } - -#endif - -void move_to(const_float_t rx, const_float_t ry, const_float_t z, const_float_t e_delta) { - static float last_z = -999.99; - - const xy_pos_t dest = { rx, ry }; - - const bool has_xy_component = dest != current_position, // Check if X or Y is involved in the movement. - has_e_component = e_delta != 0.0; - - if (z != last_z) { - last_z = z; - destination.set(current_position.x, current_position.y, z, current_position.e); - const feedRate_t fr_mm_s = planner.settings.max_feedrate_mm_s[Z_AXIS] * 0.5f; // Use half of the Z_AXIS max feed rate - prepare_internal_move_to_destination(fr_mm_s); - } - - // If X or Y in combination with E is involved do a 'normal' move. - // If X or Y with no E is involved do a 'fast' move - // Otherwise retract/recover/hop. - destination = dest; - destination.e += e_delta; - const feedRate_t fr_mm_s = has_xy_component - ? (has_e_component ? feedRate_t(G26_XY_FEEDRATE) : feedRate_t(G26_XY_FEEDRATE_TRAVEL)) - : planner.settings.max_feedrate_mm_s[E_AXIS] * 0.666f; - prepare_internal_move_to_destination(fr_mm_s); -} - -void move_to(const xyz_pos_t &where, const_float_t de) { move_to(where.x, where.y, where.z, de); } - -typedef struct { - float extrusion_multiplier = EXTRUSION_MULTIPLIER, - retraction_multiplier = G26_RETRACT_MULTIPLIER, - layer_height = MESH_TEST_LAYER_HEIGHT, - prime_length = PRIME_LENGTH; - - celsius_t bed_temp = MESH_TEST_BED_TEMP, - hotend_temp = MESH_TEST_HOTEND_TEMP; - - float nozzle = MESH_TEST_NOZZLE_SIZE, - filament_diameter = DEFAULT_NOMINAL_FILAMENT_DIA, - ooze_amount; // 'O' ... OOZE_AMOUNT - - bool continue_with_closest, // 'C' - keep_heaters_on; // 'K' - - xy_pos_t xy_pos; // = { 0, 0 } - - int8_t prime_flag = 0; - - bool g26_retracted = false; // Track the retracted state during G26 so mismatched - // retracts/recovers don't result in a bad state. - - void retract_filament(const xyz_pos_t &where) { - if (!g26_retracted) { // Only retract if we are not already retracted! - g26_retracted = true; - move_to(where, -1.0f * retraction_multiplier); - } - } - - // TODO: Parameterize the Z lift with a define - void retract_lift_move(const xyz_pos_t &s) { - retract_filament(destination); - move_to(current_position.x, current_position.y, current_position.z + 0.5f, 0.0f); // Z lift to minimize scraping - move_to(s.x, s.y, s.z + 0.5f, 0.0f); // Get to the starting point with no extrusion while lifted - } - - void recover_filament(const xyz_pos_t &where) { - if (g26_retracted) { // Only un-retract if we are retracted. - move_to(where, 1.2f * 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 print_line_from_here_to_there(const xyz_pos_t &s, const xyz_pos_t &e) { - - // Distances to the start / end of the line - xy_float_t svec = current_position - s, evec = current_position - e; - - const float dist_start = HYPOT2(svec.x, svec.y), - dist_end = HYPOT2(evec.x, evec.y), - line_length = HYPOT(e.x - s.x, e.y - s.y); - - // 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 && (INTERSECTION_CIRCLE_RADIUS) < ABS(line_length)) - return print_line_from_here_to_there(e, s); - - // Decide whether to retract & lift - if (dist_start > 2.0) retract_lift_move(s); - - move_to(s, 0.0); // Get to the starting point with no extrusion / un-Z lift - - const float e_pos_delta = line_length * g26_e_axis_feedrate * extrusion_multiplier; - - recover_filament(destination); - move_to(e, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion - } - - void connect_neighbor_with_line(const xy_int8_t &p1, int8_t dx, int8_t dy) { - xy_int8_t p2; - p2.x = p1.x + dx; - p2.y = p1.y + dy; - - if (p2.x < 0 || p2.x >= (GRID_MAX_POINTS_X)) return; - if (p2.y < 0 || p2.y >= (GRID_MAX_POINTS_Y)) return; - - if (circle_flags.marked(p1.x, p1.y) && circle_flags.marked(p2.x, p2.y)) { - xyz_pos_t s, e; - s.x = bedlevel.get_mesh_x(p1.x) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; - e.x = bedlevel.get_mesh_x(p2.x) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dx; - s.y = bedlevel.get_mesh_y(p1.y) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dy; - e.y = bedlevel.get_mesh_y(p2.y) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)) * dy; - s.z = e.z = layer_height; - - #if HAS_ENDSTOPS - LIMIT(s.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - LIMIT(e.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - LIMIT(s.x, X_MIN_POS + 1, X_MAX_POS - 1); - LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1); - #endif - - if (position_is_reachable(s) && position_is_reachable(e)) - print_line_from_here_to_there(s, e); - } - } - - /** - * Turn on the bed and nozzle heat and - * wait for them to get up to temperature. - */ - bool turn_on_heaters() { - - SERIAL_ECHOLNPGM("Waiting for heatup."); - - #if HAS_HEATED_BED - - if (bed_temp > 25) { - #if HAS_WIRED_LCD - ui.set_status(GET_TEXT_F(MSG_G26_HEATING_BED), 99); - ui.quick_feedback(); - TERN_(HAS_MARLINUI_MENU, ui.capture()); - #endif - thermalManager.setTargetBed(bed_temp); - - // Wait for the temperature to stabilize - if (!thermalManager.wait_for_bed(true OPTARG(G26_CLICK_CAN_CANCEL, true))) - return G26_ERR; - } - - #else - - UNUSED(bed_temp); - - #endif // HAS_HEATED_BED - - // Start heating the active nozzle - #if HAS_WIRED_LCD - ui.set_status(GET_TEXT_F(MSG_G26_HEATING_NOZZLE), 99); - ui.quick_feedback(); - #endif - thermalManager.setTargetHotend(hotend_temp, active_extruder); - - // Wait for the temperature to stabilize - if (!thermalManager.wait_for_hotend(active_extruder, true OPTARG(G26_CLICK_CAN_CANCEL, true))) - return G26_ERR; - - #if HAS_WIRED_LCD - ui.reset_status(); - ui.quick_feedback(); - #endif - - return G26_OK; - } - - /** - * Prime the nozzle if needed. Return true on error. - */ - bool prime_nozzle() { - - const feedRate_t fr_slow_e = planner.settings.max_feedrate_mm_s[E_AXIS] / 15.0f; - #if HAS_MARLINUI_MENU && !HAS_TOUCH_BUTTONS // ui.button_pressed issue with touchscreen - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - float Total_Prime = 0.0; - #endif - - if (prime_flag == -1) { // The user wants to control how much filament gets purged - ui.capture(); - ui.set_status(GET_TEXT_F(MSG_G26_MANUAL_PRIME), 99); - ui.chirp(); - - destination = current_position; - - recover_filament(destination); // Make sure G26 doesn't think the filament is retracted(). - - while (!ui.button_pressed()) { - ui.chirp(); - destination.e += 0.25; - #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - Total_Prime += 0.25; - if (Total_Prime >= EXTRUDE_MAXLENGTH) { - ui.release(); - return G26_ERR; - } - #endif - prepare_internal_move_to_destination(fr_slow_e); - destination = current_position; - planner.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'. - } - - ui.wait_for_release(); - - ui.set_status(GET_TEXT_F(MSG_G26_PRIME_DONE), 99); - ui.quick_feedback(); - ui.release(); - } - else - #endif - { - #if HAS_WIRED_LCD - ui.set_status(GET_TEXT_F(MSG_G26_FIXED_LENGTH), 99); - ui.quick_feedback(); - #endif - destination = current_position; - destination.e += prime_length; - prepare_internal_move_to_destination(fr_slow_e); - destination.e -= prime_length; - retract_filament(destination); - } - - return G26_OK; - } - - /** - * Find the nearest point at which to print a circle - */ - mesh_index_pair find_closest_circle_to_print(const xy_pos_t &pos) { - - mesh_index_pair out_point; - out_point.pos = -1; - - #if ENABLED(UBL_HILBERT_CURVE) - - auto test_func = [](uint8_t i, uint8_t j, void *data) -> bool { - if (!circle_flags.marked(i, j)) { - mesh_index_pair *out_point = (mesh_index_pair*)data; - out_point->pos.set(i, j); // Save its data - return true; - } - return false; - }; - - hilbert_curve::search_from_closest(pos, test_func, &out_point); - - #else - - float closest = 99999.99; - - GRID_LOOP(i, j) { - if (!circle_flags.marked(i, j)) { - // We found a circle that needs to be printed - const xy_pos_t m = { bedlevel.get_mesh_x(i), bedlevel.get_mesh_y(j) }; - - // Get the distance to this intersection - float f = (pos - m).magnitude(); - - // It is possible that we are being called with the values - // to let us find the closest circle to the start position. - // But if this is not the case, add a small weighting to the - // distance calculation to help it choose a better place to continue. - f += (xy_pos - m).magnitude() / 15.0f; - - // Add the specified amount of Random Noise to our search - if (g26_random_deviation > 1.0) f += random(0.0, g26_random_deviation); - - if (f < closest) { - closest = f; // Found a closer un-printed location - out_point.pos.set(i, j); // Save its data - out_point.distance = closest; - } - } - } - - #endif - - circle_flags.mark(out_point); // Mark this location as done. - return out_point; - } - -} g26_helper_t; - -/** - * G26: Mesh Validation Pattern generation. - * - * Used to interactively edit the mesh by placing the - * nozzle in a problem area and doing a G29 P4 R command. - * - * Parameters: - * - * B Bed Temperature - * C Continue from the Closest mesh point - * D Disable leveling before starting - * F Filament diameter - * H Hotend Temperature - * K Keep heaters on when completed - * L Layer Height - * O Ooze extrusion length - * P Prime length - * Q Retraction multiplier - * R Repetitions (number of grid points) - * S Nozzle Size (diameter) in mm - * T Tool index to change to, if included - * U Random deviation (50 if no value given) - * X X position - * Y Y position - */ -void GcodeSuite::G26() { - SERIAL_ECHOLNPGM("G26 starting..."); - - // Don't allow Mesh Validation without homing first, - // or if the parameter parsing did not go OK, abort - if (homing_needed_error()) return; - - // Change the tool first, if specified - if (parser.seenval('T')) tool_change(parser.value_int()); - - g26_helper_t g26; - - g26.ooze_amount = parser.linearval('O', OOZE_AMOUNT); - g26.continue_with_closest = parser.boolval('C'); - g26.keep_heaters_on = parser.boolval('K'); - - // Accept 'I' if temperature presets are defined - #if HAS_PREHEAT - const uint8_t preset_index = parser.seenval('I') ? _MIN(parser.value_byte(), PREHEAT_COUNT - 1) + 1 : 0; - #endif - - #if HAS_HEATED_BED - - // Get a temperature from 'I' or 'B' - celsius_t bedtemp = 0; - - // Use the 'I' index if temperature presets are defined - #if HAS_PREHEAT - if (preset_index) bedtemp = ui.material_preset[preset_index - 1].bed_temp; - #endif - - // Look for 'B' Bed Temperature - if (parser.seenval('B')) bedtemp = parser.value_celsius(); - - if (bedtemp) { - if (!WITHIN(bedtemp, 40, BED_MAX_TARGET)) { - SERIAL_ECHOLNPGM("?Specified bed temperature not plausible (40-", BED_MAX_TARGET, "C)."); - return; - } - g26.bed_temp = bedtemp; - } - - #endif // HAS_HEATED_BED - - if (parser.seenval('L')) { - g26.layer_height = parser.value_linear_units(); - if (!WITHIN(g26.layer_height, 0.0, 2.0)) { - SERIAL_ECHOLNPGM("?Specified layer height not plausible."); - return; - } - } - - if (parser.seen('Q')) { - if (parser.has_value()) { - g26.retraction_multiplier = parser.value_float(); - if (!WITHIN(g26.retraction_multiplier, 0.05, 15.0)) { - SERIAL_ECHOLNPGM("?Specified Retraction Multiplier not plausible."); - return; - } - } - else { - SERIAL_ECHOLNPGM("?Retraction Multiplier must be specified."); - return; - } - } - - if (parser.seenval('S')) { - g26.nozzle = parser.value_float(); - if (!WITHIN(g26.nozzle, 0.1, 2.0)) { - SERIAL_ECHOLNPGM("?Specified nozzle size not plausible."); - return; - } - } - - if (parser.seen('P')) { - if (!parser.has_value()) { - #if HAS_MARLINUI_MENU - g26.prime_flag = -1; - #else - SERIAL_ECHOLNPGM("?Prime length must be specified when not using an LCD."); - return; - #endif - } - else { - g26.prime_flag++; - g26.prime_length = parser.value_linear_units(); - if (!WITHIN(g26.prime_length, 0.0, 25.0)) { - SERIAL_ECHOLNPGM("?Specified prime length not plausible."); - return; - } - } - } - - if (parser.seenval('F')) { - g26.filament_diameter = parser.value_linear_units(); - if (!WITHIN(g26.filament_diameter, 1.0, 4.0)) { - SERIAL_ECHOLNPGM("?Specified filament size not plausible."); - return; - } - } - 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 - - // Get a temperature from 'I' or 'H' - celsius_t noztemp = 0; - - // Accept 'I' if temperature presets are defined - #if HAS_PREHEAT - if (preset_index) noztemp = ui.material_preset[preset_index - 1].hotend_temp; - #endif - - // Look for 'H' Hotend Temperature - if (parser.seenval('H')) noztemp = parser.value_celsius(); - - // If any preset or temperature was specified - if (noztemp) { - if (!WITHIN(noztemp, 165, (HEATER_0_MAXTEMP) - (HOTEND_OVERSHOOT))) { - SERIAL_ECHOLNPGM("?Specified nozzle temperature not plausible."); - return; - } - g26.hotend_temp = noztemp; - } - - // 'U' to Randomize and optionally set circle deviation - if (parser.seen('U')) { - randomSeed(millis()); - // This setting will persist for the next G26 - g26_random_deviation = parser.has_value() ? parser.value_float() : 50.0; - } - - // Get repeat from 'R', otherwise do one full circuit - int16_t g26_repeats; - #if HAS_MARLINUI_MENU - g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); - #else - if (parser.seen('R')) - g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1; - else { - SERIAL_ECHOLNPGM("?(R)epeat must be specified when not using an LCD."); - return; - } - #endif - if (g26_repeats < 1) { - SERIAL_ECHOLNPGM("?(R)epeat value not plausible; must be at least 1."); - return; - } - - // Set a position with 'X' and/or 'Y'. Default: current_position - g26.xy_pos.set(parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position.x, - parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position.y); - if (!position_is_reachable(g26.xy_pos)) { - SERIAL_ECHOLNPGM("?Specified X,Y coordinate out of bounds."); - return; - } - - /** - * Wait until all parameters are verified before altering the state! - */ - set_bed_leveling_enabled(!parser.seen_test('D')); - - do_z_clearance(Z_CLEARANCE_BETWEEN_PROBES); - - #if DISABLED(NO_VOLUMETRICS) - bool volumetric_was_enabled = parser.volumetric_enabled; - parser.volumetric_enabled = false; - planner.calculate_volumetric_multipliers(); - #endif - - if (g26.turn_on_heaters() != G26_OK) goto LEAVE; - - current_position.e = 0.0; - sync_plan_position_e(); - - if (g26.prime_flag && g26.prime_nozzle() != G26_OK) goto LEAVE; - - /** - * Bed is preheated - * - * Nozzle is at temperature - * - * Filament is primed! - * - * It's "Show Time" !!! - */ - - circle_flags.reset(); - - // Move nozzle to the specified height for the first layer - destination = current_position; - destination.z = g26.layer_height; - move_to(destination, 0.0); - move_to(destination, g26.ooze_amount); - - TERN_(HAS_MARLINUI_MENU, ui.capture()); - - #if DISABLED(ARC_SUPPORT) - - /** - * Pre-generate radius offset values at 30 degree intervals to reduce CPU load. - */ - #define A_INT 30 - #define _ANGS (360 / A_INT) - #define A_CNT (_ANGS / 2) - #define _IND(A) ((A + _ANGS * 8) % _ANGS) - #define _COS(A) (trig_table[_IND(A) % A_CNT] * (_IND(A) >= A_CNT ? -1 : 1)) - #define _SIN(A) (-_COS((A + A_CNT / 2) % _ANGS)) - #if A_CNT & 1 - #error "A_CNT must be a positive value. Please change A_INT." - #endif - float trig_table[A_CNT]; - LOOP_L_N(i, A_CNT) - trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT)); - - #endif // !ARC_SUPPORT - - mesh_index_pair location; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location.pos, ExtUI::G26_START)); - do { - // Find the nearest confluence - location = g26.find_closest_circle_to_print(g26.continue_with_closest ? xy_pos_t(current_position) : g26.xy_pos); - - if (location.valid()) { - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location.pos, ExtUI::G26_POINT_START)); - const xy_pos_t circle = { bedlevel.get_mesh_x(location.pos.a), bedlevel.get_mesh_y(location.pos.b) }; - - // If this mesh location is outside the printable radius, skip it. - if (!position_is_reachable(circle)) continue; - - // Determine where to start and end the circle, - // which is always drawn counter-clockwise. - const xy_int8_t st = location; - const bool f = st.y == 0, - r = st.x >= (GRID_MAX_POINTS_X) - 1, - b = st.y >= (GRID_MAX_POINTS_Y) - 1; - - #if ENABLED(ARC_SUPPORT) - - #define ARC_LENGTH(quarters) (INTERSECTION_CIRCLE_RADIUS * M_PI * (quarters) / 2) - #define INTERSECTION_CIRCLE_DIAM ((INTERSECTION_CIRCLE_RADIUS) * 2) - - xy_float_t e = { circle.x + INTERSECTION_CIRCLE_RADIUS, circle.y }; - xyz_float_t s = e; - - // Figure out where to start and end the arc - we always print counterclockwise - float arc_length = ARC_LENGTH(4); - if (st.x == 0) { // left edge - if (!f) { s.x = circle.x; s.y -= INTERSECTION_CIRCLE_RADIUS; } - if (!b) { e.x = circle.x; e.y += INTERSECTION_CIRCLE_RADIUS; } - arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2); - } - else if (r) { // right edge - if (b) s.set(circle.x - (INTERSECTION_CIRCLE_RADIUS), circle.y); - else s.set(circle.x, circle.y + INTERSECTION_CIRCLE_RADIUS); - if (f) e.set(circle.x - (INTERSECTION_CIRCLE_RADIUS), circle.y); - else e.set(circle.x, circle.y - (INTERSECTION_CIRCLE_RADIUS)); - arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2); - } - else if (f) { - e.x -= INTERSECTION_CIRCLE_DIAM; - arc_length = ARC_LENGTH(2); - } - else if (b) { - s.x -= INTERSECTION_CIRCLE_DIAM; - arc_length = ARC_LENGTH(2); - } - - const ab_float_t arc_offset = circle - s; - const xy_float_t dist = current_position - s; // Distance from the start of the actual circle - const float dist_start = HYPOT2(dist.x, dist.y); - const xyze_pos_t endpoint = { - e.x, e.y, g26.layer_height, - current_position.e + (arc_length * g26_e_axis_feedrate * g26.extrusion_multiplier) - }; - - if (dist_start > 2.0) { - s.z = g26.layer_height + 0.5f; - g26.retract_lift_move(s); - } - - s.z = g26.layer_height; - move_to(s, 0.0); // Get to the starting point with no extrusion / un-Z lift - - g26.recover_filament(destination); - - { REMEMBER(fr, feedrate_mm_s, PLANNER_XY_FEEDRATE() * 0.1f); - plan_arc(endpoint, arc_offset, false, 0); // Draw a counter-clockwise arc - destination = current_position; - } - - if (TERN0(HAS_MARLINUI_MENU, user_canceled())) goto LEAVE; // Check if the user wants to stop the Mesh Validation - - #else // !ARC_SUPPORT - - int8_t start_ind = -2, end_ind = 9; // Assume a full circle (from 5:00 to 5:00) - if (st.x == 0) { // Left edge? Just right half. - start_ind = f ? 0 : -3; // 03:00 to 12:00 for front-left - end_ind = b ? 0 : 2; // 06:00 to 03:00 for back-left - } - else if (r) { // Right edge? Just left half. - start_ind = b ? 6 : 3; // 12:00 to 09:00 for front-right - end_ind = f ? 5 : 8; // 09:00 to 06:00 for back-right - } - else if (f) { // Front edge? Just back half. - start_ind = 0; // 03:00 - end_ind = 5; // 09:00 - } - else if (b) { // Back edge? Just front half. - start_ind = 6; // 09:00 - end_ind = 11; // 03:00 - } - - for (int8_t ind = start_ind; ind <= end_ind; ind++) { - - if (TERN0(HAS_MARLINUI_MENU, user_canceled())) goto LEAVE; // Check if the user wants to stop the Mesh Validation - - xyz_float_t p = { circle.x + _COS(ind ), circle.y + _SIN(ind ), g26.layer_height }, - q = { circle.x + _COS(ind + 1), circle.y + _SIN(ind + 1), g26.layer_height }; - - #if IS_KINEMATIC - // Check to make sure this segment is entirely on the bed, skip if not. - if (!position_is_reachable(p) || !position_is_reachable(q)) continue; - #elif HAS_ENDSTOPS - LIMIT(p.x, X_MIN_POS + 1, X_MAX_POS - 1); // Prevent hitting the endstops - LIMIT(p.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - LIMIT(q.x, X_MIN_POS + 1, X_MAX_POS - 1); - LIMIT(q.y, Y_MIN_POS + 1, Y_MAX_POS - 1); - #endif - - g26.print_line_from_here_to_there(p, q); - SERIAL_FLUSH(); // Prevent host M105 buffer overrun. - } - - #endif // !ARC_SUPPORT - - g26.connect_neighbor_with_line(location.pos, -1, 0); - g26.connect_neighbor_with_line(location.pos, 1, 0); - g26.connect_neighbor_with_line(location.pos, 0, -1); - g26.connect_neighbor_with_line(location.pos, 0, 1); - planner.synchronize(); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location.pos, ExtUI::G26_POINT_FINISH)); - if (TERN0(HAS_MARLINUI_MENU, user_canceled())) goto LEAVE; - } - - SERIAL_FLUSH(); // Prevent host M105 buffer overrun. - - } while (--g26_repeats && location.valid()); - - LEAVE: - ui.set_status(GET_TEXT_F(MSG_G26_LEAVING), -1); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(location, ExtUI::G26_FINISH)); - - g26.retract_filament(destination); - destination.z = Z_CLEARANCE_BETWEEN_PROBES; - move_to(destination, 0); // Raise the nozzle - - #if DISABLED(NO_VOLUMETRICS) - parser.volumetric_enabled = volumetric_was_enabled; - planner.calculate_volumetric_multipliers(); - #endif - - TERN_(HAS_MARLINUI_MENU, ui.release()); // Give back control of the LCD - - if (!g26.keep_heaters_on) { - TERN_(HAS_HEATED_BED, thermalManager.setTargetBed(0)); - thermalManager.setTargetHotend(active_extruder, 0); - } -} - -#endif // G26_MESH_VALIDATION diff --git a/src/gcode/bedlevel/G35.cpp b/src/gcode/bedlevel/G35.cpp deleted file mode 100644 index dd828bf..0000000 --- a/src/gcode/bedlevel/G35.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(ASSISTED_TRAMMING) - -#include "../gcode.h" -#include "../../module/planner.h" -#include "../../module/probe.h" -#include "../../feature/bedlevel/bedlevel.h" - -#if HAS_MULTI_HOTEND - #include "../../module/tool_change.h" -#endif - -#if ENABLED(BLTOUCH) - #include "../../feature/bltouch.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -// -// Define tramming point names. -// - -#include "../../feature/tramming.h" - -/** - * G35: Read bed corners to help adjust bed screws - * - * S - * - * Screw thread: 30 - Clockwise M3 - * 31 - Counter-Clockwise M3 - * 40 - Clockwise M4 - * 41 - Counter-Clockwise M4 - * 50 - Clockwise M5 - * 51 - Counter-Clockwise M5 - **/ -void GcodeSuite::G35() { - DEBUG_SECTION(log_G35, "G35", DEBUGGING(LEVELING)); - - if (DEBUGGING(LEVELING)) log_machine_info(); - - float z_measured[G35_PROBE_COUNT] = { 0 }; - - const uint8_t screw_thread = parser.byteval('S', TRAMMING_SCREW_THREAD); - if (!WITHIN(screw_thread, 30, 51) || screw_thread % 10 > 1) { - SERIAL_ECHOLNPGM("?(S)crew thread must be 30, 31, 40, 41, 50, or 51."); - return; - } - - // Wait for planner moves to finish! - planner.synchronize(); - - // Disable the leveling matrix before auto-aligning - #if HAS_LEVELING - #if ENABLED(RESTORE_LEVELING_AFTER_G35) - const bool leveling_was_active = planner.leveling_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 HAS_MULTI_HOTEND - const uint8_t old_tool_index = active_extruder; - tool_change(0, true); - #endif - - // Disable duplication mode on homing - TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false)); - - // Home only Z axis when X and Y is trusted, otherwise all axes, if needed before this procedure - if (!all_axes_trusted()) process_subcommands_now(F("G28Z")); - - bool err_break = false; - - // Probe all positions - LOOP_L_N(i, G35_PROBE_COUNT) { - - // In BLTOUCH HS mode, the probe travels in a deployed state. - // Users of G35 might have a badly misaligned bed, so raise Z by the - // length of the deployed pin (BLTOUCH stroke < 7mm) - - // Unsure if this is even required. The probe seems to lift correctly after probe done. - do_blocking_move_to_z(SUM_TERN(BLTOUCH, Z_CLEARANCE_BETWEEN_PROBES, bltouch.z_extra_clearance())); - const float z_probed_height = probe.probe_at_point(tramming_points[i], PROBE_PT_RAISE, 0, true); - - if (isnan(z_probed_height)) { - SERIAL_ECHOPGM("G35 failed at point ", i + 1, " ("); - SERIAL_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i])); - SERIAL_CHAR(')'); - SERIAL_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y); - err_break = true; - break; - } - - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOPGM("Probing point ", i + 1, " ("); - DEBUG_ECHOF(FPSTR(pgm_read_ptr(&tramming_point_name[i]))); - DEBUG_CHAR(')'); - DEBUG_ECHOLNPGM_P(SP_X_STR, tramming_points[i].x, SP_Y_STR, tramming_points[i].y, SP_Z_STR, z_probed_height); - } - - z_measured[i] = z_probed_height; - } - - if (!err_break) { - const float threads_factor[] = { 0.5, 0.7, 0.8 }; - - // Calculate adjusts - LOOP_S_L_N(i, 1, G35_PROBE_COUNT) { - const float diff = z_measured[0] - z_measured[i], - adjust = ABS(diff) < 0.001f ? 0 : diff / threads_factor[(screw_thread - 30) / 10]; - - const int full_turns = trunc(adjust); - const float decimal_part = adjust - float(full_turns); - const int minutes = trunc(decimal_part * 60.0f); - - SERIAL_ECHOPGM("Turn "); - SERIAL_ECHOPGM_P((char *)pgm_read_ptr(&tramming_point_name[i])); - SERIAL_ECHOPGM(" ", (screw_thread & 1) == (adjust > 0) ? "CCW" : "CW", " by ", ABS(full_turns), " turns"); - if (minutes) SERIAL_ECHOPGM(" and ", ABS(minutes), " minutes"); - if (ENABLED(REPORT_TRAMMING_MM)) SERIAL_ECHOPGM(" (", -diff, "mm)"); - SERIAL_EOL(); - } - } - else - SERIAL_ECHOLNPGM("G35 aborted."); - - // Restore the active tool after homing - #if HAS_MULTI_HOTEND - if (old_tool_index != 0) tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER)); // Fetch previous toolhead if not PARKING_EXTRUDER - #endif - - #if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G35) - set_bed_leveling_enabled(leveling_was_active); - #endif - - // Stow the probe, as the last call to probe.probe_at_point(...) left - // the probe deployed if it was successful. - probe.stow(); - - move_to_tramming_wait_pos(); - - // After this operation the Z position needs correction - set_axis_never_homed(Z_AXIS); -} - -#endif // ASSISTED_TRAMMING diff --git a/src/gcode/bedlevel/G42.cpp b/src/gcode/bedlevel/G42.cpp deleted file mode 100644 index cb5ed97..0000000 --- a/src/gcode/bedlevel/G42.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_MESH - -#include "../gcode.h" -#include "../../MarlinCore.h" // for IsRunning() -#include "../../module/motion.h" -#include "../../module/probe.h" // for probe.offset -#include "../../feature/bedlevel/bedlevel.h" - -/** - * G42: Move X & Y axes to mesh coordinates (I & J) - */ -void GcodeSuite::G42() { - if (MOTION_CONDITIONS) { - 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(STR_ERR_MESH_XY); - return; - } - - // Move to current_position, as modified by I, J, P parameters - destination = current_position; - - if (hasI) destination.x = bedlevel.get_mesh_x(ix); - if (hasJ) destination.y = bedlevel.get_mesh_y(iy); - - #if HAS_PROBE_XY_OFFSET - if (parser.boolval('P')) { - if (hasI) destination.x -= probe.offset_xy.x; - if (hasJ) destination.y -= probe.offset_xy.y; - } - #endif - - const feedRate_t fval = parser.linearval('F'), - fr_mm_s = MMM_TO_MMS(fval > 0 ? fval : 0.0f); - - // SCARA kinematic has "safe" XY raw moves - #if IS_SCARA - prepare_internal_fast_move_to_destination(fr_mm_s); - #else - prepare_internal_move_to_destination(fr_mm_s); - #endif - } -} - -#endif // HAS_MESH diff --git a/src/gcode/bedlevel/M420.cpp b/src/gcode/bedlevel/M420.cpp deleted file mode 100644 index 277f95b..0000000 --- a/src/gcode/bedlevel/M420.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_LEVELING - -#include "../gcode.h" -#include "../../feature/bedlevel/bedlevel.h" -#include "../../module/planner.h" -#include "../../module/probe.h" - -#if ENABLED(EEPROM_SETTINGS) - #include "../../module/settings.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#endif - -//#define M420_C_USE_MEAN - -/** - * 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) - * T[map] 0:Human-readable 1:CSV 2:"LCD" 4:Compact - * - * With mesh-based leveling only: - * - * C Center mesh on the mean of the lowest and highest - * - * With MARLIN_DEV_MODE: - * S2 Create a simple random mesh and enable - */ -void GcodeSuite::M420() { - const bool seen_S = parser.seen('S'), - to_enable = seen_S ? parser.value_bool() : planner.leveling_active; - - #if ENABLED(MARLIN_DEV_MODE) - if (parser.intval('S') == 2) { - const float x_min = probe.min_x(), x_max = probe.max_x(), - y_min = probe.min_y(), y_max = probe.max_y(); - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - xy_pos_t start, spacing; - start.set(x_min, y_min); - spacing.set((x_max - x_min) / (GRID_MAX_CELLS_X), - (y_max - y_min) / (GRID_MAX_CELLS_Y)); - bedlevel.set_grid(spacing, start); - #endif - GRID_LOOP(x, y) { - bedlevel.z_values[x][y] = 0.001 * random(-200, 200); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, bedlevel.z_values[x][y])); - } - TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.refresh_bed_level()); - SERIAL_ECHOPGM("Simulated " STRINGIFY(GRID_MAX_POINTS_X) "x" STRINGIFY(GRID_MAX_POINTS_Y) " mesh "); - SERIAL_ECHOPGM(" (", x_min); - SERIAL_CHAR(','); SERIAL_ECHO(y_min); - SERIAL_ECHOPGM(")-(", x_max); - SERIAL_CHAR(','); SERIAL_ECHO(y_max); - SERIAL_ECHOLNPGM(")"); - } - #endif - - xyz_pos_t oldpos = current_position; - - // If disabling leveling do it right away - // (Don't disable for just M420 or M420 V) - if (seen_S && !to_enable) set_bed_leveling_enabled(false); - - #if ENABLED(AUTO_BED_LEVELING_UBL) - - // L to load a mesh from the EEPROM - if (parser.seen('L')) { - - set_bed_leveling_enabled(false); - - #if ENABLED(EEPROM_SETTINGS) - const int8_t storage_slot = parser.has_value() ? parser.value_int() : bedlevel.storage_slot; - const int16_t a = settings.calc_num_meshes(); - - if (!a) { - SERIAL_ECHOLNPGM("?EEPROM storage not available."); - return; - } - - if (!WITHIN(storage_slot, 0, a - 1)) { - SERIAL_ECHOLNPGM("?Invalid storage slot."); - SERIAL_ECHOLNPGM("?Use 0 to ", a - 1); - return; - } - - settings.load_mesh(storage_slot); - bedlevel.storage_slot = storage_slot; - - #else - - SERIAL_ECHOLNPGM("?EEPROM storage not available."); - return; - - #endif - } - - // L or V display the map info - if (parser.seen("LV")) { - bedlevel.display_map(parser.byteval('T')); - SERIAL_ECHOPGM("Mesh is "); - if (!bedlevel.mesh_is_valid()) SERIAL_ECHOPGM("in"); - SERIAL_ECHOLNPGM("valid\nStorage slot: ", bedlevel.storage_slot); - } - - #endif // AUTO_BED_LEVELING_UBL - - const bool seenV = parser.seen_test('V'); - - #if HAS_MESH - - if (leveling_is_valid()) { - - // Subtract the given value or the mean from all mesh values - if (parser.seen('C')) { - const float cval = parser.value_float(); - #if ENABLED(AUTO_BED_LEVELING_UBL) - - set_bed_leveling_enabled(false); - bedlevel.adjust_mesh_to_mean(true, cval); - - #else - - #if ENABLED(M420_C_USE_MEAN) - - // Get the sum and average of all mesh values - float mesh_sum = 0; - GRID_LOOP(x, y) mesh_sum += bedlevel.z_values[x][y]; - const float zmean = mesh_sum / float(GRID_MAX_POINTS); - - #else // midrange - - // Find the low and high mesh values. - float lo_val = 100, hi_val = -100; - GRID_LOOP(x, y) { - const float z = bedlevel.z_values[x][y]; - NOMORE(lo_val, z); - NOLESS(hi_val, z); - } - // Get the midrange plus C value. (The median may be better.) - const float zmean = (lo_val + hi_val) / 2.0 + cval; - - #endif - - // If not very close to 0, adjust the mesh - if (!NEAR_ZERO(zmean)) { - set_bed_leveling_enabled(false); - // Subtract the mean from all values - GRID_LOOP(x, y) { - bedlevel.z_values[x][y] -= zmean; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, bedlevel.z_values[x][y])); - } - TERN_(AUTO_BED_LEVELING_BILINEAR, bedlevel.refresh_bed_level()); - } - - #endif - } - - } - else if (to_enable || seenV) { - SERIAL_ECHO_MSG("Invalid mesh."); - goto EXIT_M420; - } - - #endif // HAS_MESH - - // V to print the matrix or mesh - if (seenV) { - #if ABL_PLANAR - planner.bed_level_matrix.debug(F("Bed Level Correction Matrix:")); - #else - if (leveling_is_valid()) { - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - bedlevel.print_leveling_grid(); - #elif ENABLED(MESH_BED_LEVELING) - SERIAL_ECHOLNPGM("Mesh Bed Level data:"); - bedlevel.report_mesh(); - #endif - } - #endif - } - - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - if (parser.seen('Z')) set_z_fade_height(parser.value_linear_units(), false); - #endif - - // Enable leveling if specified, or if previously active - set_bed_leveling_enabled(to_enable); - - #if HAS_MESH - EXIT_M420: - #endif - - // Error if leveling failed to enable or reenable - if (to_enable && !planner.leveling_active) - SERIAL_ERROR_MSG(STR_ERR_M420_FAILED); - - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Bed Leveling "); - serialprintln_onoff(planner.leveling_active); - - #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(STR_OFF); - #endif - - // Report change in position - if (oldpos != current_position) - report_current_position(); -} - -void GcodeSuite::M420_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F( - TERN(MESH_BED_LEVELING, "Mesh Bed Leveling", TERN(AUTO_BED_LEVELING_UBL, "Unified Bed Leveling", "Auto Bed Leveling")) - )); - SERIAL_ECHOF( - F(" M420 S"), planner.leveling_active - #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - , FPSTR(SP_Z_STR), LINEAR_UNIT(planner.z_fade_height) - #endif - , F(" ; Leveling ") - ); - serialprintln_onoff(planner.leveling_active); -} - -#endif // HAS_LEVELING diff --git a/src/gcode/bedlevel/abl/G29.cpp b/src/gcode/bedlevel/abl/G29.cpp deleted file mode 100644 index a540eae..0000000 --- a/src/gcode/bedlevel/abl/G29.cpp +++ /dev/null @@ -1,923 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * G29.cpp - Auto Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_ABL_NOT_UBL - -#include "../../gcode.h" -#include "../../../feature/bedlevel/bedlevel.h" -#include "../../../module/motion.h" -#include "../../../module/planner.h" -#include "../../../module/probe.h" -#include "../../queue.h" - -#if ENABLED(AUTO_BED_LEVELING_LINEAR) - #include "../../../libs/least_squares_fit.h" -#endif - -#if ABL_PLANAR - #include "../../../libs/vector_3.h" -#endif - -#include "../../../lcd/marlinui.h" -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_CREALITY_LCD) - #include "../../../lcd/e3v2/creality/dwin.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../../../lcd/e3v2/proui/dwin.h" -#endif - -#if HAS_MULTI_HOTEND - #include "../../../module/tool_change.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../../core/debug_out.h" - -#if ABL_USES_GRID - #if ENABLED(PROBE_Y_FIRST) - #define PR_OUTER_VAR abl.meshCount.x - #define PR_OUTER_SIZE abl.grid_points.x - #define PR_INNER_VAR abl.meshCount.y - #define PR_INNER_SIZE abl.grid_points.y - #else - #define PR_OUTER_VAR abl.meshCount.y - #define PR_OUTER_SIZE abl.grid_points.y - #define PR_INNER_VAR abl.meshCount.x - #define PR_INNER_SIZE abl.grid_points.x - #endif -#endif - -static void pre_g29_return(const bool retry, const bool did) { - if (!retry) { - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE, false)); - } - if (did) { - TERN_(HAS_DWIN_E3V2_BASIC, DWIN_LevelingDone()); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); - } -} - -#define G29_RETURN(retry, did) do{ \ - pre_g29_return(TERN0(G29_RETRY_AND_RECOVER, retry), did); \ - return TERN_(G29_RETRY_AND_RECOVER, retry); \ -}while(0) - -// For manual probing values persist over multiple G29 -class G29_State { -public: - int verbose_level; - xy_pos_t probePos; - float measured_z; - bool dryrun, - reenable; - - #if HAS_MULTI_HOTEND - uint8_t tool_index; - #endif - - #if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR) - int abl_probe_index; - #endif - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - int abl_points; - #elif ENABLED(AUTO_BED_LEVELING_3POINT) - static constexpr int abl_points = 3; - #elif ABL_USES_GRID - static constexpr int abl_points = GRID_MAX_POINTS; - #endif - - #if ABL_USES_GRID - - xy_int8_t meshCount; - - xy_pos_t probe_position_lf, - probe_position_rb; - - xy_float_t gridSpacing; // = { 0.0f, 0.0f } - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - bool topography_map; - xy_uint8_t grid_points; - #else // Bilinear - static constexpr xy_uint8_t grid_points = { GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y }; - #endif - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - float Z_offset; - bed_mesh_t z_values; - #endif - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - int indexIntoAB[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; - 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 - #endif -}; - -#if ABL_USES_GRID && EITHER(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR) - constexpr xy_uint8_t G29_State::grid_points; - constexpr int G29_State::abl_points; -#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 - * - * O Auto-level only if needed - * - * 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) - * - * H Set bounds to a centered square H x H units in size - * - * -or- - * - * 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. - */ -G29_TYPE GcodeSuite::G29() { - DEBUG_SECTION(log_G29, "G29", DEBUGGING(LEVELING)); - - // Leveling state is persistent when done manually with multiple G29 commands - TERN_(PROBE_MANUALLY, static) G29_State abl; - - // Keep powered steppers from timing out - reset_stepper_timeout(); - - // Q = Query leveling and G29 state - const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q'); - - // G29 Q is also available if debugging - #if ENABLED(DEBUG_LEVELING_FEATURE) - if (seenQ || DEBUGGING(LEVELING)) log_machine_info(); - if (DISABLED(PROBE_MANUALLY) && seenQ) G29_RETURN(false, false); - #endif - - // A = Abort manual probing - // C = Generate fake probe points (DEBUG_LEVELING_FEATURE) - const bool seenA = TERN0(PROBE_MANUALLY, parser.seen_test('A')), - no_action = seenA || seenQ, - faux = ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) ? parser.boolval('C') : no_action; - - // O = Don't level if leveling is already active - if (!no_action && planner.leveling_active && parser.boolval('O')) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Auto-level not needed, skip"); - G29_RETURN(false, false); - } - - // Send 'N' to force homing before G29 (internal only) - if (parser.seen_test('N')) - process_subcommands_now(TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR))); - - // Don't allow auto-leveling without homing first - if (homing_needed_error()) G29_RETURN(false, false); - - // 3-point leveling gets points from the probe class - #if ENABLED(AUTO_BED_LEVELING_3POINT) - vector_3 points[3]; - probe.get_three_points(points); - #endif - - // Storage for ABL Linear results - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - struct linear_fit_data lsf_results; - #endif - - // Set and report "probing" state to host - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE, false)); - - /** - * On the initial G29 fetch command parameters. - */ - if (!g29_in_progress) { - - #if HAS_MULTI_HOTEND - abl.tool_index = active_extruder; - if (active_extruder != 0) tool_change(0, true); - #endif - - #if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR) - abl.abl_probe_index = -1; - #endif - - abl.reenable = planner.leveling_active; - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - - const bool seen_w = parser.seen_test('W'); - if (seen_w) { - if (!leveling_is_valid()) { - SERIAL_ERROR_MSG("No bilinear grid"); - G29_RETURN(false, false); - } - - const float rz = parser.seenval('Z') ? RAW_Z_POSITION(parser.value_linear_units()) : current_position.z; - if (!WITHIN(rz, -10, 10)) { - SERIAL_ERROR_MSG("Bad Z value"); - G29_RETURN(false, false); - } - - const float rx = RAW_X_POSITION(parser.linearval('X', NAN)), - ry = RAW_Y_POSITION(parser.linearval('Y', NAN)); - int8_t i = parser.byteval('I', -1), j = parser.byteval('J', -1); - - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" - - if (!isnan(rx) && !isnan(ry)) { - // Get nearest i / j from rx / ry - i = (rx - bedlevel.grid_start.x) / bedlevel.grid_spacing.x + 0.5f; - j = (ry - bedlevel.grid_start.y) / bedlevel.grid_spacing.y + 0.5f; - LIMIT(i, 0, (GRID_MAX_POINTS_X) - 1); - LIMIT(j, 0, (GRID_MAX_POINTS_Y) - 1); - } - - #pragma GCC diagnostic pop - - if (WITHIN(i, 0, (GRID_MAX_POINTS_X) - 1) && WITHIN(j, 0, (GRID_MAX_POINTS_Y) - 1)) { - set_bed_leveling_enabled(false); - bedlevel.z_values[i][j] = rz; - bedlevel.refresh_bed_level(); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(i, j, rz)); - if (abl.reenable) { - set_bed_leveling_enabled(true); - report_current_position(); - } - } - G29_RETURN(false, false); - } // parser.seen_test('W') - - #else - - constexpr bool seen_w = false; - - #endif - - // Jettison bed leveling data - if (!seen_w && parser.seen_test('J')) { - reset_bed_level(); - G29_RETURN(false, false); - } - - abl.verbose_level = parser.intval('V'); - if (!WITHIN(abl.verbose_level, 0, 4)) { - SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4)."); - G29_RETURN(false, false); - } - - abl.dryrun = parser.boolval('D') || TERN0(PROBE_MANUALLY, no_action); - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - - incremental_LSF_reset(&lsf_results); - - abl.topography_map = abl.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.set( - parser.byteval('X', GRID_MAX_POINTS_X), - parser.byteval('Y', GRID_MAX_POINTS_Y) - ); - if (parser.seenval('P')) abl.grid_points.x = abl.grid_points.y = parser.value_int(); - - if (!WITHIN(abl.grid_points.x, 2, GRID_MAX_POINTS_X)) { - SERIAL_ECHOLNPGM("?Probe points (X) implausible (2-" STRINGIFY(GRID_MAX_POINTS_X) ")."); - G29_RETURN(false, false); - } - if (!WITHIN(abl.grid_points.y, 2, GRID_MAX_POINTS_Y)) { - SERIAL_ECHOLNPGM("?Probe points (Y) implausible (2-" STRINGIFY(GRID_MAX_POINTS_Y) ")."); - G29_RETURN(false, false); - } - - abl.abl_points = abl.grid_points.x * abl.grid_points.y; - abl.mean = 0; - - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - - abl.Z_offset = parser.linearval('Z'); - - #endif - - #if ABL_USES_GRID - - xy_probe_feedrate_mm_s = MMM_TO_MMS(parser.linearval('S', XY_PROBE_FEEDRATE)); - - const float x_min = probe.min_x(), x_max = probe.max_x(), - y_min = probe.min_y(), y_max = probe.max_y(); - - if (parser.seen('H')) { - const int16_t size = (int16_t)parser.value_linear_units(); - abl.probe_position_lf.set(_MAX((X_CENTER) - size / 2, x_min), _MAX((Y_CENTER) - size / 2, y_min)); - abl.probe_position_rb.set(_MIN(abl.probe_position_lf.x + size, x_max), _MIN(abl.probe_position_lf.y + size, y_max)); - } - else { - abl.probe_position_lf.set(parser.linearval('L', x_min), parser.linearval('F', y_min)); - abl.probe_position_rb.set(parser.linearval('R', x_max), parser.linearval('B', y_max)); - } - - if (!probe.good_bounds(abl.probe_position_lf, abl.probe_position_rb)) { - if (DEBUGGING(LEVELING)) { - DEBUG_ECHOLNPGM("G29 L", abl.probe_position_lf.x, " R", abl.probe_position_rb.x, - " F", abl.probe_position_lf.y, " B", abl.probe_position_rb.y); - } - SERIAL_ECHOLNPGM("? (L,R,F,B) out of bounds."); - G29_RETURN(false, false); - } - - // Probe at the points of a lattice grid - abl.gridSpacing.set((abl.probe_position_rb.x - abl.probe_position_lf.x) / (abl.grid_points.x - 1), - (abl.probe_position_rb.y - abl.probe_position_lf.y) / (abl.grid_points.y - 1)); - - #endif // ABL_USES_GRID - - if (abl.verbose_level > 0) { - SERIAL_ECHOPGM("G29 Auto Bed Leveling"); - if (abl.dryrun) SERIAL_ECHOPGM(" (DRYRUN)"); - SERIAL_EOL(); - } - - planner.synchronize(); - - #if ENABLED(AUTO_BED_LEVELING_3POINT) - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> 3-point Leveling"); - points[0].z = points[1].z = points[2].z = 0; // Probe at 3 arbitrary points - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart()); - #endif - - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); - - if (!faux) { - remember_feedrate_scaling_off(); - - #if ENABLED(PREHEAT_BEFORE_LEVELING) - if (!abl.dryrun) probe.preheat_for_probing(LEVELING_NOZZLE_TEMP, - #if BOTH(DWIN_LCD_PROUI, HAS_HEATED_BED) - HMI_data.BedLevT - #else - LEVELING_BED_TEMP - #endif - ); - #endif - } - - // Disable auto bed leveling during G29. - // Be formal so G29 can be done successively without G28. - if (!no_action) set_bed_leveling_enabled(false); - - // Deploy certain probes before starting probing - #if ENABLED(BLTOUCH) - do_z_clearance(Z_CLEARANCE_DEPLOY_PROBE); - #elif HAS_BED_PROBE - if (probe.deploy()) { // (returns true on deploy failure) - set_bed_leveling_enabled(abl.reenable); - G29_RETURN(false, true); - } - #endif - - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - if (!abl.dryrun - && (abl.gridSpacing != bedlevel.grid_spacing || abl.probe_position_lf != bedlevel.grid_start) - ) { - // Reset grid to 0.0 or "not probed". (Also disables ABL) - reset_bed_level(); - - // Can't re-enable (on error) until the new grid is written - abl.reenable = false; - } - - // Pre-populate local Z values from the stored mesh - TERN_(IS_KINEMATIC, COPY(abl.z_values, bedlevel.z_values)); - - #endif // AUTO_BED_LEVELING_BILINEAR - - } // !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.abl_probe_index; - g29_in_progress = true; - } - - // Abort current G29 procedure, go back to idle state - if (seenA && g29_in_progress) { - SERIAL_ECHOLNPGM("Manual G29 aborted"); - SET_SOFT_ENDSTOP_LOOSE(false); - set_bed_leveling_enabled(abl.reenable); - g29_in_progress = false; - TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); - } - - // Query G29 status - if (abl.verbose_level || seenQ) { - SERIAL_ECHOPGM("Manual G29 "); - if (g29_in_progress) - SERIAL_ECHOLNPGM("point ", _MIN(abl.abl_probe_index + 1, abl.abl_points), " of ", abl.abl_points); - else - SERIAL_ECHOLNPGM("idle"); - } - - // For 'A' or 'Q' exit with success state - if (no_action) G29_RETURN(false, true); - - if (abl.abl_probe_index == 0) { - // For the initial G29 S2 save software endstop state - SET_SOFT_ENDSTOP_LOOSE(true); - // Move close to the bed before the first point - do_blocking_move_to_z(0); - } - else { - - #if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT) - const uint16_t index = abl.abl_probe_index - 1; - #endif - - // For G29 after adjusting Z. - // Save the previous Z before going to the next point - abl.measured_z = current_position.z; - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - - abl.mean += abl.measured_z; - abl.eqnBVector[index] = abl.measured_z; - abl.eqnAMatrix[index + 0 * abl.abl_points] = abl.probePos.x; - abl.eqnAMatrix[index + 1 * abl.abl_points] = abl.probePos.y; - abl.eqnAMatrix[index + 2 * abl.abl_points] = 1; - - incremental_LSF(&lsf_results, abl.probePos, abl.measured_z); - - #elif ENABLED(AUTO_BED_LEVELING_3POINT) - - points[index].z = abl.measured_z; - - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - - const float newz = abl.measured_z + abl.Z_offset; - abl.z_values[abl.meshCount.x][abl.meshCount.y] = newz; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, newz)); - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM_P(PSTR("Save X"), abl.meshCount.x, SP_Y_STR, abl.meshCount.y, SP_Z_STR, abl.measured_z + abl.Z_offset); - - #endif - } - - // - // If there's another point to sample, move there with optional lift. - // - - #if ABL_USES_GRID - - // Skip any unreachable points - while (abl.abl_probe_index < abl.abl_points) { - - // Set abl.meshCount.x, abl.meshCount.y based on abl.abl_probe_index, with zig-zag - PR_OUTER_VAR = abl.abl_probe_index / PR_INNER_SIZE; - PR_INNER_VAR = abl.abl_probe_index - (PR_OUTER_VAR * PR_INNER_SIZE); - - // Probe in reverse order for every other row/column - const bool zig = (PR_OUTER_VAR & 1); // != ((PR_OUTER_SIZE) & 1); - if (zig) PR_INNER_VAR = (PR_INNER_SIZE - 1) - PR_INNER_VAR; - - abl.probePos = abl.probe_position_lf + abl.gridSpacing * abl.meshCount.asFloat(); - - TERN_(AUTO_BED_LEVELING_LINEAR, abl.indexIntoAB[abl.meshCount.x][abl.meshCount.y] = abl.abl_probe_index); - - // Keep looping till a reachable point is found - if (position_is_reachable(abl.probePos)) break; - ++abl.abl_probe_index; - } - - // Is there a next point to move to? - if (abl.abl_probe_index < abl.abl_points) { - _manual_goto_xy(abl.probePos); // Can be used here too! - // Disable software endstops to allow manual adjustment - // If G29 is not completed, they will not be re-enabled - SET_SOFT_ENDSTOP_LOOSE(true); - G29_RETURN(false, true); - } - else { - // Leveling done! Fall through to G29 finishing code below - SERIAL_ECHOLNPGM("Grid probing done."); - // Re-enable software endstops, if needed - SET_SOFT_ENDSTOP_LOOSE(false); - } - - #elif ENABLED(AUTO_BED_LEVELING_3POINT) - - // Probe at 3 arbitrary points - if (abl.abl_probe_index < abl.abl_points) { - abl.probePos = xy_pos_t(points[abl.abl_probe_index]); - _manual_goto_xy(abl.probePos); - // Disable software endstops to allow manual adjustment - // If G29 is not completed, they will not be re-enabled - SET_SOFT_ENDSTOP_LOOSE(true); - G29_RETURN(false, true); - } - else { - - SERIAL_ECHOLNPGM("3-point probing done."); - - // Re-enable software endstops, if needed - SET_SOFT_ENDSTOP_LOOSE(false); - - if (!abl.dryrun) { - vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); - if (planeNormal.z < 0) planeNormal *= -1; - planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); - - // Can't re-enable (on error) until the new grid is written - abl.reenable = false; - } - - } - - #endif // AUTO_BED_LEVELING_3POINT - - #else // !PROBE_MANUALLY - { - const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE; - - abl.measured_z = 0; - - #if ABL_USES_GRID - - bool zig = PR_OUTER_SIZE & 1; // Always end at RIGHT and BACK_PROBE_BED_POSITION - - // Outer loop is X with PROBE_Y_FIRST enabled - // Outer loop is Y with PROBE_Y_FIRST disabled - for (PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_SIZE && !isnan(abl.measured_z); PR_OUTER_VAR++) { - - int8_t inStart, inStop, inInc; - - if (zig) { // Zig away from origin - inStart = 0; // Left or front - inStop = PR_INNER_SIZE; // Right or back - inInc = 1; // Zig right - } - else { // Zag towards origin - inStart = PR_INNER_SIZE - 1; // Right or back - inStop = -1; // Left or front - inInc = -1; // Zag left - } - - zig ^= true; // zag - - // An index to print current state - uint8_t pt_index = (PR_OUTER_VAR) * (PR_INNER_SIZE) + 1; - - // Inner loop is Y with PROBE_Y_FIRST enabled - // Inner loop is X with PROBE_Y_FIRST disabled - for (PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; pt_index++, PR_INNER_VAR += inInc) { - - abl.probePos = abl.probe_position_lf + abl.gridSpacing * abl.meshCount.asFloat(); - - TERN_(AUTO_BED_LEVELING_LINEAR, abl.indexIntoAB[abl.meshCount.x][abl.meshCount.y] = ++abl.abl_probe_index); // 0... - - // Avoid probing outside the round or hexagonal area - if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue; - - if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, "."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points))); - - abl.measured_z = faux ? 0.001f * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); - - if (isnan(abl.measured_z)) { - set_bed_leveling_enabled(abl.reenable); - break; // Breaks out of both loops - } - - #if ENABLED(AUTO_BED_LEVELING_LINEAR) - - abl.mean += abl.measured_z; - abl.eqnBVector[abl.abl_probe_index] = abl.measured_z; - abl.eqnAMatrix[abl.abl_probe_index + 0 * abl.abl_points] = abl.probePos.x; - abl.eqnAMatrix[abl.abl_probe_index + 1 * abl.abl_points] = abl.probePos.y; - abl.eqnAMatrix[abl.abl_probe_index + 2 * abl.abl_points] = 1; - - incremental_LSF(&lsf_results, abl.probePos, abl.measured_z); - - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - - const float z = abl.measured_z + abl.Z_offset; - abl.z_values[abl.meshCount.x][abl.meshCount.y] = z; - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(abl.meshCount, z)); - - #endif - - abl.reenable = false; // Don't re-enable after modifying the mesh - idle_no_sleep(); - - } // inner - } // outer - - #elif ENABLED(AUTO_BED_LEVELING_3POINT) - - // Probe at 3 arbitrary points - - LOOP_L_N(i, 3) { - if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3."); - TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1))); - - // Retain the last probe position - abl.probePos = xy_pos_t(points[i]); - abl.measured_z = faux ? 0.001 * random(-100, 101) : probe.probe_at_point(abl.probePos, raise_after, abl.verbose_level); - if (isnan(abl.measured_z)) { - set_bed_leveling_enabled(abl.reenable); - break; - } - points[i].z = abl.measured_z; - } - - if (!abl.dryrun && !isnan(abl.measured_z)) { - vector_3 planeNormal = vector_3::cross(points[0] - points[1], points[2] - points[1]).get_normal(); - if (planeNormal.z < 0) planeNormal *= -1; - planner.bed_level_matrix = matrix_3x3::create_look_at(planeNormal); - - // Can't re-enable (on error) until the new grid is written - abl.reenable = false; - } - - #endif // AUTO_BED_LEVELING_3POINT - - TERN_(HAS_STATUS_MESSAGE, ui.reset_status()); - - // Stow the probe. No raise for FIX_MOUNTED_PROBE. - if (probe.stow()) { - set_bed_leveling_enabled(abl.reenable); - abl.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 (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position); - - #if ENABLED(PROBE_MANUALLY) - g29_in_progress = false; - TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); - #endif - - // Calculate leveling, print reports, correct the position - if (!isnan(abl.measured_z)) { - #if ENABLED(AUTO_BED_LEVELING_BILINEAR) - - if (abl.dryrun) - bedlevel.print_leveling_grid(&abl.z_values); - else { - bedlevel.set_grid(abl.gridSpacing, abl.probe_position_lf); - COPY(bedlevel.z_values, abl.z_values); - TERN_(IS_KINEMATIC, bedlevel.extrapolate_unprobed_bed_level()); - bedlevel.refresh_bed_level(); - - bedlevel.print_leveling_grid(); - } - - #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 - */ - struct { float a, b, d; } plane_equation_coefficients; - - finish_incremental_LSF(&lsf_results); - plane_equation_coefficients.a = -lsf_results.A; // We should be able to eliminate the '-' on these three lines and down below - plane_equation_coefficients.b = -lsf_results.B; // but that is not yet tested. - plane_equation_coefficients.d = -lsf_results.D; - - abl.mean /= abl.abl_points; - - if (abl.verbose_level) { - SERIAL_ECHOPAIR_F("Eqn coefficients: a: ", plane_equation_coefficients.a, 8); - SERIAL_ECHOPAIR_F(" b: ", plane_equation_coefficients.b, 8); - SERIAL_ECHOPAIR_F(" d: ", plane_equation_coefficients.d, 8); - if (abl.verbose_level > 2) - SERIAL_ECHOPAIR_F("\nMean of sampled points: ", abl.mean, 8); - SERIAL_EOL(); - } - - // Create the matrix but don't correct the position yet - if (!abl.dryrun) - planner.bed_level_matrix = matrix_3x3::create_look_at( - vector_3(-plane_equation_coefficients.a, -plane_equation_coefficients.b, 1) // We can eliminate the '-' here and up above - ); - - // Show the Topography map if enabled - if (abl.topography_map) { - - float min_diff = 999; - - auto print_topo_map = [&](FSTR_P const title, const bool get_min) { - SERIAL_ECHOF(title); - for (int8_t yy = abl.grid_points.y - 1; yy >= 0; yy--) { - LOOP_L_N(xx, abl.grid_points.x) { - const int ind = abl.indexIntoAB[xx][yy]; - xyz_float_t tmp = { abl.eqnAMatrix[ind + 0 * abl.abl_points], - abl.eqnAMatrix[ind + 1 * abl.abl_points], 0 }; - planner.bed_level_matrix.apply_rotation_xyz(tmp.x, tmp.y, tmp.z); - if (get_min) NOMORE(min_diff, abl.eqnBVector[ind] - tmp.z); - const float subval = get_min ? abl.mean : tmp.z + min_diff, - diff = abl.eqnBVector[ind] - subval; - SERIAL_CHAR(' '); if (diff >= 0.0) SERIAL_CHAR('+'); // Include + for column alignment - SERIAL_ECHO_F(diff, 5); - } // xx - SERIAL_EOL(); - } // yy - SERIAL_EOL(); - }; - - print_topo_map(F("\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)\n"), true); - if (abl.verbose_level > 3) - print_topo_map(F("\nCorrected Bed Height vs. Bed Topology:\n"), false); - - } // abl.topography_map - - #endif // AUTO_BED_LEVELING_LINEAR - - #if ABL_PLANAR - - // For LINEAR and 3POINT leveling correct the current position - - if (abl.verbose_level > 0) - planner.bed_level_matrix.debug(F("\n\nBed Level Correction Matrix:")); - - if (!abl.dryrun) { - // - // Correct the current XYZ position based on the tilted plane. - // - - if (DEBUGGING(LEVELING)) DEBUG_POS("G29 uncorrected XYZ", current_position); - - xyze_pos_t converted = current_position; - planner.force_unapply_leveling(converted); // use conversion machinery - - // Use the last measured distance to the bed, if possible - if ( NEAR(current_position.x, abl.probePos.x - probe.offset_xy.x) - && NEAR(current_position.y, abl.probePos.y - probe.offset_xy.y) - ) { - const float simple_z = current_position.z - abl.measured_z; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Probed Z", simple_z, " Matrix Z", converted.z, " Discrepancy ", simple_z - converted.z); - converted.z = simple_z; - } - - // The rotated XY and corrected Z are now current_position - current_position = converted; - - if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position); - - abl.reenable = true; - } - - // Auto Bed Leveling is complete! Enable if possible. - if (abl.reenable) { - planner.leveling_active = true; - sync_plan_position(); - } - - #elif ENABLED(AUTO_BED_LEVELING_BILINEAR) - - // Auto Bed Leveling is complete! Enable if possible. - if (!abl.dryrun || abl.reenable) set_bed_leveling_enabled(true); - - #endif - - } // !isnan(abl.measured_z) - - // Restore state after probing - if (!faux) restore_feedrate_and_scaling(); - - TERN_(HAS_BED_PROBE, probe.move_z_after_probing()); - - #ifdef Z_PROBE_END_SCRIPT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Probe End Script: ", Z_PROBE_END_SCRIPT); - planner.synchronize(); - process_subcommands_now(F(Z_PROBE_END_SCRIPT)); - #endif - - TERN_(HAS_MULTI_HOTEND, if (abl.tool_index != 0) tool_change(abl.tool_index)); - - report_current_position(); - - G29_RETURN(isnan(abl.measured_z), true); -} - -#endif // HAS_ABL_NOT_UBL diff --git a/src/gcode/bedlevel/abl/M421.cpp b/src/gcode/bedlevel/abl/M421.cpp deleted file mode 100644 index 3272ea1..0000000 --- a/src/gcode/bedlevel/abl/M421.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * M421.cpp - Auto Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_BILINEAR) - -#include "../../gcode.h" -#include "../../../feature/bedlevel/bedlevel.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#endif - -/** - * M421: Set one or more Mesh Bed Leveling Z coordinates - * - * Usage: - * M421 I J Z - * M421 I J Q - * - * - If I is omitted, set the entire row - * - If J is omitted, set the entire column - * - If both I and J are omitted, set all - */ -void GcodeSuite::M421() { - int8_t ix = parser.intval('I', -1), iy = parser.intval('J', -1); - const bool hasZ = parser.seenval('Z'), - hasQ = !hasZ && parser.seenval('Q'); - - if (hasZ || hasQ) { - if (WITHIN(ix, -1, GRID_MAX_POINTS_X - 1) && WITHIN(iy, -1, GRID_MAX_POINTS_Y - 1)) { - const float zval = parser.value_linear_units(); - uint8_t sx = ix >= 0 ? ix : 0, ex = ix >= 0 ? ix : GRID_MAX_POINTS_X - 1, - sy = iy >= 0 ? iy : 0, ey = iy >= 0 ? iy : GRID_MAX_POINTS_Y - 1; - LOOP_S_LE_N(x, sx, ex) { - LOOP_S_LE_N(y, sy, ey) { - bedlevel.z_values[x][y] = zval + (hasQ ? bedlevel.z_values[x][y] : 0); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, bedlevel.z_values[x][y])); - } - } - bedlevel.refresh_bed_level(); - } - else - SERIAL_ERROR_MSG(STR_ERR_MESH_XY); - } - else - SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); -} - -#endif // AUTO_BED_LEVELING_BILINEAR diff --git a/src/gcode/bedlevel/mbl/G29.cpp b/src/gcode/bedlevel/mbl/G29.cpp deleted file mode 100644 index 227964e..0000000 --- a/src/gcode/bedlevel/mbl/G29.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * G29.cpp - Mesh Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(MESH_BED_LEVELING) - -#include "../../../feature/bedlevel/bedlevel.h" - -#include "../../gcode.h" -#include "../../queue.h" - -#include "../../../libs/buzzer.h" -#include "../../../lcd/marlinui.h" -#include "../../../module/motion.h" -#include "../../../module/planner.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../../../lcd/e3v2/proui/dwin.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../../core/debug_out.h" - -// Save 130 bytes with non-duplication of PSTR -inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM(" not entered."); } - -/** - * G29: Mesh-based Z probe, probes a grid and produces a - * mesh to compensate for variable bed height - * - * Parameters With MESH_BED_LEVELING: - * - * S0 Report the current mesh values - * S1 Start probing mesh points - * S2 Probe the next mesh point - * S3 In Jn Zn.nn Manually modify a single point - * S4 Zn.nn Set z offset. Positive away from bed, negative closer to bed. - * S5 Reset and disable mesh - */ -void GcodeSuite::G29() { - DEBUG_SECTION(log_G29, "G29", true); - - // G29 Q is also available if debugging - #if ENABLED(DEBUG_LEVELING_FEATURE) - const bool seenQ = parser.seen_test('Q'); - if (seenQ || DEBUGGING(LEVELING)) { - log_machine_info(); - if (seenQ) return; - } - #endif - - static int mbl_probe_index = -1; - - MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport); - if (!WITHIN(state, 0, 5)) { - SERIAL_ECHOLNPGM("S out of range (0-5)."); - return; - } - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); - - int8_t ix, iy; - ix = iy = 0; - - switch (state) { - case MeshReport: - SERIAL_ECHOPGM("Mesh Bed Leveling "); - if (leveling_is_valid()) { - serialprintln_onoff(planner.leveling_active); - bedlevel.report_mesh(); - } - else - SERIAL_ECHOLNPGM("has no data."); - break; - - case MeshStart: - bedlevel.reset(); - mbl_probe_index = 0; - if (!ui.wait_for_move) { - queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2")); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); - TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart()); - return; - } - state = MeshNext; - - case MeshNext: - if (mbl_probe_index < 0) { - SERIAL_ECHOLNPGM("Start mesh probing with \"G29 S1\" first."); - return; - } - // For each G29 S2... - if (mbl_probe_index == 0) { - // Move close to the bed before the first point - do_blocking_move_to_z( - #ifdef MANUAL_PROBE_START_Z - MANUAL_PROBE_START_Z - #else - 0.4f - #endif - ); - } - else { - // Save Z for the previous mesh position - bedlevel.set_zigzag_z(mbl_probe_index - 1, current_position.z); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, current_position.z)); - TERN_(DWIN_LCD_PROUI, DWIN_MeshUpdate(_MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS), current_position.z)); - SET_SOFT_ENDSTOP_LOOSE(false); - } - // If there's another point to sample, move there with optional lift. - if (mbl_probe_index < (GRID_MAX_POINTS)) { - // Disable software endstops to allow manual adjustment - // If G29 is left hanging without completion they won't be re-enabled! - SET_SOFT_ENDSTOP_LOOSE(true); - bedlevel.zigzag(mbl_probe_index++, ix, iy); - _manual_goto_xy({ bedlevel.index_to_xpos[ix], bedlevel.index_to_ypos[iy] }); - } - else { - // Move to the after probing position - current_position.z = ( - #ifdef Z_AFTER_PROBING - Z_AFTER_PROBING - #else - Z_CLEARANCE_BETWEEN_MANUAL_PROBES - #endif - ); - line_to_current_position(); - planner.synchronize(); - - // After recording the last point, activate home and activate - mbl_probe_index = -1; - SERIAL_ECHOLNPGM("Mesh probing done."); - TERN_(HAS_STATUS_MESSAGE, LCD_MESSAGE(MSG_MESH_DONE)); - OKAY_BUZZ(); - - home_all_axes(); - set_bed_leveling_enabled(true); - - #if ENABLED(MESH_G28_REST_ORIGIN) - current_position.z = 0; - line_to_current_position(homing_feedrate(Z_AXIS)); - planner.synchronize(); - #endif - - TERN_(LCD_BED_LEVELING, ui.wait_for_move = false); - TERN_(EXTENSIBLE_UI, ExtUI::onLevelingDone()); - } - break; - - case MeshSet: - if (parser.seenval('I')) { - ix = parser.value_int(); - if (!WITHIN(ix, 0, (GRID_MAX_POINTS_X) - 1)) { - SERIAL_ECHOLNPGM("I out of range (0-", (GRID_MAX_POINTS_X) - 1, ")"); - return; - } - } - else - return echo_not_entered('J'); - - if (parser.seenval('J')) { - iy = parser.value_int(); - if (!WITHIN(iy, 0, (GRID_MAX_POINTS_Y) - 1)) { - SERIAL_ECHOLNPGM("J out of range (0-", (GRID_MAX_POINTS_Y) - 1, ")"); - return; - } - } - else - return echo_not_entered('J'); - - if (parser.seenval('Z')) { - bedlevel.z_values[ix][iy] = parser.value_linear_units(); - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ix, iy, bedlevel.z_values[ix][iy])); - TERN_(DWIN_LCD_PROUI, DWIN_MeshUpdate(ix, iy, bedlevel.z_values[ix][iy])); - } - else - return echo_not_entered('Z'); - break; - - case MeshSetZOffset: - if (parser.seenval('Z')) - bedlevel.z_offset = parser.value_linear_units(); - else - return echo_not_entered('Z'); - break; - - case MeshReset: - reset_bed_level(); - break; - - } // switch(state) - - if (state == MeshNext) { - SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS); - if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS))); - } - - report_current_position(); - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); -} - -#endif // MESH_BED_LEVELING diff --git a/src/gcode/bedlevel/mbl/M421.cpp b/src/gcode/bedlevel/mbl/M421.cpp deleted file mode 100644 index e23683d..0000000 --- a/src/gcode/bedlevel/mbl/M421.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * M421.cpp - Mesh Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(MESH_BED_LEVELING) - -#include "../../gcode.h" -#include "../../../module/motion.h" -#include "../../../feature/bedlevel/mbl/mesh_bed_leveling.h" - -/** - * 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 - */ -void GcodeSuite::M421() { - const bool hasX = parser.seen('X'), hasI = parser.seen('I'); - const int8_t ix = hasI ? parser.value_int() : hasX ? bedlevel.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 ? bedlevel.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_MSG(STR_ERR_M421_PARAMETERS); - else if (ix < 0 || iy < 0) - SERIAL_ERROR_MSG(STR_ERR_MESH_XY); - else - bedlevel.set_z(ix, iy, parser.value_linear_units() + (hasQ ? bedlevel.z_values[ix][iy] : 0)); -} - -#endif // MESH_BED_LEVELING diff --git a/src/gcode/bedlevel/ubl/G29.cpp b/src/gcode/bedlevel/ubl/G29.cpp deleted file mode 100644 index 90deab3..0000000 --- a/src/gcode/bedlevel/ubl/G29.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * G29.cpp - Unified Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - -#include "../../gcode.h" -#include "../../../feature/bedlevel/bedlevel.h" - -#if ENABLED(FULL_REPORT_TO_HOST_FEATURE) - #include "../../../module/motion.h" -#endif - -void GcodeSuite::G29() { - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); - - bedlevel.G29(); - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); -} - -#endif // AUTO_BED_LEVELING_UBL diff --git a/src/gcode/bedlevel/ubl/M421.cpp b/src/gcode/bedlevel/ubl/M421.cpp deleted file mode 100644 index ff74f4c..0000000 --- a/src/gcode/bedlevel/ubl/M421.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * M421.cpp - Unified Bed Leveling - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - -#include "../../gcode.h" -#include "../../../feature/bedlevel/bedlevel.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../../../lcd/e3v2/proui/dwin.h" -#endif - -/** - * M421: Set a single Mesh Bed Leveling Z coordinate - * - * Usage: - * M421 I J Z : Set the Mesh Point IJ to the Z value - * M421 I J Q : Add the Q value to the Mesh Point IJ - * M421 I J N : Set the Mesh Point IJ to NAN (not set) - * M421 C Z : Set the closest Mesh Point to the Z value - * M421 C Q : Add the Q value to the closest Mesh Point - */ -void GcodeSuite::M421() { - xy_int8_t ij = { int8_t(parser.intval('I', -1)), int8_t(parser.intval('J', -1)) }; - const bool hasI = ij.x >= 0, - hasJ = ij.y >= 0, - hasC = parser.seen_test('C'), - hasN = parser.seen_test('N'), - hasZ = parser.seen('Z'), - hasQ = !hasZ && parser.seen('Q'); - - if (hasC) ij = bedlevel.find_closest_mesh_point_of_type(CLOSEST, current_position); - - // Test for bad parameter combinations - if (int(hasC) + int(hasI && hasJ) != 1 || !(hasZ || hasQ || hasN)) - SERIAL_ERROR_MSG(STR_ERR_M421_PARAMETERS); - - // Test for I J out of range - else if (!WITHIN(ij.x, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(ij.y, 0, GRID_MAX_POINTS_Y - 1)) - SERIAL_ERROR_MSG(STR_ERR_MESH_XY); - else { - float &zval = bedlevel.z_values[ij.x][ij.y]; // Altering this Mesh Point - zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); // N=NAN, Z=NEWVAL, or Q=ADDVAL - TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); // Ping ExtUI in case it's showing the mesh - TERN_(DWIN_LCD_PROUI, DWIN_MeshUpdate(ij.x, ij.y, zval)); - } -} - -#endif // AUTO_BED_LEVELING_UBL diff --git a/src/gcode/calibrate/G28.cpp b/src/gcode/calibrate/G28.cpp deleted file mode 100644 index f7b480a..0000000 --- a/src/gcode/calibrate/G28.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#include "../gcode.h" - -#include "../../module/endstops.h" -#include "../../module/planner.h" -#include "../../module/stepper.h" // for various - -#if HAS_MULTI_HOTEND - #include "../../module/tool_change.h" -#endif - -#if HAS_LEVELING - #include "../../feature/bedlevel/bedlevel.h" -#endif - -#if ENABLED(SENSORLESS_HOMING) - #include "../../feature/tmc_util.h" -#endif - -#include "../../module/probe.h" - -#if ENABLED(BLTOUCH) - #include "../../feature/bltouch.h" -#endif - -#include "../../lcd/marlinui.h" - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#elif ENABLED(DWIN_CREALITY_LCD) - #include "../../lcd/e3v2/creality/dwin.h" -#elif ENABLED(DWIN_LCD_PROUI) - #include "../../lcd/e3v2/proui/dwin.h" -#endif - -#if HAS_L64XX // set L6470 absolute position registers to counts - #include "../../libs/L64XX/L64XX_Marlin.h" -#endif - -#if ENABLED(LASER_FEATURE) - #include "../../feature/spindle_laser.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -#if ENABLED(QUICK_HOME) - - static void quick_home_xy() { - - // Pretend the current position is 0,0 - current_position.set(0.0, 0.0); - sync_plan_position(); - - const int x_axis_home_dir = TOOL_X_HOME_DIR(active_extruder); - - // Use a higher diagonal feedrate so axes move at homing speed - const float minfr = _MIN(homing_feedrate(X_AXIS), homing_feedrate(Y_AXIS)), - fr_mm_s = HYPOT(minfr, minfr); - - #if ENABLED(SENSORLESS_HOMING) - sensorless_t stealth_states { - NUM_AXIS_LIST( - TERN0(X_SENSORLESS, tmc_enable_stallguard(stepperX)), - TERN0(Y_SENSORLESS, tmc_enable_stallguard(stepperY)), - false, false, false, false - ) - , TERN0(X2_SENSORLESS, tmc_enable_stallguard(stepperX2)) - , TERN0(Y2_SENSORLESS, tmc_enable_stallguard(stepperY2)) - }; - #endif - - do_blocking_move_to_xy(1.5 * max_length(X_AXIS) * x_axis_home_dir, 1.5 * max_length(Y_AXIS) * Y_HOME_DIR, fr_mm_s); - - endstops.validate_homing_move(); - - current_position.set(0.0, 0.0); - - #if ENABLED(SENSORLESS_HOMING) && DISABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) - TERN_(X_SENSORLESS, tmc_disable_stallguard(stepperX, stealth_states.x)); - TERN_(X2_SENSORLESS, tmc_disable_stallguard(stepperX2, stealth_states.x2)); - TERN_(Y_SENSORLESS, tmc_disable_stallguard(stepperY, stealth_states.y)); - TERN_(Y2_SENSORLESS, tmc_disable_stallguard(stepperY2, stealth_states.y2)); - #endif - } - -#endif // QUICK_HOME - -#if ENABLED(Z_SAFE_HOMING) - - inline void home_z_safely() { - DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING)); - - // Disallow Z homing if X or Y homing is needed - if (homing_needed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return; - - sync_plan_position(); - - /** - * Move the Z probe (or just the nozzle) to the safe homing point - * (Z is already at the right height) - */ - constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; - #if HAS_HOME_OFFSET - xy_float_t okay_homing_xy = safe_homing_xy; - okay_homing_xy -= home_offset; - #else - constexpr xy_float_t okay_homing_xy = safe_homing_xy; - #endif - - destination.set(okay_homing_xy, current_position.z); - - TERN_(HOMING_Z_WITH_PROBE, destination -= probe.offset_xy); - - if (position_is_reachable(destination)) { - - if (DEBUGGING(LEVELING)) DEBUG_POS("home_z_safely", destination); - - // Free the active extruder for movement - TERN_(DUAL_X_CARRIAGE, idex_set_parked(false)); - - TERN_(SENSORLESS_HOMING, safe_delay(500)); // Short delay needed to settle - - do_blocking_move_to_xy(destination); - homeaxis(Z_AXIS); - } - else { - LCD_MESSAGE(MSG_ZPROBE_OUT); - SERIAL_ECHO_MSG(STR_ZPROBE_OUT_SER); - } - } - -#endif // Z_SAFE_HOMING - -#if ENABLED(IMPROVE_HOMING_RELIABILITY) - - motion_state_t begin_slow_homing() { - motion_state_t motion_state{0}; - motion_state.acceleration.set(planner.settings.max_acceleration_mm_per_s2[X_AXIS], - planner.settings.max_acceleration_mm_per_s2[Y_AXIS] - OPTARG(DELTA, planner.settings.max_acceleration_mm_per_s2[Z_AXIS]) - ); - planner.settings.max_acceleration_mm_per_s2[X_AXIS] = 100; - planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = 100; - TERN_(DELTA, planner.settings.max_acceleration_mm_per_s2[Z_AXIS] = 100); - #if HAS_CLASSIC_JERK - motion_state.jerk_state = planner.max_jerk; - planner.max_jerk.set(0, 0 OPTARG(DELTA, 0)); - #endif - planner.refresh_acceleration_rates(); - return motion_state; - } - - void end_slow_homing(const motion_state_t &motion_state) { - planner.settings.max_acceleration_mm_per_s2[X_AXIS] = motion_state.acceleration.x; - planner.settings.max_acceleration_mm_per_s2[Y_AXIS] = motion_state.acceleration.y; - TERN_(DELTA, planner.settings.max_acceleration_mm_per_s2[Z_AXIS] = motion_state.acceleration.z); - TERN_(HAS_CLASSIC_JERK, planner.max_jerk = motion_state.jerk_state); - planner.refresh_acceleration_rates(); - } - -#endif // IMPROVE_HOMING_RELIABILITY - -/** - * 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. - * - * L Force leveling state ON (if possible) or OFF after homing (Requires RESTORE_LEVELING_AFTER_G28 or ENABLE_LEVELING_AFTER_G28) - * O Home only if the position is not known and trusted - * R Raise by n mm/inches before homing - * - * Cartesian/SCARA parameters - * - * X Home to the X endstop - * Y Home to the Y endstop - * Z Home to the Z endstop - */ -void GcodeSuite::G28() { - DEBUG_SECTION(log_G28, "G28", DEBUGGING(LEVELING)); - if (DEBUGGING(LEVELING)) log_machine_info(); - - /* - * Set the laser power to false to stop the planner from processing the current power setting. - */ - #if ENABLED(LASER_FEATURE) - planner.laser_inline.status.isPowered = false; - #endif - - #if ENABLED(DUAL_X_CARRIAGE) - bool IDEX_saved_duplication_state = extruder_duplication_enabled; - DualXMode IDEX_saved_mode = dual_x_carriage_mode; - #endif - - #if ENABLED(MARLIN_DEV_MODE) - if (parser.seen_test('S')) { - LOOP_NUM_AXES(a) set_axis_is_at_home((AxisEnum)a); - sync_plan_position(); - SERIAL_ECHOLNPGM("Simulated Homing"); - report_current_position(); - return; - } - #endif - - // Home (O)nly if position is unknown - if (!axes_should_home() && parser.seen_test('O')) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip"); - return; - } - - #if ENABLED(FULL_REPORT_TO_HOST_FEATURE) - const M_StateEnum old_grblstate = M_State_grbl; - set_and_report_grblstate(M_HOMING); - #endif - - TERN_(HAS_DWIN_E3V2_BASIC, DWIN_HomingStart()); - TERN_(EXTENSIBLE_UI, ExtUI::onHomingStart()); - - planner.synchronize(); // Wait for planner moves to finish! - - SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state - - // Disable the leveling matrix before homing - #if CAN_SET_LEVELING_AFTER_G28 - const bool leveling_restore_state = parser.boolval('L', TERN1(RESTORE_LEVELING_AFTER_G28, planner.leveling_active)); - #endif - - // Cancel any prior G29 session - TERN_(PROBE_MANUALLY, g29_in_progress = false); - - // Disable leveling before homing - TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); - - // Reset to the XY plane - TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY); - - // Count this command as movement / activity - reset_stepper_timeout(); - - #define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT) - #if HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2) || (ENABLED(DELTA) && HAS_CURRENT_HOME(Z)) || HAS_CURRENT_HOME(I) || HAS_CURRENT_HOME(J) || HAS_CURRENT_HOME(K) - #define HAS_HOMING_CURRENT 1 - #endif - - #if HAS_HOMING_CURRENT - auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) { - DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b); - }; - #if HAS_CURRENT_HOME(X) - const int16_t tmc_save_current_X = stepperX.getMilliamps(); - stepperX.rms_current(X_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_X), tmc_save_current_X, X_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(X2) - const int16_t tmc_save_current_X2 = stepperX2.getMilliamps(); - stepperX2.rms_current(X2_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_X2), tmc_save_current_X2, X2_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(Y) - const int16_t tmc_save_current_Y = stepperY.getMilliamps(); - stepperY.rms_current(Y_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_Y), tmc_save_current_Y, Y_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(Y2) - const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps(); - stepperY2.rms_current(Y2_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_Y2), tmc_save_current_Y2, Y2_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(I) - const int16_t tmc_save_current_I = stepperI.getMilliamps(); - stepperI.rms_current(I_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_I), tmc_save_current_I, I_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(J) - const int16_t tmc_save_current_J = stepperJ.getMilliamps(); - stepperJ.rms_current(J_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_J), tmc_save_current_J, J_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(K) - const int16_t tmc_save_current_K = stepperK.getMilliamps(); - stepperK.rms_current(K_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(Z) && ENABLED(DELTA) - const int16_t tmc_save_current_Z = stepperZ.getMilliamps(); - stepperZ.rms_current(Z_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_Z), tmc_save_current_Z, Z_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(I) - const int16_t tmc_save_current_I = stepperI.getMilliamps(); - stepperI.rms_current(I_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_I), tmc_save_current_I, I_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(J) - const int16_t tmc_save_current_J = stepperJ.getMilliamps(); - stepperJ.rms_current(J_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_J), tmc_save_current_J, J_CURRENT_HOME); - #endif - #if HAS_CURRENT_HOME(K) - const int16_t tmc_save_current_K = stepperK.getMilliamps(); - stepperK.rms_current(K_CURRENT_HOME); - if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME); - #endif - #if SENSORLESS_STALLGUARD_DELAY - safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle - #endif - #endif - - #if ENABLED(IMPROVE_HOMING_RELIABILITY) - motion_state_t saved_motion_state = begin_slow_homing(); - #endif - - // Always home with tool 0 active - #if HAS_MULTI_HOTEND - #if DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE) - const uint8_t old_tool_index = active_extruder; - #endif - // PARKING_EXTRUDER homing requires different handling of movement / solenoid activation, depending on the side of homing - #if ENABLED(PARKING_EXTRUDER) - const bool pe_final_change_must_unpark = parking_extruder_unpark_after_homing(old_tool_index, X_HOME_DIR + 1 == old_tool_index * 2); - #endif - tool_change(0, true); - #endif - - TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false)); - - remember_feedrate_scaling_off(); - - endstops.enable(true); // Enable endstops for next homing move - - #if ENABLED(DELTA) - - constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a DELTA - - home_delta(); - - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); - - #elif ENABLED(AXEL_TPARA) - - constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a TPARA - - home_TPARA(); - - #else - - #define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS)))) - - const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')), - NUM_AXIS_LIST( // Other axes should be homed before Z safe-homing - needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED - needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K) - ), - NUM_AXIS_LIST( // Home each axis if needed or flagged - homeX = needX || parser.seen_test('X'), - homeY = needY || parser.seen_test('Y'), - homeZZ = homeZ, - homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME), homeK = needK || parser.seen_test(AXIS6_NAME) - ), - home_all = NUM_AXIS_GANG( // Home-all if all or none are flagged - homeX == homeX, && homeY == homeX, && homeZ == homeX, - && homeI == homeX, && homeJ == homeX, && homeK == homeX - ), - NUM_AXIS_LIST( - doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ, - doI = home_all || homeI, doJ = home_all || homeJ, doK = home_all || homeK - ); - - #if HAS_Z_AXIS - UNUSED(needZ); UNUSED(homeZZ); - #else - constexpr bool doZ = false; - #endif - - TERN_(HOME_Z_FIRST, if (doZ) homeaxis(Z_AXIS)); - - const bool seenR = parser.seenval('R'); - const float z_homing_height = seenR ? parser.value_linear_units() : Z_HOMING_HEIGHT; - - if (z_homing_height && (seenR || NUM_AXIS_GANG(doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK))) { - // Raise Z before homing any other axes and z is not already high enough (never lower z) - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z (before homing) by ", z_homing_height); - do_z_clearance(z_homing_height); - TERN_(BLTOUCH, bltouch.init()); - } - - // Diagonal move first if both are homing - TERN_(QUICK_HOME, if (doX && doY) quick_home_xy()); - - // Home Y (before X) - if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX))) - homeaxis(Y_AXIS); - - // Home X - if (doX || (doY && ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X))) { - - #if ENABLED(DUAL_X_CARRIAGE) - - // Always home the 2nd (right) extruder first - active_extruder = 1; - homeaxis(X_AXIS); - - // Remember this extruder's position for later tool change - inactive_extruder_x = current_position.x; - - // Home the 1st (left) extruder - active_extruder = 0; - homeaxis(X_AXIS); - - // Consider the active extruder to be in its "parked" position - idex_set_parked(); - - #else - - homeaxis(X_AXIS); - - #endif - } - - // Home Y (after X) - if (DISABLED(HOME_Y_BEFORE_X) && doY) - homeaxis(Y_AXIS); - - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); - - // Home Z last if homing towards the bed - #if HAS_Z_AXIS && DISABLED(HOME_Z_FIRST) - if (doZ) { - #if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) - stepper.set_all_z_lock(false); - stepper.set_separate_multi_axis(false); - #endif - - #if ENABLED(Z_SAFE_HOMING) - if (TERN1(POWER_LOSS_RECOVERY, !parser.seen_test('H'))) home_z_safely(); else homeaxis(Z_AXIS); - #else - homeaxis(Z_AXIS); - #endif - probe.move_z_after_homing(); - } - #endif - - SECONDARY_AXIS_CODE( - if (doI) homeaxis(I_AXIS), - if (doJ) homeaxis(J_AXIS), - if (doK) homeaxis(K_AXIS) - ); - - sync_plan_position(); - - #endif - - /** - * Preserve DXC mode across a G28 for IDEX printers in DXC_DUPLICATION_MODE. - * This is important because it lets a user use the LCD Panel to set an IDEX Duplication mode, and - * then print a standard GCode file that contains a single print that does a G28 and has no other - * IDEX specific commands in it. - */ - #if ENABLED(DUAL_X_CARRIAGE) - - if (idex_is_duplicating()) { - - TERN_(IMPROVE_HOMING_RELIABILITY, saved_motion_state = begin_slow_homing()); - - // Always home the 2nd (right) extruder first - active_extruder = 1; - homeaxis(X_AXIS); - - // Remember this extruder's position for later tool change - inactive_extruder_x = current_position.x; - - // Home the 1st (left) extruder - active_extruder = 0; - homeaxis(X_AXIS); - - // Consider the active extruder to be parked - idex_set_parked(); - - dual_x_carriage_mode = IDEX_saved_mode; - set_duplication_enabled(IDEX_saved_duplication_state); - - TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state)); - } - - #endif // DUAL_X_CARRIAGE - - endstops.not_homing(); - - // Clear endstop state for polled stallGuard endstops - TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state()); - - // Move to a height where we can use the full xy-area - TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height)); - - TERN_(CAN_SET_LEVELING_AFTER_G28, if (leveling_restore_state) set_bed_leveling_enabled()); - - restore_feedrate_and_scaling(); - - // Restore the active tool after homing - #if HAS_MULTI_HOTEND && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)) - tool_change(old_tool_index, TERN(PARKING_EXTRUDER, !pe_final_change_must_unpark, DISABLED(DUAL_X_CARRIAGE))); // Do move if one of these - #endif - - #if HAS_HOMING_CURRENT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current..."); - #if HAS_CURRENT_HOME(X) - stepperX.rms_current(tmc_save_current_X); - #endif - #if HAS_CURRENT_HOME(X2) - stepperX2.rms_current(tmc_save_current_X2); - #endif - #if HAS_CURRENT_HOME(Y) - stepperY.rms_current(tmc_save_current_Y); - #endif - #if HAS_CURRENT_HOME(Y2) - stepperY2.rms_current(tmc_save_current_Y2); - #endif - #if HAS_CURRENT_HOME(Z) && ENABLED(DELTA) - stepperZ.rms_current(tmc_save_current_Z); - #endif - #if HAS_CURRENT_HOME(I) - stepperI.rms_current(tmc_save_current_I); - #endif - #if HAS_CURRENT_HOME(J) - stepperJ.rms_current(tmc_save_current_J); - #endif - #if HAS_CURRENT_HOME(K) - stepperK.rms_current(tmc_save_current_K); - #endif - #if SENSORLESS_STALLGUARD_DELAY - safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle - #endif - #endif // HAS_HOMING_CURRENT - - ui.refresh(); - - TERN_(HAS_DWIN_E3V2_BASIC, DWIN_HomingDone()); - TERN_(EXTENSIBLE_UI, ExtUI::onHomingDone()); - - report_current_position(); - - if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS))) - SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(old_grblstate)); - - #if HAS_L64XX - // Set L6470 absolute position registers to counts - // constexpr *might* move this to PROGMEM. - // If not, this will need a PROGMEM directive and an accessor. - #define _EN_ITEM(N) , E_AXIS - static constexpr AxisEnum L64XX_axis_xref[MAX_L64XX] = { - NUM_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS), - X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS, Z_AXIS - REPEAT(E_STEPPERS, _EN_ITEM) - }; - #undef _EN_ITEM - for (uint8_t j = 1; j <= L64XX::chain[0]; j++) { - const uint8_t cv = L64XX::chain[j]; - L64xxManager.set_param((L64XX_axis_t)cv, L6470_ABS_POS, stepper.position(L64XX_axis_xref[cv])); - } - #endif -} diff --git a/src/gcode/calibrate/G33.cpp b/src/gcode/calibrate/G33.cpp deleted file mode 100644 index 656c23c..0000000 --- a/src/gcode/calibrate/G33.cpp +++ /dev/null @@ -1,698 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DELTA_AUTO_CALIBRATION) - -#include "../gcode.h" -#include "../../module/delta.h" -#include "../../module/motion.h" -#include "../../module/planner.h" -#include "../../module/endstops.h" -#include "../../lcd/marlinui.h" - -#if HAS_BED_PROBE - #include "../../module/probe.h" -#endif - -#if HAS_MULTI_HOTEND - #include "../../module/tool_change.h" -#endif - -#if HAS_LEVELING - #include "../../feature/bedlevel/bedlevel.h" -#endif - -constexpr uint8_t _7P_STEP = 1, // 7-point step - to change number of calibration points - _4P_STEP = _7P_STEP * 2, // 4-point step - NPP = _7P_STEP * 6; // number of calibration points on the radius -enum CalEnum : char { // the 7 main calibration points - add definitions if needed - CEN = 0, - __A = 1, - _AB = __A + _7P_STEP, - __B = _AB + _7P_STEP, - _BC = __B + _7P_STEP, - __C = _BC + _7P_STEP, - _CA = __C + _7P_STEP, -}; - -#define LOOP_CAL_PT(VAR, S, N) for (uint8_t VAR=S; VAR<=NPP; VAR+=N) -#define F_LOOP_CAL_PT(VAR, S, N) for (float VAR=S; VARCEN+0.9999; VAR-=N) -#define LOOP_CAL_ALL(VAR) LOOP_CAL_PT(VAR, CEN, 1) -#define LOOP_CAL_RAD(VAR) LOOP_CAL_PT(VAR, __A, _7P_STEP) -#define LOOP_CAL_ACT(VAR, _4P, _OP) LOOP_CAL_PT(VAR, _OP ? _AB : __A, _4P ? _4P_STEP : _7P_STEP) - -#if HAS_MULTI_HOTEND - const uint8_t old_tool_index = active_extruder; -#endif - -float lcd_probe_pt(const xy_pos_t &xy); - -void ac_home() { - endstops.enable(true); - TERN_(SENSORLESS_HOMING, endstops.set_homing_current(true)); - home_delta(); - TERN_(SENSORLESS_HOMING, endstops.set_homing_current(false)); - endstops.not_homing(); -} - -void ac_setup(const bool reset_bed) { - TERN_(HAS_MULTI_HOTEND, tool_change(0, true)); - - planner.synchronize(); - remember_feedrate_scaling_off(); - - #if HAS_LEVELING - if (reset_bed) reset_bed_level(); // After full calibration bed-level data is no longer valid - #endif -} - -void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) { - TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height)); - TERN_(HAS_BED_PROBE, probe.stow()); - restore_feedrate_and_scaling(); - TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, true)); -} - -void print_signed_float(FSTR_P const prefix, const_float_t f) { - SERIAL_ECHOPGM(" "); - SERIAL_ECHOF(prefix, AS_CHAR(':')); - serial_offset(f); -} - -/** - * - Print the delta settings - */ -static void print_calibration_settings(const bool end_stops, const bool tower_angles) { - SERIAL_ECHOPGM(".Height:", delta_height); - if (end_stops) { - print_signed_float(F("Ex"), delta_endstop_adj.a); - print_signed_float(F("Ey"), delta_endstop_adj.b); - print_signed_float(F("Ez"), delta_endstop_adj.c); - } - if (end_stops && tower_angles) { - SERIAL_ECHOLNPGM(" Radius:", delta_radius); - SERIAL_CHAR('.'); - SERIAL_ECHO_SP(13); - } - if (tower_angles) { - print_signed_float(F("Tx"), delta_tower_angle_trim.a); - print_signed_float(F("Ty"), delta_tower_angle_trim.b); - print_signed_float(F("Tz"), delta_tower_angle_trim.c); - } - if (end_stops != tower_angles) - SERIAL_ECHOPGM(" Radius:", delta_radius); - - SERIAL_EOL(); -} - -/** - * - Print the probe results - */ -static void print_calibration_results(const float z_pt[NPP + 1], const bool tower_points, const bool opposite_points) { - SERIAL_ECHOPGM(". "); - print_signed_float(F("c"), z_pt[CEN]); - if (tower_points) { - print_signed_float(F(" x"), z_pt[__A]); - print_signed_float(F(" y"), z_pt[__B]); - print_signed_float(F(" z"), z_pt[__C]); - } - if (tower_points && opposite_points) { - SERIAL_EOL(); - SERIAL_CHAR('.'); - SERIAL_ECHO_SP(13); - } - if (opposite_points) { - print_signed_float(F("yz"), z_pt[_BC]); - print_signed_float(F("zx"), z_pt[_CA]); - print_signed_float(F("xy"), z_pt[_AB]); - } - SERIAL_EOL(); -} - -/** - * - Calculate the standard deviation from the zero plane - */ -static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool _1p_cal, const bool _4p_cal, const bool _4p_opp) { - if (!_0p_cal) { - float S2 = sq(z_pt[CEN]); - int16_t N = 1; - if (!_1p_cal) { // std dev from zero plane - LOOP_CAL_ACT(rad, _4p_cal, _4p_opp) { - S2 += sq(z_pt[rad]); - N++; - } - return LROUND(SQRT(S2 / N) * 1000.0f) / 1000.0f + 0.00001f; - } - } - return 0.00001f; -} - -/** - * - Probe a point - */ -static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool probe_at_offset) { - #if HAS_BED_PROBE - return probe.probe_at_point(xy, stow ? PROBE_PT_STOW : PROBE_PT_RAISE, 0, probe_at_offset, false); - #else - UNUSED(stow); - return lcd_probe_pt(xy); - #endif -} - -/** - * - Probe a grid - */ -static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const float dcr, const bool towers_set, const bool stow_after_each, const bool probe_at_offset) { - const bool _0p_calibration = probe_points == 0, - _1p_calibration = probe_points == 1 || probe_points == -1, - _4p_calibration = probe_points == 2, - _4p_opposite_points = _4p_calibration && !towers_set, - _7p_calibration = probe_points >= 3, - _7p_no_intermediates = probe_points == 3, - _7p_1_intermediates = probe_points == 4, - _7p_2_intermediates = probe_points == 5, - _7p_4_intermediates = probe_points == 6, - _7p_6_intermediates = probe_points == 7, - _7p_8_intermediates = probe_points == 8, - _7p_11_intermediates = probe_points == 9, - _7p_14_intermediates = probe_points == 10, - _7p_intermed_points = probe_points >= 4, - _7p_6_center = probe_points >= 5 && probe_points <= 7, - _7p_9_center = probe_points >= 8; - - LOOP_CAL_ALL(rad) z_pt[rad] = 0.0f; - - if (!_0p_calibration) { - - if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center - const xy_pos_t center{0}; - z_pt[CEN] += calibration_probe(center, stow_after_each, probe_at_offset); - if (isnan(z_pt[CEN])) return false; - } - - if (_7p_calibration) { // probe extra center points - const float start = _7p_9_center ? float(_CA) + _7P_STEP / 3.0f : _7p_6_center ? float(_CA) : float(__C), - steps = _7p_9_center ? _4P_STEP / 3.0f : _7p_6_center ? _7P_STEP : _4P_STEP; - I_LOOP_CAL_PT(rad, start, steps) { - const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), - r = dcr * 0.1; - const xy_pos_t vec = { cos(a), sin(a) }; - z_pt[CEN] += calibration_probe(vec * r, stow_after_each, probe_at_offset); - if (isnan(z_pt[CEN])) return false; - } - z_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points); - } - - if (!_1p_calibration) { // probe the radius - const CalEnum start = _4p_opposite_points ? _AB : __A; - const float steps = _7p_14_intermediates ? _7P_STEP / 15.0f : // 15r * 6 + 10c = 100 - _7p_11_intermediates ? _7P_STEP / 12.0f : // 12r * 6 + 9c = 81 - _7p_8_intermediates ? _7P_STEP / 9.0f : // 9r * 6 + 10c = 64 - _7p_6_intermediates ? _7P_STEP / 7.0f : // 7r * 6 + 7c = 49 - _7p_4_intermediates ? _7P_STEP / 5.0f : // 5r * 6 + 6c = 36 - _7p_2_intermediates ? _7P_STEP / 3.0f : // 3r * 6 + 7c = 25 - _7p_1_intermediates ? _7P_STEP / 2.0f : // 2r * 6 + 4c = 16 - _7p_no_intermediates ? _7P_STEP : // 1r * 6 + 3c = 9 - _4P_STEP; // .5r * 6 + 1c = 4 - bool zig_zag = true; - F_LOOP_CAL_PT(rad, start, _7p_9_center ? steps * 3 : steps) { - const int8_t offset = _7p_9_center ? 2 : 0; - for (int8_t circle = 0; circle <= offset; circle++) { - const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), - r = dcr * (1 - 0.1 * (zig_zag ? offset - circle : circle)), - interpol = FMOD(rad, 1); - const xy_pos_t vec = { cos(a), sin(a) }; - const float z_temp = calibration_probe(vec * r, stow_after_each, probe_at_offset); - if (isnan(z_temp)) return false; - // split probe point to neighbouring calibration points - z_pt[uint8_t(LROUND(rad - interpol + NPP - 1)) % NPP + 1] += z_temp * sq(cos(RADIANS(interpol * 90))); - z_pt[uint8_t(LROUND(rad - interpol)) % NPP + 1] += z_temp * sq(sin(RADIANS(interpol * 90))); - } - zig_zag = !zig_zag; - } - if (_7p_intermed_points) - LOOP_CAL_RAD(rad) - z_pt[rad] /= _7P_STEP / steps; - - do_blocking_move_to_xy(0.0f, 0.0f); - } - } - return true; -} - -/** - * kinematics routines and auto tune matrix scaling parameters: - * see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for - * - formulae for approximative forward kinematics in the end-stop displacement matrix - * - definition of the matrix scaling parameters - */ -static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1], const float dcr) { - xyz_pos_t pos{0}; - - LOOP_CAL_ALL(rad) { - const float a = RADIANS(210 + (360 / NPP) * (rad - 1)), - r = (rad == CEN ? 0.0f : dcr); - pos.set(cos(a) * r, sin(a) * r, z_pt[rad]); - inverse_kinematics(pos); - mm_at_pt_axis[rad] = delta; - } -} - -static void forward_kinematics_probe_points(abc_float_t mm_at_pt_axis[NPP + 1], float z_pt[NPP + 1], const float dcr) { - const float r_quot = dcr / delta_radius; - - #define ZPP(N,I,A) (((1.0f + r_quot * (N)) / 3.0f) * mm_at_pt_axis[I].A) - #define Z00(I, A) ZPP( 0, I, A) - #define Zp1(I, A) ZPP(+1, I, A) - #define Zm1(I, A) ZPP(-1, I, A) - #define Zp2(I, A) ZPP(+2, I, A) - #define Zm2(I, A) ZPP(-2, I, A) - - z_pt[CEN] = Z00(CEN, a) + Z00(CEN, b) + Z00(CEN, c); - z_pt[__A] = Zp2(__A, a) + Zm1(__A, b) + Zm1(__A, c); - z_pt[__B] = Zm1(__B, a) + Zp2(__B, b) + Zm1(__B, c); - z_pt[__C] = Zm1(__C, a) + Zm1(__C, b) + Zp2(__C, c); - z_pt[_BC] = Zm2(_BC, a) + Zp1(_BC, b) + Zp1(_BC, c); - z_pt[_CA] = Zp1(_CA, a) + Zm2(_CA, b) + Zp1(_CA, c); - z_pt[_AB] = Zp1(_AB, a) + Zp1(_AB, b) + Zm2(_AB, c); -} - -static void calc_kinematics_diff_probe_points(float z_pt[NPP + 1], const float dcr, abc_float_t delta_e, const float delta_r, abc_float_t delta_t) { - const float z_center = z_pt[CEN]; - abc_float_t diff_mm_at_pt_axis[NPP + 1], new_mm_at_pt_axis[NPP + 1]; - - reverse_kinematics_probe_points(z_pt, diff_mm_at_pt_axis, dcr); - - delta_radius += delta_r; - delta_tower_angle_trim += delta_t; - recalc_delta_settings(); - reverse_kinematics_probe_points(z_pt, new_mm_at_pt_axis, dcr); - - LOOP_CAL_ALL(rad) diff_mm_at_pt_axis[rad] -= new_mm_at_pt_axis[rad] + delta_e; - forward_kinematics_probe_points(diff_mm_at_pt_axis, z_pt, dcr); - - LOOP_CAL_RAD(rad) z_pt[rad] -= z_pt[CEN] - z_center; - z_pt[CEN] = z_center; - - delta_radius -= delta_r; - delta_tower_angle_trim -= delta_t; - recalc_delta_settings(); -} - -static float auto_tune_h(const float dcr) { - const float r_quot = dcr / delta_radius; - return RECIPROCAL(r_quot / (2.0f / 3.0f)); // (2/3)/CR -} - -static float auto_tune_r(const float dcr) { - constexpr float diff = 0.01f, delta_r = diff; - float r_fac = 0.0f, z_pt[NPP + 1] = { 0.0f }; - abc_float_t delta_e = { 0.0f }, delta_t = { 0.0f }; - - calc_kinematics_diff_probe_points(z_pt, dcr, delta_e, delta_r, delta_t); - r_fac = -(z_pt[__A] + z_pt[__B] + z_pt[__C] + z_pt[_BC] + z_pt[_CA] + z_pt[_AB]) / 6.0f; - r_fac = diff / r_fac / 3.0f; // 1/(3*delta_Z) - return r_fac; -} - -static float auto_tune_a(const float dcr) { - constexpr float diff = 0.01f, delta_r = 0.0f; - float a_fac = 0.0f, z_pt[NPP + 1] = { 0.0f }; - abc_float_t delta_e = { 0.0f }, delta_t = { 0.0f }; - - delta_t.reset(); - LOOP_NUM_AXES(axis) { - delta_t[axis] = diff; - calc_kinematics_diff_probe_points(z_pt, dcr, delta_e, delta_r, delta_t); - delta_t[axis] = 0; - a_fac += z_pt[uint8_t((axis * _4P_STEP) - _7P_STEP + NPP) % NPP + 1] / 6.0f; - a_fac -= z_pt[uint8_t((axis * _4P_STEP) + 1 + _7P_STEP)] / 6.0f; - } - a_fac = diff / a_fac / 3.0f; // 1/(3*delta_Z) - return a_fac; -} - -/** - * G33 - Delta '1-4-7-point' Auto-Calibration - * Calibrate height, z_offset, endstops, delta radius, and tower angles. - * - * Parameters: - * - * Pn Number of probe points: - * P0 Normalizes calibration. - * P1 Calibrates height only with center probe. - * P2 Probe center and towers. Calibrate height, endstops and delta radius. - * P3 Probe all positions: center, towers and opposite towers. Calibrate all. - * P4-P10 Probe all positions at different intermediate locations and average them. - * - * Rn.nn Temporary reduce the probe grid by the specified amount (mm) - * - * T 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 take the best result - * - * Vn Verbose level: - * V0 Dry-run mode. Report settings and probe results. No calibration. - * V1 Report start and end settings only - * V2 Report settings at each iteration - * V3 Report settings and probe results - * - * E Engage the probe for each point - * - * O Probe at offsetted probe positions (this is wrong but it seems to work) - * - * With SENSORLESS_PROBING: - * Use these flags to calibrate stall sensitivity: (e.g., `G33 P1 Y Z` to calibrate X only.) - * X Don't activate stallguard on X. - * Y Don't activate stallguard on Y. - * Z Don't activate stallguard on Z. - * - * S Save offset_sensorless_adj - */ -void GcodeSuite::G33() { - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE)); - - const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS); - if (!WITHIN(probe_points, 0, 10)) { - SERIAL_ECHOLNPGM("?(P)oints implausible (0-10)."); - return; - } - - const bool probe_at_offset = TERN0(HAS_PROBE_XY_OFFSET, parser.seen_test('O')), - towers_set = !parser.seen_test('T'); - - // The calibration radius is set to a calculated value - float dcr = probe_at_offset ? DELTA_PRINTABLE_RADIUS : DELTA_PRINTABLE_RADIUS - PROBING_MARGIN; - #if HAS_PROBE_XY_OFFSET - const float total_offset = HYPOT(probe.offset_xy.x, probe.offset_xy.y); - dcr -= probe_at_offset ? _MAX(total_offset, PROBING_MARGIN) : total_offset; - #endif - NOMORE(dcr, DELTA_PRINTABLE_RADIUS); - if (parser.seenval('R')) dcr -= _MAX(parser.value_float(), 0.0f); - TERN_(HAS_DELTA_SENSORLESS_PROBING, dcr *= sensorless_radius_factor); - - const float calibration_precision = parser.floatval('C', 0.0f); - if (calibration_precision < 0) { - SERIAL_ECHOLNPGM("?(C)alibration precision implausible (>=0)."); - return; - } - - const int8_t force_iterations = parser.intval('F', 0); - if (!WITHIN(force_iterations, 0, 30)) { - SERIAL_ECHOLNPGM("?(F)orce iteration implausible (0-30)."); - return; - } - - const int8_t verbose_level = parser.byteval('V', 1); - if (!WITHIN(verbose_level, 0, 3)) { - SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-3)."); - return; - } - - const bool stow_after_each = parser.seen_test('E'); - - #if HAS_DELTA_SENSORLESS_PROBING - probe.test_sensitivity = { !parser.seen_test('X'), !parser.seen_test('Y'), !parser.seen_test('Z') }; - const bool do_save_offset_adj = parser.seen_test('S'); - #endif - - const bool _0p_calibration = probe_points == 0, - _1p_calibration = probe_points == 1 || probe_points == -1, - _4p_calibration = probe_points == 2, - _4p_opposite_points = _4p_calibration && !towers_set, - _7p_9_center = probe_points >= 8, - _tower_results = (_4p_calibration && towers_set) || probe_points >= 3, - _opposite_results = (_4p_calibration && !towers_set) || probe_points >= 3, - _endstop_results = probe_points != 1 && probe_points != -1 && probe_points != 0, - _angle_results = probe_points >= 3 && towers_set; - int8_t iterations = 0; - float test_precision, - zero_std_dev = (verbose_level ? 999.0f : 0.0f), // 0.0 in dry-run mode : forced end - zero_std_dev_min = zero_std_dev, - zero_std_dev_old = zero_std_dev, - h_factor, r_factor, a_factor, - r_old = delta_radius, - h_old = delta_height; - - abc_pos_t e_old = delta_endstop_adj, a_old = delta_tower_angle_trim; - - SERIAL_ECHOLNPGM("G33 Auto Calibrate"); - - // Report settings - PGM_P const checkingac = PSTR("Checking... AC"); - SERIAL_ECHOPGM_P(checkingac); - SERIAL_ECHOPGM(" at radius:", dcr); - if (verbose_level == 0) SERIAL_ECHOPGM(" (DRY-RUN)"); - SERIAL_EOL(); - ui.set_status(checkingac); - - print_calibration_settings(_endstop_results, _angle_results); - - ac_setup(!_0p_calibration && !_1p_calibration); - - if (!_0p_calibration) ac_home(); - - #if HAS_DELTA_SENSORLESS_PROBING - if (verbose_level > 0 && do_save_offset_adj) { - offset_sensorless_adj.reset(); - - auto caltower = [&](Probe::sense_bool_t s){ - float z_at_pt[NPP + 1]; - LOOP_CAL_ALL(rad) z_at_pt[rad] = 0.0f; - probe.test_sensitivity = s; - if (probe_calibration_points(z_at_pt, 1, dcr, false, false, probe_at_offset)) - probe.set_offset_sensorless_adj(z_at_pt[CEN]); - }; - caltower({ true, false, false }); // A - caltower({ false, true, false }); // B - caltower({ false, false, true }); // C - - probe.test_sensitivity = { true, true, true }; // reset to all - } - #endif - - do { // start iterations - - float z_at_pt[NPP + 1] = { 0.0f }; - - test_precision = zero_std_dev_old != 999.0f ? (zero_std_dev + zero_std_dev_old) / 2.0f : zero_std_dev; - iterations++; - - // Probe the points - zero_std_dev_old = zero_std_dev; - if (!probe_calibration_points(z_at_pt, probe_points, dcr, towers_set, stow_after_each, probe_at_offset)) { - SERIAL_ECHOLNPGM("Correct delta settings with M665 and M666"); - return ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index)); - } - zero_std_dev = std_dev_points(z_at_pt, _0p_calibration, _1p_calibration, _4p_calibration, _4p_opposite_points); - - // Solve matrices - - if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) { - - #if !HAS_BED_PROBE - test_precision = 0.0f; // forced end - #endif - - if (zero_std_dev < zero_std_dev_min) { - // set roll-back point - e_old = delta_endstop_adj; - r_old = delta_radius; - h_old = delta_height; - a_old = delta_tower_angle_trim; - } - - abc_float_t e_delta = { 0.0f }, t_delta = { 0.0f }; - float r_delta = 0.0f; - - /** - * convergence matrices: - * see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for - * - definition of the matrix scaling parameters - * - matrices for 4 and 7 point calibration - */ - #define ZP(N,I) ((N) * z_at_pt[I] / 4.0f) // 4.0 = divider to normalize to integers - #define Z12(I) ZP(12, I) - #define Z4(I) ZP(4, I) - #define Z2(I) ZP(2, I) - #define Z1(I) ZP(1, I) - #define Z0(I) ZP(0, I) - - // calculate factors - if (_7p_9_center) dcr *= 0.9f; - h_factor = auto_tune_h(dcr); - r_factor = auto_tune_r(dcr); - a_factor = auto_tune_a(dcr); - if (_7p_9_center) dcr /= 0.9f; - - switch (probe_points) { - case 0: - test_precision = 0.0f; // forced end - break; - - case 1: - test_precision = 0.0f; // forced end - LOOP_NUM_AXES(axis) e_delta[axis] = +Z4(CEN); - break; - - case 2: - if (towers_set) { // see 4 point calibration (towers) matrix - e_delta.set((+Z4(__A) -Z2(__B) -Z2(__C)) * h_factor +Z4(CEN), - (-Z2(__A) +Z4(__B) -Z2(__C)) * h_factor +Z4(CEN), - (-Z2(__A) -Z2(__B) +Z4(__C)) * h_factor +Z4(CEN)); - r_delta = (+Z4(__A) +Z4(__B) +Z4(__C) -Z12(CEN)) * r_factor; - } - else { // see 4 point calibration (opposites) matrix - e_delta.set((-Z4(_BC) +Z2(_CA) +Z2(_AB)) * h_factor +Z4(CEN), - (+Z2(_BC) -Z4(_CA) +Z2(_AB)) * h_factor +Z4(CEN), - (+Z2(_BC) +Z2(_CA) -Z4(_AB)) * h_factor +Z4(CEN)); - r_delta = (+Z4(_BC) +Z4(_CA) +Z4(_AB) -Z12(CEN)) * r_factor; - } - break; - - default: // see 7 point calibration (towers & opposites) matrix - e_delta.set((+Z2(__A) -Z1(__B) -Z1(__C) -Z2(_BC) +Z1(_CA) +Z1(_AB)) * h_factor +Z4(CEN), - (-Z1(__A) +Z2(__B) -Z1(__C) +Z1(_BC) -Z2(_CA) +Z1(_AB)) * h_factor +Z4(CEN), - (-Z1(__A) -Z1(__B) +Z2(__C) +Z1(_BC) +Z1(_CA) -Z2(_AB)) * h_factor +Z4(CEN)); - r_delta = (+Z2(__A) +Z2(__B) +Z2(__C) +Z2(_BC) +Z2(_CA) +Z2(_AB) -Z12(CEN)) * r_factor; - - if (towers_set) { // see 7 point tower angle calibration (towers & opposites) matrix - t_delta.set((+Z0(__A) -Z4(__B) +Z4(__C) +Z0(_BC) -Z4(_CA) +Z4(_AB) +Z0(CEN)) * a_factor, - (+Z4(__A) +Z0(__B) -Z4(__C) +Z4(_BC) +Z0(_CA) -Z4(_AB) +Z0(CEN)) * a_factor, - (-Z4(__A) +Z4(__B) +Z0(__C) -Z4(_BC) +Z4(_CA) +Z0(_AB) +Z0(CEN)) * a_factor); - } - break; - } - delta_endstop_adj += e_delta; - delta_radius += r_delta; - delta_tower_angle_trim += t_delta; - } - else if (zero_std_dev >= test_precision) { - // roll back - delta_endstop_adj = e_old; - delta_radius = r_old; - delta_height = h_old; - delta_tower_angle_trim = a_old; - } - - if (verbose_level != 0) { // !dry run - - // Normalize angles to least-squares - if (_angle_results) { - float a_sum = 0.0f; - LOOP_NUM_AXES(axis) a_sum += delta_tower_angle_trim[axis]; - LOOP_NUM_AXES(axis) delta_tower_angle_trim[axis] -= a_sum / 3.0f; - } - - // adjust delta_height and endstops by the max amount - const float z_temp = _MAX(delta_endstop_adj.a, delta_endstop_adj.b, delta_endstop_adj.c); - delta_height -= z_temp; - LOOP_NUM_AXES(axis) delta_endstop_adj[axis] -= z_temp; - } - recalc_delta_settings(); - NOMORE(zero_std_dev_min, zero_std_dev); - - // print report - - if (verbose_level == 3 || verbose_level == 0) { - print_calibration_results(z_at_pt, _tower_results, _opposite_results); - #if HAS_DELTA_SENSORLESS_PROBING - if (verbose_level == 0 && probe_points == 1) { - if (do_save_offset_adj) - probe.set_offset_sensorless_adj(z_at_pt[CEN]); - else - probe.refresh_largest_sensorless_adj(); - } - #endif - } - - if (verbose_level != 0) { // !dry run - if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations - SERIAL_ECHOPGM("Calibration OK"); - SERIAL_ECHO_SP(32); - #if HAS_BED_PROBE - if (zero_std_dev >= test_precision && !_1p_calibration && !_0p_calibration) - SERIAL_ECHOPGM("rolling back."); - else - #endif - { - SERIAL_ECHOPAIR_F("std dev:", zero_std_dev_min, 3); - } - SERIAL_EOL(); - char mess[21]; - strcpy_P(mess, PSTR("Calibration sd:")); - if (zero_std_dev_min < 1) - sprintf_P(&mess[15], PSTR("0.%03i"), (int)LROUND(zero_std_dev_min * 1000.0f)); - else - sprintf_P(&mess[15], PSTR("%03i.x"), (int)LROUND(zero_std_dev_min)); - ui.set_status(mess); - print_calibration_settings(_endstop_results, _angle_results); - SERIAL_ECHOLNPGM("Save with M500 and/or copy to Configuration.h"); - } - else { // !end iterations - char mess[15]; - if (iterations < 31) - sprintf_P(mess, PSTR("Iteration : %02i"), (unsigned int)iterations); - else - strcpy_P(mess, PSTR("No convergence")); - SERIAL_ECHO(mess); - SERIAL_ECHO_SP(32); - SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3); - ui.set_status(mess); - if (verbose_level > 1) - print_calibration_settings(_endstop_results, _angle_results); - } - } - else { // dry run - FSTR_P const enddryrun = F("End DRY-RUN"); - SERIAL_ECHOF(enddryrun); - SERIAL_ECHO_SP(35); - SERIAL_ECHOLNPAIR_F("std dev:", zero_std_dev, 3); - - char mess[21]; - strcpy_P(mess, FTOP(enddryrun)); - strcpy_P(&mess[11], PSTR(" sd:")); - if (zero_std_dev < 1) - sprintf_P(&mess[15], PSTR("0.%03i"), (int)LROUND(zero_std_dev * 1000.0f)); - else - sprintf_P(&mess[15], PSTR("%03i.x"), (int)LROUND(zero_std_dev)); - ui.set_status(mess); - } - ac_home(); - } - while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision); - - ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index)); - - TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE)); - #if HAS_DELTA_SENSORLESS_PROBING - probe.test_sensitivity = { true, true, true }; - #endif -} - -#endif // DELTA_AUTO_CALIBRATION diff --git a/src/gcode/calibrate/G34.cpp b/src/gcode/calibrate/G34.cpp deleted file mode 100644 index 1be3952..0000000 --- a/src/gcode/calibrate/G34.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(MECHANICAL_GANTRY_CALIBRATION) - -#include "../gcode.h" -#include "../../module/motion.h" -#include "../../module/endstops.h" - -#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_TRINAMIC_CONFIG) - #include "../../module/stepper.h" -#endif - -#if HAS_LEVELING - #include "../../feature/bedlevel/bedlevel.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -void GcodeSuite::G34() { - - // Home before the alignment procedure - home_if_needed(); - - TERN_(HAS_LEVELING, TEMPORARY_BED_LEVELING_STATE(false)); - - SET_SOFT_ENDSTOP_LOOSE(true); - TemporaryGlobalEndstopsState unlock_z(false); - - #ifdef GANTRY_CALIBRATION_COMMANDS_PRE - process_subcommands_now(F(GANTRY_CALIBRATION_COMMANDS_PRE)); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Sub Commands Processed"); - #endif - - #ifdef GANTRY_CALIBRATION_SAFE_POSITION - // Move XY to safe position - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Parking XY"); - const xy_pos_t safe_pos = GANTRY_CALIBRATION_SAFE_POSITION; - do_blocking_move_to(safe_pos, MMM_TO_MMS(GANTRY_CALIBRATION_XY_PARK_FEEDRATE)); - #endif - - const float move_distance = parser.intval('Z', GANTRY_CALIBRATION_EXTRA_HEIGHT), - zbase = ENABLED(GANTRY_CALIBRATION_TO_MIN) ? Z_MIN_POS : Z_MAX_POS, - zpounce = zbase - move_distance, zgrind = zbase + move_distance; - - // Move Z to pounce position - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Setting Z Pounce"); - do_blocking_move_to_z(zpounce, homing_feedrate(Z_AXIS)); - - // Store current motor settings, then apply reduced value - - #define _REDUCE_CURRENT ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_DAC, HAS_MOTOR_CURRENT_I2C, HAS_TRINAMIC_CONFIG) - #if _REDUCE_CURRENT - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Reducing Current"); - #endif - - #if HAS_MOTOR_CURRENT_SPI - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - const uint32_t previous_current = stepper.motor_current_setting[Z_AXIS]; - stepper.set_digipot_current(Z_AXIS, target_current); - #elif HAS_MOTOR_CURRENT_PWM - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - const uint32_t previous_current = stepper.motor_current_setting[1]; // Z - stepper.set_digipot_current(1, target_current); - #elif HAS_MOTOR_CURRENT_DAC - const float target_current = parser.floatval('S', GANTRY_CALIBRATION_CURRENT); - const float previous_current = dac_amps(Z_AXIS, target_current); - stepper_dac.set_current_value(Z_AXIS, target_current); - #elif HAS_MOTOR_CURRENT_I2C - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - previous_current = dac_amps(Z_AXIS); - digipot_i2c.set_current(Z_AXIS, target_current) - #elif HAS_TRINAMIC_CONFIG - const uint16_t target_current = parser.intval('S', GANTRY_CALIBRATION_CURRENT); - static uint16_t previous_current_arr[NUM_Z_STEPPERS]; - #if AXIS_IS_TMC(Z) - previous_current_arr[0] = stepperZ.getMilliamps(); - stepperZ.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z2) - previous_current_arr[1] = stepperZ2.getMilliamps(); - stepperZ2.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z3) - previous_current_arr[2] = stepperZ3.getMilliamps(); - stepperZ3.rms_current(target_current); - #endif - #if AXIS_IS_TMC(Z4) - previous_current_arr[3] = stepperZ4.getMilliamps(); - stepperZ4.rms_current(target_current); - #endif - #endif - - // Do Final Z move to adjust - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Final Z Move"); - do_blocking_move_to_z(zgrind, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); - - #if _REDUCE_CURRENT - // Reset current to original values - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore Current"); - #endif - - #if HAS_MOTOR_CURRENT_SPI - stepper.set_digipot_current(Z_AXIS, previous_current); - #elif HAS_MOTOR_CURRENT_PWM - stepper.set_digipot_current(1, previous_current); - #elif HAS_MOTOR_CURRENT_DAC - stepper_dac.set_current_value(Z_AXIS, previous_current); - #elif HAS_MOTOR_CURRENT_I2C - digipot_i2c.set_current(Z_AXIS, previous_current) - #elif HAS_TRINAMIC_CONFIG - #if AXIS_IS_TMC(Z) - stepperZ.rms_current(previous_current_arr[0]); - #endif - #if AXIS_IS_TMC(Z2) - stepperZ2.rms_current(previous_current_arr[1]); - #endif - #if AXIS_IS_TMC(Z3) - stepperZ3.rms_current(previous_current_arr[2]); - #endif - #if AXIS_IS_TMC(Z4) - stepperZ4.rms_current(previous_current_arr[3]); - #endif - #endif - - // Back off end plate, back to normal motion range - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Z Backoff"); - do_blocking_move_to_z(zpounce, MMM_TO_MMS(GANTRY_CALIBRATION_FEEDRATE)); - - #ifdef GANTRY_CALIBRATION_COMMANDS_POST - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Running Post Commands"); - process_subcommands_now(F(GANTRY_CALIBRATION_COMMANDS_POST)); - #endif - - SET_SOFT_ENDSTOP_LOOSE(false); -} - -#endif // MECHANICAL_GANTRY_CALIBRATION diff --git a/src/gcode/calibrate/G34_M422.cpp b/src/gcode/calibrate/G34_M422.cpp deleted file mode 100644 index 8cf652c..0000000 --- a/src/gcode/calibrate/G34_M422.cpp +++ /dev/null @@ -1,569 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN) - -#include "../../feature/z_stepper_align.h" - -#include "../gcode.h" -#include "../../module/motion.h" -#include "../../module/stepper.h" -#include "../../module/planner.h" -#include "../../module/probe.h" -#include "../../lcd/marlinui.h" // for LCD_MESSAGE - -#if HAS_LEVELING - #include "../../feature/bedlevel/bedlevel.h" -#endif - -#if HAS_MULTI_HOTEND - #include "../../module/tool_change.h" -#endif - -#if HAS_Z_STEPPER_ALIGN_STEPPER_XY - #include "../../libs/least_squares_fit.h" -#endif - -#if ENABLED(BLTOUCH) - #include "../../feature/bltouch.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -#if NUM_Z_STEPPERS >= 3 - #define TRIPLE_Z 1 - #if NUM_Z_STEPPERS >= 4 - #define QUAD_Z 1 - #endif -#endif - -/** - * G34: Z-Stepper automatic alignment - * - * Manual stepper lock controls (reset by G28): - * L Unlock all steppers - * Z<1-4> Z stepper to lock / unlock - * S 0=UNLOCKED 1=LOCKED. If omitted, assume LOCKED. - * - * Examples: - * G34 Z1 ; Lock Z1 - * G34 L Z2 ; Unlock all, then lock Z2 - * G34 Z2 S0 ; Unlock Z2 - * - * With Z_STEPPER_AUTO_ALIGN: - * I Number of tests. If omitted, Z_STEPPER_ALIGN_ITERATIONS. - * T Target Accuracy factor. If omitted, Z_STEPPER_ALIGN_ACC. - * A Provide an Amplification value. If omitted, Z_STEPPER_ALIGN_AMP. - * R Flag to recalculate points based on current probe offsets - */ -void GcodeSuite::G34() { - DEBUG_SECTION(log_G34, "G34", DEBUGGING(LEVELING)); - if (DEBUGGING(LEVELING)) log_machine_info(); - - planner.synchronize(); // Prevent damage - - const bool seenL = parser.seen('L'); - if (seenL) stepper.set_all_z_lock(false); - - const bool seenZ = parser.seenval('Z'); - if (seenZ) { - const bool state = parser.boolval('S', true); - switch (parser.intval('Z')) { - case 1: stepper.set_z1_lock(state); break; - case 2: stepper.set_z2_lock(state); break; - #if TRIPLE_Z - case 3: stepper.set_z3_lock(state); break; - #if QUAD_Z - case 4: stepper.set_z4_lock(state); break; - #endif - #endif - } - } - - if (seenL || seenZ) { - stepper.set_separate_multi_axis(seenZ); - return; - } - - #if ENABLED(Z_STEPPER_AUTO_ALIGN) - do { // break out on error - - const int8_t z_auto_align_iterations = parser.intval('I', Z_STEPPER_ALIGN_ITERATIONS); - if (!WITHIN(z_auto_align_iterations, 1, 30)) { - SERIAL_ECHOLNPGM("?(I)teration out of bounds (1-30)."); - break; - } - - const float z_auto_align_accuracy = parser.floatval('T', Z_STEPPER_ALIGN_ACC); - if (!WITHIN(z_auto_align_accuracy, 0.01f, 1.0f)) { - SERIAL_ECHOLNPGM("?(T)arget accuracy out of bounds (0.01-1.0)."); - break; - } - - const float z_auto_align_amplification = TERN(HAS_Z_STEPPER_ALIGN_STEPPER_XY, Z_STEPPER_ALIGN_AMP, parser.floatval('A', Z_STEPPER_ALIGN_AMP)); - if (!WITHIN(ABS(z_auto_align_amplification), 0.5f, 2.0f)) { - SERIAL_ECHOLNPGM("?(A)mplification out of bounds (0.5-2.0)."); - break; - } - - if (parser.seen('R')) z_stepper_align.reset_to_default(); - - const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE; - - // Disable the leveling matrix before auto-aligning - #if HAS_LEVELING - #if ENABLED(RESTORE_LEVELING_AFTER_G34) - const bool leveling_was_active = planner.leveling_active; - #endif - set_bed_leveling_enabled(false); - #endif - - TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY); - - // Always home with tool 0 active - #if HAS_MULTI_HOTEND - const uint8_t old_tool_index = active_extruder; - tool_change(0, true); - #endif - - TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false)); - - // In BLTOUCH HS mode, the probe travels in a deployed state. - // Users of G34 might have a badly misaligned bed, so raise Z by the - // length of the deployed pin (BLTOUCH stroke < 7mm) - #define Z_BASIC_CLEARANCE (Z_CLEARANCE_BETWEEN_PROBES + TERN0(BLTOUCH, bltouch.z_extra_clearance())) - - // Compute a worst-case clearance height to probe from. After the first - // iteration this will be re-calculated based on the actual bed position - auto magnitude2 = [&](const uint8_t i, const uint8_t j) { - const xy_pos_t diff = z_stepper_align.xy[i] - z_stepper_align.xy[j]; - return HYPOT2(diff.x, diff.y); - }; - float z_probe = Z_BASIC_CLEARANCE + (G34_MAX_GRADE) * 0.01f * SQRT(_MAX(0, magnitude2(0, 1) - #if TRIPLE_Z - , magnitude2(2, 1), magnitude2(2, 0) - #if QUAD_Z - , magnitude2(3, 2), magnitude2(3, 1), magnitude2(3, 0) - #endif - #endif - )); - - // Home before the alignment procedure - home_if_needed(); - - // Move the Z coordinate realm towards the positive - dirty trick - current_position.z += z_probe * 0.5f; - sync_plan_position(); - // Now, the Z origin lies below the build plate. That allows to probe deeper, before run_z_probe throws an error. - // This hack is un-done at the end of G34 - either by re-homing, or by using the probed heights of the last iteration. - - #if !HAS_Z_STEPPER_ALIGN_STEPPER_XY - float last_z_align_move[NUM_Z_STEPPERS] = ARRAY_N_1(NUM_Z_STEPPERS, 10000.0f); - #else - float last_z_align_level_indicator = 10000.0f; - #endif - float z_measured[NUM_Z_STEPPERS] = { 0 }, - z_maxdiff = 0.0f, - amplification = z_auto_align_amplification; - - #if !HAS_Z_STEPPER_ALIGN_STEPPER_XY - bool adjustment_reverse = false; - #endif - - #if HAS_STATUS_MESSAGE - PGM_P const msg_iteration = GET_TEXT(MSG_ITERATION); - const uint8_t iter_str_len = strlen_P(msg_iteration); - #endif - - // Final z and iteration values will be used after breaking the loop - float z_measured_min; - uint8_t iteration = 0; - bool err_break = false; // To break out of nested loops - while (iteration < z_auto_align_iterations) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> probing all positions."); - - const int iter = iteration + 1; - SERIAL_ECHOLNPGM("\nG34 Iteration: ", iter); - #if HAS_STATUS_MESSAGE - char str[iter_str_len + 2 + 1]; - sprintf_P(str, msg_iteration, iter); - ui.set_status(str); - #endif - - // Initialize minimum value - z_measured_min = 100000.0f; - float z_measured_max = -100000.0f; - - // Probe all positions (one per Z-Stepper) - LOOP_L_N(i, NUM_Z_STEPPERS) { - // iteration odd/even --> downward / upward stepper sequence - const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPERS - 1 - i : i; - - // Safe clearance even on an incline - if ((iteration == 0 || i > 0) && z_probe > current_position.z) do_blocking_move_to_z(z_probe); - - xy_pos_t &ppos = z_stepper_align.xy[iprobe]; - - if (DEBUGGING(LEVELING)) - DEBUG_ECHOLNPGM_P(PSTR("Probing X"), ppos.x, SP_Y_STR, ppos.y); - - // Probe a Z height for each stepper. - // Probing sanity check is disabled, as it would trigger even in normal cases because - // current_position.z has been manually altered in the "dirty trick" above. - const float z_probed_height = probe.probe_at_point(DIFF_TERN(HAS_HOME_OFFSET, ppos, xy_pos_t(home_offset)), raise_after, 0, true, false); - if (isnan(z_probed_height)) { - SERIAL_ECHOLNPGM("Probing failed"); - LCD_MESSAGE(MSG_LCD_PROBING_FAILED); - err_break = true; - break; - } - - // Add height to each value, to provide a more useful target height for - // the next iteration of probing. This allows adjustments to be made away from the bed. - z_measured[iprobe] = z_probed_height + Z_CLEARANCE_BETWEEN_PROBES; - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", iprobe + 1, " measured position is ", z_measured[iprobe]); - - // Remember the minimum measurement to calculate the correction later on - z_measured_min = _MIN(z_measured_min, z_measured[iprobe]); - z_measured_max = _MAX(z_measured_max, z_measured[iprobe]); - } // for (i) - - if (err_break) break; - - // Adapt the next probe clearance height based on the new measurements. - // Safe_height = lowest distance to bed (= highest measurement) plus highest measured misalignment. - z_maxdiff = z_measured_max - z_measured_min; - z_probe = Z_BASIC_CLEARANCE + z_measured_max + z_maxdiff; - - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - // Replace the initial values in z_measured with calculated heights at - // each stepper position. This allows the adjustment algorithm to be - // shared between both possible probing mechanisms. - - // This must be done after the next z_probe height is calculated, so that - // the height is calculated from actual print area positions, and not - // extrapolated motor movements. - - // Compute the least-squares fit for all probed points. - // Calculate the Z position of each stepper and store it in z_measured. - // This allows the actual adjustment logic to be shared by both algorithms. - linear_fit_data lfd; - incremental_LSF_reset(&lfd); - LOOP_L_N(i, NUM_Z_STEPPERS) { - SERIAL_ECHOLNPGM("PROBEPT_", i, ": ", z_measured[i]); - incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]); - } - finish_incremental_LSF(&lfd); - - z_measured_min = 100000.0f; - LOOP_L_N(i, NUM_Z_STEPPERS) { - z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y + lfd.D); - z_measured_min = _MIN(z_measured_min, z_measured[i]); - } - - SERIAL_ECHOLNPGM( - LIST_N(DOUBLE(NUM_Z_STEPPERS), - "Calculated Z1=", z_measured[0], - " Z2=", z_measured[1], - " Z3=", z_measured[2], - " Z4=", z_measured[3] - ) - ); - #endif - - SERIAL_ECHOLNPGM("\n" - "Z2-Z1=", ABS(z_measured[1] - z_measured[0]) - #if TRIPLE_Z - , " Z3-Z2=", ABS(z_measured[2] - z_measured[1]) - , " Z3-Z1=", ABS(z_measured[2] - z_measured[0]) - #if QUAD_Z - , " Z4-Z3=", ABS(z_measured[3] - z_measured[2]) - , " Z4-Z2=", ABS(z_measured[3] - z_measured[1]) - , " Z4-Z1=", ABS(z_measured[3] - z_measured[0]) - #endif - #endif - ); - - #if HAS_STATUS_MESSAGE - char fstr1[10]; - char msg[6 + (6 + 5) * NUM_Z_STEPPERS + 1] - #if TRIPLE_Z - , fstr2[10], fstr3[10] - #if QUAD_Z - , fstr4[10], fstr5[10], fstr6[10] - #endif - #endif - ; - sprintf_P(msg, - PSTR("1:2=%s" TERN_(TRIPLE_Z, " 3-2=%s 3-1=%s") TERN_(QUAD_Z, " 4-3=%s 4-2=%s 4-1=%s")), - dtostrf(ABS(z_measured[1] - z_measured[0]), 1, 3, fstr1) - OPTARG(TRIPLE_Z, - dtostrf(ABS(z_measured[2] - z_measured[1]), 1, 3, fstr2), - dtostrf(ABS(z_measured[2] - z_measured[0]), 1, 3, fstr3)) - OPTARG(QUAD_Z, - dtostrf(ABS(z_measured[3] - z_measured[2]), 1, 3, fstr4), - dtostrf(ABS(z_measured[3] - z_measured[1]), 1, 3, fstr5), - dtostrf(ABS(z_measured[3] - z_measured[0]), 1, 3, fstr6)) - ); - ui.set_status(msg); - #endif - - auto decreasing_accuracy = [](const_float_t v1, const_float_t v2) { - if (v1 < v2 * 0.7f) { - SERIAL_ECHOLNPGM("Decreasing Accuracy Detected."); - LCD_MESSAGE(MSG_DECREASING_ACCURACY); - return true; - } - return false; - }; - - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - // Check if the applied corrections go in the correct direction. - // Calculate the sum of the absolute deviations from the mean of the probe measurements. - // Compare to the last iteration to ensure it's getting better. - - // Calculate mean value as a reference - float z_measured_mean = 0.0f; - LOOP_L_N(zstepper, NUM_Z_STEPPERS) z_measured_mean += z_measured[zstepper]; - z_measured_mean /= NUM_Z_STEPPERS; - - // Calculate the sum of the absolute deviations from the mean value - float z_align_level_indicator = 0.0f; - LOOP_L_N(zstepper, NUM_Z_STEPPERS) - z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean); - - // If it's getting worse, stop and throw an error - err_break = decreasing_accuracy(last_z_align_level_indicator, z_align_level_indicator); - if (err_break) break; - - last_z_align_level_indicator = z_align_level_indicator; - #endif - - // The following correction actions are to be enabled for select Z-steppers only - stepper.set_separate_multi_axis(true); - - bool success_break = true; - // Correct the individual stepper offsets - LOOP_L_N(zstepper, NUM_Z_STEPPERS) { - // Calculate current stepper move - float z_align_move = z_measured[zstepper] - z_measured_min; - const float z_align_abs = ABS(z_align_move); - - #if !HAS_Z_STEPPER_ALIGN_STEPPER_XY - // Optimize one iteration's correction based on the first measurements - if (z_align_abs) amplification = (iteration == 1) ? _MIN(last_z_align_move[zstepper] / z_align_abs, 2.0f) : z_auto_align_amplification; - - // Check for less accuracy compared to last move - if (decreasing_accuracy(last_z_align_move[zstepper], z_align_abs)) { - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " last_z_align_move = ", last_z_align_move[zstepper]); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " z_align_abs = ", z_align_abs); - adjustment_reverse = !adjustment_reverse; - } - - // Remember the alignment for the next iteration, but only if steppers move, - // otherwise it would be just zero (in case this stepper was at z_measured_min already) - if (z_align_abs > 0) last_z_align_move[zstepper] = z_align_abs; - #endif - - // Stop early if all measured points achieve accuracy target - if (z_align_abs > z_auto_align_accuracy) success_break = false; - - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " corrected by ", z_align_move); - - // Lock all steppers except one - stepper.set_all_z_lock(true, zstepper); - - #if !HAS_Z_STEPPER_ALIGN_STEPPER_XY - // Decreasing accuracy was detected so move was inverted. - // Will match reversed Z steppers on dual steppers. Triple will need more work to map. - if (adjustment_reverse) { - z_align_move = -z_align_move; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", zstepper + 1, " correction reversed to ", z_align_move); - } - #endif - - // Do a move to correct part of the misalignment for the current stepper - do_blocking_move_to_z(amplification * z_align_move + current_position.z); - } // for (zstepper) - - // Back to normal stepper operations - stepper.set_all_z_lock(false); - stepper.set_separate_multi_axis(false); - - if (err_break) break; - - if (success_break) { - SERIAL_ECHOLNPGM("Target accuracy achieved."); - LCD_MESSAGE(MSG_ACCURACY_ACHIEVED); - break; - } - - iteration++; - } // while (iteration < z_auto_align_iterations) - - if (err_break) - SERIAL_ECHOLNPGM("G34 aborted."); - else { - SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations); - SERIAL_ECHOLNPAIR_F("Accuracy: ", z_maxdiff); - } - - // Stow the probe because the last call to probe.probe_at_point(...) - // leaves the probe deployed when it's successful. - IF_DISABLED(TOUCH_MI_PROBE, probe.stow()); - - #if ENABLED(HOME_AFTER_G34) - // After this operation the z position needs correction - set_axis_never_homed(Z_AXIS); - // Home Z after the alignment procedure - process_subcommands_now(F("G28Z")); - #else - // Use the probed height from the last iteration to determine the Z height. - // z_measured_min is used, because all steppers are aligned to z_measured_min. - // Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier. - current_position.z -= z_measured_min - (float)Z_CLEARANCE_BETWEEN_PROBES; - sync_plan_position(); - #endif - - // Restore the active tool after homing - TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER))); // Fetch previous tool for parking extruder - - #if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34) - set_bed_leveling_enabled(leveling_was_active); - #endif - - }while(0); - #endif // Z_STEPPER_AUTO_ALIGN -} - -#endif // Z_MULTI_ENDSTOPS || Z_STEPPER_AUTO_ALIGN - -#if ENABLED(Z_STEPPER_AUTO_ALIGN) - -/** - * M422: Set a Z-Stepper automatic alignment XY point. - * Use repeatedly to set multiple points. - * - * S : Index of the probe point to set - * - * With Z_STEPPER_ALIGN_STEPPER_XY: - * W : Index of the Z stepper position to set - * The W and S parameters may not be combined. - * - * S and W require an X and/or Y parameter - * X : X position to set (Unchanged if omitted) - * Y : Y position to set (Unchanged if omitted) - * - * R : Recalculate points based on current probe offsets - */ -void GcodeSuite::M422() { - - if (!parser.seen_any()) return M422_report(); - - if (parser.seen('R')) { - z_stepper_align.reset_to_default(); - return; - } - - const bool is_probe_point = parser.seen_test('S'); - - if (TERN0(HAS_Z_STEPPER_ALIGN_STEPPER_XY, is_probe_point && parser.seen_test('W'))) { - SERIAL_ECHOLNPGM("?(S) and (W) may not be combined."); - return; - } - - xy_pos_t * const pos_dest = ( - TERN_(HAS_Z_STEPPER_ALIGN_STEPPER_XY, !is_probe_point ? z_stepper_align.stepper_xy :) - z_stepper_align.xy - ); - - if (!is_probe_point && TERN1(HAS_Z_STEPPER_ALIGN_STEPPER_XY, !parser.seen_test('W'))) { - SERIAL_ECHOLNPGM("?(S)" TERN_(HAS_Z_STEPPER_ALIGN_STEPPER_XY, " or (W)") " is required."); - return; - } - - // Get the Probe Position Index or Z Stepper Index - int8_t position_index = 1; - FSTR_P err_string = F("?(S) Probe-position"); - if (is_probe_point) - position_index = parser.intval('S'); - else { - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - err_string = F("?(W) Z-stepper"); - position_index = parser.intval('W'); - #endif - } - - if (!WITHIN(position_index, 1, NUM_Z_STEPPERS)) { - SERIAL_ECHOF(err_string); - SERIAL_ECHOLNPGM(" index invalid (1.." STRINGIFY(NUM_Z_STEPPERS) ")."); - return; - } - - --position_index; - - const xy_pos_t pos = { - parser.floatval('X', pos_dest[position_index].x), - parser.floatval('Y', pos_dest[position_index].y) - }; - - if (is_probe_point) { - if (!probe.can_reach(pos.x, Y_CENTER)) { - SERIAL_ECHOLNPGM("?(X) out of bounds."); - return; - } - if (!probe.can_reach(pos)) { - SERIAL_ECHOLNPGM("?(Y) out of bounds."); - return; - } - } - - pos_dest[position_index] = pos; -} - -void GcodeSuite::M422_report(const bool forReplay/*=true*/) { - report_heading(forReplay, F(STR_Z_AUTO_ALIGN)); - LOOP_L_N(i, NUM_Z_STEPPERS) { - report_echo_start(forReplay); - SERIAL_ECHOLNPGM_P( - PSTR(" M422 S"), i + 1, - SP_X_STR, z_stepper_align.xy[i].x, - SP_Y_STR, z_stepper_align.xy[i].y - ); - } - #if HAS_Z_STEPPER_ALIGN_STEPPER_XY - LOOP_L_N(i, NUM_Z_STEPPERS) { - report_echo_start(forReplay); - SERIAL_ECHOLNPGM_P( - PSTR(" M422 W"), i + 1, - SP_X_STR, z_stepper_align.stepper_xy[i].x, - SP_Y_STR, z_stepper_align.stepper_xy[i].y - ); - } - #endif -} - -#endif // Z_STEPPER_AUTO_ALIGN diff --git a/src/gcode/calibrate/G425.cpp b/src/gcode/calibrate/G425.cpp deleted file mode 100644 index f4d05ae..0000000 --- a/src/gcode/calibrate/G425.cpp +++ /dev/null @@ -1,764 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../MarlinCore.h" - -#if ENABLED(CALIBRATION_GCODE) - -#include "../gcode.h" - -#if ENABLED(BACKLASH_GCODE) - #include "../../feature/backlash.h" -#endif - -#include "../../lcd/marlinui.h" -#include "../../module/motion.h" -#include "../../module/planner.h" -#include "../../module/tool_change.h" -#include "../../module/endstops.h" -#include "../../feature/bedlevel/bedlevel.h" - -#if !AXIS_CAN_CALIBRATE(X) - #undef CALIBRATION_MEASURE_LEFT - #undef CALIBRATION_MEASURE_RIGHT -#endif - -#if !AXIS_CAN_CALIBRATE(Y) - #undef CALIBRATION_MEASURE_FRONT - #undef CALIBRATION_MEASURE_BACK -#endif - -#if !AXIS_CAN_CALIBRATE(Z) - #undef CALIBRATION_MEASURE_AT_TOP_EDGES -#endif - -/** - * G425 backs away from the calibration object by various distances - * depending on the confidence level: - * - * UNKNOWN - No real notion on where the calibration object is on the bed - * UNCERTAIN - Measurement may be uncertain due to backlash - * CERTAIN - Measurement obtained with backlash compensation - */ - -#ifndef CALIBRATION_MEASUREMENT_UNKNOWN - #define CALIBRATION_MEASUREMENT_UNKNOWN 5.0 // mm -#endif -#ifndef CALIBRATION_MEASUREMENT_UNCERTAIN - #define CALIBRATION_MEASUREMENT_UNCERTAIN 1.0 // mm -#endif -#ifndef CALIBRATION_MEASUREMENT_CERTAIN - #define CALIBRATION_MEASUREMENT_CERTAIN 0.5 // mm -#endif - -#if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT) - #define HAS_X_CENTER 1 -#endif -#if ALL(HAS_Y_AXIS, CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK) - #define HAS_Y_CENTER 1 -#endif -#if ALL(HAS_I_AXIS, CALIBRATION_MEASURE_IMIN, CALIBRATION_MEASURE_IMAX) - #define HAS_I_CENTER 1 -#endif -#if ALL(HAS_J_AXIS, CALIBRATION_MEASURE_JMIN, CALIBRATION_MEASURE_JMAX) - #define HAS_J_CENTER 1 -#endif -#if ALL(HAS_K_AXIS, CALIBRATION_MEASURE_KMIN, CALIBRATION_MEASURE_KMAX) - #define HAS_K_CENTER 1 -#endif - -enum side_t : uint8_t { - TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES, - LIST_N(DOUBLE(SECONDARY_AXES), IMINIMUM, IMAXIMUM, JMINIMUM, JMAXIMUM, KMINIMUM, KMAXIMUM) -}; - -static constexpr xyz_pos_t true_center CALIBRATION_OBJECT_CENTER; -static constexpr xyz_float_t dimensions CALIBRATION_OBJECT_DIMENSIONS; -static constexpr xy_float_t nod = { CALIBRATION_NOZZLE_OUTER_DIAMETER, CALIBRATION_NOZZLE_OUTER_DIAMETER }; - -struct measurements_t { - xyz_pos_t obj_center = true_center; // Non-static must be assigned from xyz_pos_t - - float obj_side[NUM_SIDES], backlash[NUM_SIDES]; - xyz_float_t pos_error; - - xy_float_t nozzle_outer_dimension = nod; -}; - -#if ENABLED(BACKLASH_GCODE) - class restorer_correction { - const uint8_t val_; - public: - restorer_correction(const uint8_t temp_val) : val_(backlash.get_correction_uint8()) { backlash.set_correction_uint8(temp_val); } - ~restorer_correction() { backlash.set_correction_uint8(val_); } - }; - - #define TEMPORARY_BACKLASH_CORRECTION(value) restorer_correction restorer_tbst(value) -#else - #define TEMPORARY_BACKLASH_CORRECTION(value) -#endif - -#if ENABLED(BACKLASH_GCODE) && defined(BACKLASH_SMOOTHING_MM) - class restorer_smoothing { - const float val_; - public: - restorer_smoothing(const float temp_val) : val_(backlash.get_smoothing_mm()) { backlash.set_smoothing_mm(temp_val); } - ~restorer_smoothing() { backlash.set_smoothing_mm(val_); } - }; - - #define TEMPORARY_BACKLASH_SMOOTHING(value) restorer_smoothing restorer_tbsm(value) -#else - #define TEMPORARY_BACKLASH_SMOOTHING(value) -#endif - -inline void calibration_move() { - do_blocking_move_to((xyz_pos_t)current_position, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL)); -} - -/** - * Move to the exact center above the calibration object - * - * m in - Measurement record - * uncertainty in - How far away from the object top to park - */ -inline void park_above_object(measurements_t &m, const float uncertainty) { - // Move to safe distance above calibration object - current_position.z = m.obj_center.z + dimensions.z / 2 + uncertainty; - calibration_move(); - - // Move to center of calibration object in XY - current_position = xy_pos_t(m.obj_center); - calibration_move(); -} - -#if HAS_MULTI_HOTEND - inline void set_nozzle(measurements_t &m, const uint8_t extruder) { - if (extruder != active_extruder) { - park_above_object(m, CALIBRATION_MEASUREMENT_UNKNOWN); - tool_change(extruder); - } - } -#endif - -#if HAS_HOTEND_OFFSET - - inline void normalize_hotend_offsets() { - LOOP_S_L_N(e, 1, HOTENDS) - hotend_offset[e] -= hotend_offset[0]; - hotend_offset[0].reset(); - } - -#endif - -#if !PIN_EXISTS(CALIBRATION) - #include "../../module/probe.h" -#endif - -inline bool read_calibration_pin() { - return ( - #if PIN_EXISTS(CALIBRATION) - READ(CALIBRATION_PIN) != CALIBRATION_PIN_INVERTING - #else - PROBE_TRIGGERED() - #endif - ); -} - -/** - * Move along axis in the specified dir until the probe value becomes stop_state, - * then return the axis value. - * - * axis in - Axis along which the measurement will take place - * dir in - Direction along that axis (-1 or 1) - * stop_state in - Move until probe pin becomes this value - * fast in - Fast vs. precise measurement - */ -float measuring_movement(const AxisEnum axis, const int dir, const bool stop_state, const bool fast) { - const float step = fast ? 0.25 : CALIBRATION_MEASUREMENT_RESOLUTION; - const feedRate_t mms = fast ? MMM_TO_MMS(CALIBRATION_FEEDRATE_FAST) : MMM_TO_MMS(CALIBRATION_FEEDRATE_SLOW); - const float limit = fast ? 50 : 5; - - destination = current_position; - for (float travel = 0; travel < limit; travel += step) { - destination[axis] += dir * step; - do_blocking_move_to((xyz_pos_t)destination, mms); - planner.synchronize(); - if (read_calibration_pin() == stop_state) break; - } - return destination[axis]; -} - -/** - * Move along axis until the probe is triggered. Move toolhead to its starting - * point and return the measured value. - * - * axis in - Axis along which the measurement will take place - * dir in - Direction along that axis (-1 or 1) - * stop_state in - Move until probe pin becomes this value - * backlash_ptr in/out - When not nullptr, measure and record axis backlash - * uncertainty in - If uncertainty is CALIBRATION_MEASUREMENT_UNKNOWN, do a fast probe. - */ -inline float measure(const AxisEnum axis, const int dir, const bool stop_state, float * const backlash_ptr, const float uncertainty) { - const bool fast = uncertainty == CALIBRATION_MEASUREMENT_UNKNOWN; - - // Save the current position of the specified axis - const float start_pos = current_position[axis]; - - // Take a measurement. Only the specified axis will be affected. - const float measured_pos = measuring_movement(axis, dir, stop_state, fast); - - // Measure backlash - if (backlash_ptr && !fast) { - const float release_pos = measuring_movement(axis, -dir, !stop_state, fast); - *backlash_ptr = ABS(release_pos - measured_pos); - } - - // Move back to the starting position - destination = current_position; - destination[axis] = start_pos; - do_blocking_move_to((xyz_pos_t)destination, MMM_TO_MMS(CALIBRATION_FEEDRATE_TRAVEL)); - return measured_pos; -} - -/** - * Probe one side of the calibration object - * - * m in/out - Measurement record, m.obj_center and m.obj_side will be updated. - * uncertainty in - How far away from the calibration object to begin probing - * side in - Side of probe where probe will occur - * probe_top_at_edge in - When probing sides, probe top of calibration object nearest edge - * to find out height of edge - */ -inline void probe_side(measurements_t &m, const float uncertainty, const side_t side, const bool probe_top_at_edge=false) { - const xyz_float_t dimensions = CALIBRATION_OBJECT_DIMENSIONS; - AxisEnum axis; - float dir = 1; - - park_above_object(m, uncertainty); - - #define _ACASE(N,A,B) case A: dir = -1; case B: axis = N##_AXIS; break - #define _PCASE(N) _ACASE(N, N##MINIMUM, N##MAXIMUM) - - switch (side) { - #if AXIS_CAN_CALIBRATE(X) - _ACASE(X, RIGHT, LEFT); - #endif - #if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y) - _ACASE(Y, BACK, FRONT); - #endif - #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) - case TOP: { - const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); - m.obj_center.z = measurement - dimensions.z / 2; - m.obj_side[TOP] = measurement; - return; - } - #endif - #if HAS_I_AXIS && AXIS_CAN_CALIBRATE(I) - _PCASE(I); - #endif - #if HAS_J_AXIS && AXIS_CAN_CALIBRATE(J) - _PCASE(J); - #endif - #if HAS_K_AXIS && AXIS_CAN_CALIBRATE(K) - _PCASE(K); - #endif - default: return; - } - - if (probe_top_at_edge) { - #if AXIS_CAN_CALIBRATE(Z) - // Probe top nearest the side we are probing - current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 - m.nozzle_outer_dimension[axis]); - calibration_move(); - m.obj_side[TOP] = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); - m.obj_center.z = m.obj_side[TOP] - dimensions.z / 2; - #endif - } - - if ((AXIS_CAN_CALIBRATE(X) && axis == X_AXIS) || (AXIS_CAN_CALIBRATE(Y) && axis == Y_AXIS)) { - // Move to safe distance to the side of the calibration object - current_position[axis] = m.obj_center[axis] + (-dir) * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2 + uncertainty); - calibration_move(); - - // Plunge below the side of the calibration object and measure - current_position.z = m.obj_side[TOP] - (CALIBRATION_NOZZLE_TIP_HEIGHT) * 0.7f; - calibration_move(); - const float measurement = measure(axis, dir, true, &m.backlash[side], uncertainty); - m.obj_center[axis] = measurement + dir * (dimensions[axis] / 2 + m.nozzle_outer_dimension[axis] / 2); - m.obj_side[side] = measurement; - } -} - -/** - * Probe all sides of the calibration calibration object - * - * m in/out - Measurement record: center, backlash and error values be updated. - * uncertainty in - How far away from the calibration object to begin probing - */ -inline void probe_sides(measurements_t &m, const float uncertainty) { - #if ENABLED(CALIBRATION_MEASURE_AT_TOP_EDGES) - constexpr bool probe_top_at_edge = true; - #else - // Probing at the exact center only works if the center is flat. Probing on a washer - // or bolt will require probing the top near the side edges, away from the center. - constexpr bool probe_top_at_edge = false; - probe_side(m, uncertainty, TOP); - #endif - - TERN_(CALIBRATION_MEASURE_RIGHT, probe_side(m, uncertainty, RIGHT, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_FRONT, probe_side(m, uncertainty, FRONT, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_LEFT, probe_side(m, uncertainty, LEFT, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_BACK, probe_side(m, uncertainty, BACK, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_IMIN, probe_side(m, uncertainty, IMINIMUM, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_IMAX, probe_side(m, uncertainty, IMAXIMUM, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_JMIN, probe_side(m, uncertainty, JMINIMUM, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_JMAX, probe_side(m, uncertainty, JMAXIMUM, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_KMIN, probe_side(m, uncertainty, KMINIMUM, probe_top_at_edge)); - TERN_(CALIBRATION_MEASURE_KMAX, probe_side(m, uncertainty, KMAXIMUM, probe_top_at_edge)); - - // Compute the measured center of the calibration object. - TERN_(HAS_X_CENTER, m.obj_center.x = (m.obj_side[LEFT] + m.obj_side[RIGHT]) / 2); - TERN_(HAS_Y_CENTER, m.obj_center.y = (m.obj_side[FRONT] + m.obj_side[BACK]) / 2); - TERN_(HAS_I_CENTER, m.obj_center.i = (m.obj_side[IMINIMUM] + m.obj_side[IMAXIMUM]) / 2); - TERN_(HAS_J_CENTER, m.obj_center.j = (m.obj_side[JMINIMUM] + m.obj_side[JMAXIMUM]) / 2); - TERN_(HAS_K_CENTER, m.obj_center.k = (m.obj_side[KMINIMUM] + m.obj_side[KMAXIMUM]) / 2); - - // Compute the outside diameter of the nozzle at the height - // at which it makes contact with the calibration object - TERN_(HAS_X_CENTER, m.nozzle_outer_dimension.x = m.obj_side[RIGHT] - m.obj_side[LEFT] - dimensions.x); - TERN_(HAS_Y_CENTER, m.nozzle_outer_dimension.y = m.obj_side[BACK] - m.obj_side[FRONT] - dimensions.y); - - park_above_object(m, uncertainty); - - // The difference between the known and the measured location - // of the calibration object is the positional error - NUM_AXIS_CODE( - m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x), - m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y), - m.pos_error.z = true_center.z - m.obj_center.z, - m.pos_error.i = TERN0(HAS_I_CENTER, true_center.i - m.obj_center.i), - m.pos_error.j = TERN0(HAS_J_CENTER, true_center.j - m.obj_center.j), - m.pos_error.k = TERN0(HAS_K_CENTER, true_center.k - m.obj_center.k) - ); -} - -#if ENABLED(CALIBRATION_REPORTING) - inline void report_measured_faces(const measurements_t &m) { - SERIAL_ECHOLNPGM("Sides:"); - #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) - SERIAL_ECHOLNPGM(" Top: ", m.obj_side[TOP]); - #endif - #if ENABLED(CALIBRATION_MEASURE_LEFT) - SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_RIGHT) - SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]); - #endif - #if HAS_Y_AXIS - #if ENABLED(CALIBRATION_MEASURE_FRONT) - SERIAL_ECHOLNPGM(" Front: ", m.obj_side[FRONT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_BACK) - SERIAL_ECHOLNPGM(" Back: ", m.obj_side[BACK]); - #endif - #endif - #if HAS_I_AXIS - #if ENABLED(CALIBRATION_MEASURE_IMIN) - SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.obj_side[IMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_IMAX) - SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.obj_side[IMAXIMUM]); - #endif - #endif - #if HAS_J_AXIS - #if ENABLED(CALIBRATION_MEASURE_JMIN) - SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.obj_side[JMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_JMAX) - SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.obj_side[JMAXIMUM]); - #endif - #endif - #if HAS_K_AXIS - #if ENABLED(CALIBRATION_MEASURE_KMIN) - SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.obj_side[KMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_KMAX) - SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.obj_side[KMAXIMUM]); - #endif - #endif - SERIAL_EOL(); - } - - inline void report_measured_center(const measurements_t &m) { - SERIAL_ECHOLNPGM("Center:"); - #if HAS_X_CENTER - SERIAL_ECHOLNPGM_P(SP_X_STR, m.obj_center.x); - #endif - #if HAS_Y_CENTER - SERIAL_ECHOLNPGM_P(SP_Y_STR, m.obj_center.y); - #endif - SERIAL_ECHOLNPGM_P(SP_Z_STR, m.obj_center.z); - #if HAS_I_CENTER - SERIAL_ECHOLNPGM_P(SP_I_STR, m.obj_center.i); - #endif - #if HAS_J_CENTER - SERIAL_ECHOLNPGM_P(SP_J_STR, m.obj_center.j); - #endif - #if HAS_K_CENTER - SERIAL_ECHOLNPGM_P(SP_K_STR, m.obj_center.k); - #endif - SERIAL_EOL(); - } - - inline void report_measured_backlash(const measurements_t &m) { - SERIAL_ECHOLNPGM("Backlash:"); - #if AXIS_CAN_CALIBRATE(X) - #if ENABLED(CALIBRATION_MEASURE_LEFT) - SERIAL_ECHOLNPGM(" Left: ", m.backlash[LEFT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_RIGHT) - SERIAL_ECHOLNPGM(" Right: ", m.backlash[RIGHT]); - #endif - #endif - #if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y) - #if ENABLED(CALIBRATION_MEASURE_FRONT) - SERIAL_ECHOLNPGM(" Front: ", m.backlash[FRONT]); - #endif - #if ENABLED(CALIBRATION_MEASURE_BACK) - SERIAL_ECHOLNPGM(" Back: ", m.backlash[BACK]); - #endif - #endif - #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) - SERIAL_ECHOLNPGM(" Top: ", m.backlash[TOP]); - #endif - #if HAS_I_AXIS && AXIS_CAN_CALIBRATE(I) - #if ENABLED(CALIBRATION_MEASURE_IMIN) - SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.backlash[IMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_IMAX) - SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]); - #endif - #endif - #if HAS_J_AXIS && AXIS_CAN_CALIBRATE(J) - #if ENABLED(CALIBRATION_MEASURE_JMIN) - SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.backlash[JMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_JMAX) - SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]); - #endif - #endif - #if HAS_K_AXIS && AXIS_CAN_CALIBRATE(K) - #if ENABLED(CALIBRATION_MEASURE_KMIN) - SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.backlash[KMINIMUM]); - #endif - #if ENABLED(CALIBRATION_MEASURE_KMAX) - SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]); - #endif - #endif - SERIAL_EOL(); - } - - inline void report_measured_positional_error(const measurements_t &m) { - SERIAL_CHAR('T'); - SERIAL_ECHO(active_extruder); - SERIAL_ECHOLNPGM(" Positional Error:"); - #if HAS_X_CENTER && AXIS_CAN_CALIBRATE(X) - SERIAL_ECHOLNPGM_P(SP_X_STR, m.pos_error.x); - #endif - #if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y) - SERIAL_ECHOLNPGM_P(SP_Y_STR, m.pos_error.y); - #endif - #if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) - SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z); - #endif - #if HAS_I_CENTER && AXIS_CAN_CALIBRATE(I) - SERIAL_ECHOLNPGM_P(SP_I_STR, m.pos_error.i); - #endif - #if HAS_J_CENTER && AXIS_CAN_CALIBRATE(J) - SERIAL_ECHOLNPGM_P(SP_J_STR, m.pos_error.j); - #endif - #if HAS_K_CENTER && AXIS_CAN_CALIBRATE(K) - SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z); - #endif - SERIAL_EOL(); - } - - inline void report_measured_nozzle_dimensions(const measurements_t &m) { - SERIAL_ECHOLNPGM("Nozzle Tip Outer Dimensions:"); - #if HAS_X_CENTER - SERIAL_ECHOLNPGM_P(SP_X_STR, m.nozzle_outer_dimension.x); - #endif - #if HAS_Y_CENTER - SERIAL_ECHOLNPGM_P(SP_Y_STR, m.nozzle_outer_dimension.y); - #endif - SERIAL_EOL(); - UNUSED(m); - } - - #if HAS_HOTEND_OFFSET - // - // This function requires normalize_hotend_offsets() to be called - // - inline void report_hotend_offsets() { - LOOP_S_L_N(e, 1, HOTENDS) - SERIAL_ECHOLNPGM_P(PSTR("T"), e, PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z); - } - #endif - -#endif // CALIBRATION_REPORTING - -/** - * Probe around the calibration object to measure backlash - * - * m in/out - Measurement record, updated with new readings - * uncertainty in - How far away from the object to begin probing - */ -inline void calibrate_backlash(measurements_t &m, const float uncertainty) { - // Backlash compensation should be off while measuring backlash - - { - // New scope for TEMPORARY_BACKLASH_CORRECTION - TEMPORARY_BACKLASH_CORRECTION(backlash.all_off); - TEMPORARY_BACKLASH_SMOOTHING(0.0f); - - probe_sides(m, uncertainty); - - #if ENABLED(BACKLASH_GCODE) - - #if HAS_X_CENTER - backlash.set_distance_mm(X_AXIS, (m.backlash[LEFT] + m.backlash[RIGHT]) / 2); - #elif ENABLED(CALIBRATION_MEASURE_LEFT) - backlash.set_distance_mm(X_AXIS, m.backlash[LEFT]); - #elif ENABLED(CALIBRATION_MEASURE_RIGHT) - backlash.set_distance_mm(X_AXIS, m.backlash[RIGHT]); - #endif - - #if HAS_Y_CENTER - backlash.set_distance_mm(Y_AXIS, (m.backlash[FRONT] + m.backlash[BACK]) / 2); - #elif ENABLED(CALIBRATION_MEASURE_FRONT) - backlash.set_distance_mm(Y_AXIS, m.backlash[FRONT]); - #elif ENABLED(CALIBRATION_MEASURE_BACK) - backlash.set_distance_mm(Y_AXIS, m.backlash[BACK]); - #endif - - TERN_(HAS_Z_AXIS, if (AXIS_CAN_CALIBRATE(Z)) backlash.set_distance_mm(Z_AXIS, m.backlash[TOP])); - - #if HAS_I_CENTER - backlash.set_distance_mm(I_AXIS, (m.backlash[IMINIMUM] + m.backlash[IMAXIMUM]) / 2); - #elif ENABLED(CALIBRATION_MEASURE_IMIN) - backlash.set_distance_mm(I_AXIS, m.backlash[IMINIMUM]); - #elif ENABLED(CALIBRATION_MEASURE_IMAX) - backlash.set_distance_mm(I_AXIS, m.backlash[IMAXIMUM]); - #endif - - #if HAS_J_CENTER - backlash.set_distance_mm(J_AXIS, (m.backlash[JMINIMUM] + m.backlash[JMAXIMUM]) / 2); - #elif ENABLED(CALIBRATION_MEASURE_JMIN) - backlash.set_distance_mm(J_AXIS, m.backlash[JMINIMUM]); - #elif ENABLED(CALIBRATION_MEASURE_JMAX) - backlash.set_distance_mm(J_AXIS, m.backlash[JMAXIMUM]); - #endif - - #if HAS_K_CENTER - backlash.set_distance_mm(K_AXIS, (m.backlash[KMINIMUM] + m.backlash[KMAXIMUM]) / 2); - #elif ENABLED(CALIBRATION_MEASURE_KMIN) - backlash.set_distance_mm(K_AXIS, m.backlash[KMINIMUM]); - #elif ENABLED(CALIBRATION_MEASURE_KMAX) - backlash.set_distance_mm(K_AXIS, m.backlash[KMAXIMUM]); - #endif - - #endif // BACKLASH_GCODE - } - - #if ENABLED(BACKLASH_GCODE) - // Turn on backlash compensation and move in all - // allowed directions to take up any backlash - { - // New scope for TEMPORARY_BACKLASH_CORRECTION - TEMPORARY_BACKLASH_CORRECTION(backlash.all_on); - TEMPORARY_BACKLASH_SMOOTHING(0.0f); - const xyz_float_t move = NUM_AXIS_ARRAY( - AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3, - AXIS_CAN_CALIBRATE(I) * 3, AXIS_CAN_CALIBRATE(J) * 3, AXIS_CAN_CALIBRATE(K) * 3 - ); - current_position += move; calibration_move(); - current_position -= move; calibration_move(); - } - #endif -} - -inline void update_measurements(measurements_t &m, const AxisEnum axis) { - current_position[axis] += m.pos_error[axis]; - m.obj_center[axis] = true_center[axis]; - m.pos_error[axis] = 0; -} - -/** - * Probe around the calibration object. Adjust the position and toolhead offset - * using the deviation from the known position of the calibration object. - * - * m in/out - Measurement record, updated with new readings - * uncertainty in - How far away from the object to begin probing - * extruder in - What extruder to probe - * - * Prerequisites: - * - Call calibrate_backlash() beforehand for best accuracy - */ -inline void calibrate_toolhead(measurements_t &m, const float uncertainty, const uint8_t extruder) { - TEMPORARY_BACKLASH_CORRECTION(backlash.all_on); - TEMPORARY_BACKLASH_SMOOTHING(0.0f); - - TERN(HAS_MULTI_HOTEND, set_nozzle(m, extruder), UNUSED(extruder)); - - probe_sides(m, uncertainty); - - // Adjust the hotend offset - #if HAS_HOTEND_OFFSET - if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) hotend_offset[extruder].x += m.pos_error.x; - if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) hotend_offset[extruder].y += m.pos_error.y; - if (AXIS_CAN_CALIBRATE(Z)) hotend_offset[extruder].z += m.pos_error.z; - normalize_hotend_offsets(); - #endif - - // Correct for positional error, so the object - // is at the known actual spot - planner.synchronize(); - if (ENABLED(HAS_X_CENTER) && AXIS_CAN_CALIBRATE(X)) update_measurements(m, X_AXIS); - if (ENABLED(HAS_Y_CENTER) && AXIS_CAN_CALIBRATE(Y)) update_measurements(m, Y_AXIS); - if (AXIS_CAN_CALIBRATE(Z)) update_measurements(m, Z_AXIS); - - TERN_(HAS_I_CENTER, update_measurements(m, I_AXIS)); - TERN_(HAS_J_CENTER, update_measurements(m, J_AXIS)); - TERN_(HAS_K_CENTER, update_measurements(m, K_AXIS)); - - sync_plan_position(); -} - -/** - * Probe around the calibration object for all toolheads, adjusting the coordinate - * system for the first nozzle and the nozzle offset for subsequent nozzles. - * - * m in/out - Measurement record, updated with new readings - * uncertainty in - How far away from the object to begin probing - */ -inline void calibrate_all_toolheads(measurements_t &m, const float uncertainty) { - TEMPORARY_BACKLASH_CORRECTION(backlash.all_on); - TEMPORARY_BACKLASH_SMOOTHING(0.0f); - - HOTEND_LOOP() calibrate_toolhead(m, uncertainty, e); - - TERN_(HAS_HOTEND_OFFSET, normalize_hotend_offsets()); - - TERN_(HAS_MULTI_HOTEND, set_nozzle(m, 0)); -} - -/** - * Perform a full auto-calibration routine: - * - * 1) For each nozzle, touch top and sides of object to determine object position and - * nozzle offsets. Do a fast but rough search over a wider area. - * 2) With the first nozzle, touch top and sides of object to determine backlash values - * for all axes (if BACKLASH_GCODE is enabled) - * 3) For each nozzle, touch top and sides of object slowly to determine precise - * position of object. Adjust coordinate system and nozzle offsets so probed object - * location corresponds to known object location with a high degree of precision. - */ -inline void calibrate_all() { - measurements_t m; - - TERN_(HAS_HOTEND_OFFSET, reset_hotend_offsets()); - - TEMPORARY_BACKLASH_CORRECTION(backlash.all_on); - TEMPORARY_BACKLASH_SMOOTHING(0.0f); - - // Do a fast and rough calibration of the toolheads - calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNKNOWN); - - TERN_(BACKLASH_GCODE, calibrate_backlash(m, CALIBRATION_MEASUREMENT_UNCERTAIN)); - - // Cycle the toolheads so the servos settle into their "natural" positions - #if HAS_MULTI_HOTEND - HOTEND_LOOP() set_nozzle(m, e); - #endif - - // Do a slow and precise calibration of the toolheads - calibrate_all_toolheads(m, CALIBRATION_MEASUREMENT_UNCERTAIN); - - current_position.x = X_CENTER; - calibration_move(); // Park nozzle away from calibration object -} - -/** - * G425: Perform calibration with calibration object. - * - * B - Perform calibration of backlash only. - * T - Perform calibration of toolhead only. - * V - Probe object and print position, error, backlash and hotend offset. - * U - Uncertainty, how far to start probe away from the object (mm) - * - * no args - Perform entire calibration sequence (backlash + position on all toolheads) - */ -void GcodeSuite::G425() { - - #ifdef CALIBRATION_SCRIPT_PRE - process_subcommands_now(F(CALIBRATION_SCRIPT_PRE)); - #endif - - if (homing_needed_error()) return; - - TEMPORARY_BED_LEVELING_STATE(false); - SET_SOFT_ENDSTOP_LOOSE(true); - - measurements_t m; - const float uncertainty = parser.floatval('U', CALIBRATION_MEASUREMENT_UNCERTAIN); - - if (parser.seen_test('B')) - calibrate_backlash(m, uncertainty); - else if (parser.seen_test('T')) - calibrate_toolhead(m, uncertainty, parser.intval('T', active_extruder)); - #if ENABLED(CALIBRATION_REPORTING) - else if (parser.seen('V')) { - probe_sides(m, uncertainty); - SERIAL_EOL(); - report_measured_faces(m); - report_measured_center(m); - report_measured_backlash(m); - report_measured_nozzle_dimensions(m); - report_measured_positional_error(m); - #if HAS_HOTEND_OFFSET - normalize_hotend_offsets(); - report_hotend_offsets(); - #endif - } - #endif - else - calibrate_all(); - - SET_SOFT_ENDSTOP_LOOSE(false); - - #ifdef CALIBRATION_SCRIPT_POST - process_subcommands_now(F(CALIBRATION_SCRIPT_POST)); - #endif -} - -#endif // CALIBRATION_GCODE diff --git a/src/gcode/calibrate/G76_M871.cpp b/src/gcode/calibrate/G76_M871.cpp deleted file mode 100644 index c484d4f..0000000 --- a/src/gcode/calibrate/G76_M871.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/** - * G76_M871.cpp - Temperature calibration/compensation for z-probing - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_PTC - -#include "../gcode.h" -#include "../../module/motion.h" -#include "../../module/planner.h" -#include "../../module/probe.h" -#include "../../feature/bedlevel/bedlevel.h" -#include "../../module/temperature.h" -#include "../../module/probe.h" -#include "../../feature/probe_temp_comp.h" -#include "../../lcd/marlinui.h" - -/** - * G76: calibrate probe and/or bed temperature offsets - * Notes: - * - When calibrating probe, bed temperature is held constant. - * Compensation values are deltas to first probe measurement at probe temp. = 30°C. - * - When calibrating bed, probe temperature is held constant. - * Compensation values are deltas to first probe measurement at bed temp. = 60°C. - * - The hotend will not be heated at any time. - * - On my Průša MK3S clone I put a piece of paper between the probe and the hotend - * so the hotend fan would not cool my probe constantly. Alternatively you could just - * make sure the fan is not running while running the calibration process. - * - * Probe calibration: - * - Moves probe to cooldown point. - * - Heats up bed to 100°C. - * - Moves probe to probing point (1mm above heatbed). - * - Waits until probe reaches target temperature (30°C). - * - Does a z-probing (=base value) and increases target temperature by 5°C. - * - Waits until probe reaches increased target temperature. - * - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C. - * - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further). - * - Compensation values of higher temperatures will be extrapolated (using linear regression first). - * While this is not exact by any means it is still better than simply using the last compensation value. - * - * Bed calibration: - * - Moves probe to cooldown point. - * - Heats up bed to 60°C. - * - Moves probe to probing point (1mm above heatbed). - * - Waits until probe reaches target temperature (30°C). - * - Does a z-probing (=base value) and increases bed temperature by 5°C. - * - Moves probe to cooldown point. - * - Waits until probe is below 30°C and bed has reached target temperature. - * - Moves probe to probing point and waits until it reaches target temperature (30°C). - * - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C. - * - Repeats last four points until max. bed temperature reached (110°C) or timeout. - * - Compensation values of higher temperatures will be extrapolated (using linear regression first). - * While this is not exact by any means it is still better than simply using the last compensation value. - * - * G76 [B | P] - * - no flag - Both calibration procedures will be run. - * - `B` - Run bed temperature calibration. - * - `P` - Run probe temperature calibration. - */ - -#if BOTH(PTC_PROBE, PTC_BED) - - static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); } - static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); } - static void say_successfully_calibrated() { SERIAL_ECHOPGM("Successfully calibrated"); } - static void say_failed_to_calibrate() { SERIAL_ECHOPGM("!Failed to calibrate"); } - - void GcodeSuite::G76() { - auto report_temps = [](millis_t &ntr, millis_t timeout=0) { - idle_no_sleep(); - const millis_t ms = millis(); - if (ELAPSED(ms, ntr)) { - ntr = ms + 1000; - thermalManager.print_heater_states(active_extruder); - } - return (timeout && ELAPSED(ms, timeout)); - }; - - auto wait_for_temps = [&](const celsius_t tb, const celsius_t tp, millis_t &ntr, const millis_t timeout=0) { - say_waiting_for(); SERIAL_ECHOLNPGM("bed and probe temperature."); - while (thermalManager.wholeDegBed() != tb || thermalManager.wholeDegProbe() > tp) - if (report_temps(ntr, timeout)) return true; - return false; - }; - - auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) { - do_z_clearance(5.0); // Raise nozzle before probing - ptc.set_enabled(false); - const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false - ptc.set_enabled(true); - if (isnan(measured_z)) - SERIAL_ECHOLNPGM("!Received NAN. Aborting."); - else { - SERIAL_ECHOLNPAIR_F("Measured: ", measured_z); - if (targ == ProbeTempComp::cali_info[sid].start_temp) - ptc.prepare_new_calibration(measured_z); - else - ptc.push_back_new_measurement(sid, measured_z); - targ += ProbeTempComp::cali_info[sid].temp_resolution; - } - return measured_z; - }; - - #if ENABLED(BLTOUCH) - // Make sure any BLTouch error condition is cleared - bltouch_command(BLTOUCH_RESET, BLTOUCH_RESET_DELAY); - set_bltouch_deployed(false); - #endif - - bool do_bed_cal = parser.boolval('B'), do_probe_cal = parser.boolval('P'); - if (!do_bed_cal && !do_probe_cal) do_bed_cal = do_probe_cal = true; - - // Synchronize with planner - planner.synchronize(); - - #ifndef PTC_PROBE_HEATING_OFFSET - #define PTC_PROBE_HEATING_OFFSET 0 - #endif - const xyz_pos_t parkpos = PTC_PARK_POS, - probe_pos_xyz = xyz_pos_t(PTC_PROBE_POS) + xyz_pos_t({ 0.0f, 0.0f, PTC_PROBE_HEATING_OFFSET }), - noz_pos_xyz = probe_pos_xyz - probe.offset_xy; // Nozzle position based on probe position - - if (do_bed_cal || do_probe_cal) { - // Ensure park position is reachable - bool reachable = position_is_reachable(parkpos) || WITHIN(parkpos.z, Z_MIN_POS - fslop, Z_MAX_POS + fslop); - if (!reachable) - SERIAL_ECHOLNPGM("!Park"); - else { - // Ensure probe position is reachable - reachable = probe.can_reach(probe_pos_xyz); - if (!reachable) SERIAL_ECHOLNPGM("!Probe"); - } - - if (!reachable) { - SERIAL_ECHOLNPGM(" position unreachable - aborting."); - return; - } - - process_subcommands_now(FPSTR(G28_STR)); - } - - remember_feedrate_scaling_off(); - - /****************************************** - * Calibrate bed temperature offsets - ******************************************/ - - // Report temperatures every second and handle heating timeouts - millis_t next_temp_report = millis() + 1000; - - auto report_targets = [&](const celsius_t tb, const celsius_t tp) { - SERIAL_ECHOLNPGM("Target Bed:", tb, " Probe:", tp); - }; - - if (do_bed_cal) { - - celsius_t target_bed = PTC_BED_START, - target_probe = PTC_PROBE_TEMP; - - say_waiting_for(); SERIAL_ECHOLNPGM(" cooling."); - while (thermalManager.wholeDegBed() > target_bed || thermalManager.wholeDegProbe() > target_probe) - report_temps(next_temp_report); - - // Disable leveling so it won't mess with us - TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); - - for (uint8_t idx = 0; idx <= PTC_BED_COUNT; idx++) { - thermalManager.setTargetBed(target_bed); - - report_targets(target_bed, target_probe); - - // Park nozzle - do_blocking_move_to(parkpos); - - // Wait for heatbed to reach target temp and probe to cool below target temp - if (wait_for_temps(target_bed, target_probe, next_temp_report, millis() + MIN_TO_MS(15))) { - SERIAL_ECHOLNPGM("!Bed heating timeout."); - break; - } - - // Move the nozzle to the probing point and wait for the probe to reach target temp - do_blocking_move_to(noz_pos_xyz); - say_waiting_for_probe_heating(); - SERIAL_EOL(); - while (thermalManager.wholeDegProbe() < target_probe) - report_temps(next_temp_report); - - const float measured_z = g76_probe(TSI_BED, target_bed, noz_pos_xyz); - if (isnan(measured_z) || target_bed > (BED_MAX_TARGET)) break; - } - - SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index()); - if (ptc.finish_calibration(TSI_BED)) { - say_successfully_calibrated(); - SERIAL_ECHOLNPGM(" bed."); - } - else { - say_failed_to_calibrate(); - SERIAL_ECHOLNPGM(" bed. Values reset."); - } - - // Cleanup - thermalManager.setTargetBed(0); - TERN_(HAS_LEVELING, set_bed_leveling_enabled(true)); - } // do_bed_cal - - /******************************************** - * Calibrate probe temperature offsets - ********************************************/ - - if (do_probe_cal) { - - // Park nozzle - do_blocking_move_to(parkpos); - - // Initialize temperatures - const celsius_t target_bed = BED_MAX_TARGET; - thermalManager.setTargetBed(target_bed); - - celsius_t target_probe = PTC_PROBE_START; - - report_targets(target_bed, target_probe); - - // Wait for heatbed to reach target temp and probe to cool below target temp - wait_for_temps(target_bed, target_probe, next_temp_report); - - // Disable leveling so it won't mess with us - TERN_(HAS_LEVELING, set_bed_leveling_enabled(false)); - - bool timeout = false; - for (uint8_t idx = 0; idx <= PTC_PROBE_COUNT; idx++) { - // Move probe to probing point and wait for it to reach target temperature - do_blocking_move_to(noz_pos_xyz); - - say_waiting_for_probe_heating(); - SERIAL_ECHOLNPGM(" Bed:", target_bed, " Probe:", target_probe); - const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL); - while (thermalManager.degProbe() < target_probe) { - if (report_temps(next_temp_report, probe_timeout_ms)) { - SERIAL_ECHOLNPGM("!Probe heating timed out."); - timeout = true; - break; - } - } - if (timeout) break; - - const float measured_z = g76_probe(TSI_PROBE, target_probe, noz_pos_xyz); - if (isnan(measured_z)) break; - } - - SERIAL_ECHOLNPGM("Retrieved measurements: ", ptc.get_index()); - if (ptc.finish_calibration(TSI_PROBE)) - say_successfully_calibrated(); - else - say_failed_to_calibrate(); - SERIAL_ECHOLNPGM(" probe."); - - // Cleanup - thermalManager.setTargetBed(0); - TERN_(HAS_LEVELING, set_bed_leveling_enabled(true)); - - SERIAL_ECHOLNPGM("Final compensation values:"); - ptc.print_offsets(); - } // do_probe_cal - - restore_feedrate_and_scaling(); - } - -#endif // PTC_PROBE && PTC_BED - -/** - * M871: Report / reset temperature compensation offsets. - * Note: This does not affect values in EEPROM until M500. - * - * M871 [ R | B | P | E ] - * - * No Parameters - Print current offset values. - * - * Select only one of these flags: - * R - Reset all offsets to zero (i.e., disable compensation). - * B - Manually set offset for bed - * P - Manually set offset for probe - * E - Manually set offset for extruder - * - * With B, P, or E: - * I[index] - Index in the array - * V[value] - Adjustment in µm - */ -void GcodeSuite::M871() { - - if (parser.seen('R')) { - // Reset z-probe offsets to factory defaults - ptc.clear_all_offsets(); - SERIAL_ECHOLNPGM("Offsets reset to default."); - } - else if (parser.seen("BPE")) { - if (!parser.seenval('V')) return; - const int16_t offset_val = parser.value_int(); - if (!parser.seenval('I')) return; - const int16_t idx = parser.value_int(); - const TempSensorID mod = TERN_(PTC_BED, parser.seen_test('B') ? TSI_BED :) - TERN_(PTC_HOTEND, parser.seen_test('E') ? TSI_EXT :) - TERN_(PTC_PROBE, parser.seen_test('P') ? TSI_PROBE :) TSI_COUNT; - if (mod == TSI_COUNT) - SERIAL_ECHOLNPGM("!Invalid sensor."); - else if (idx > 0 && ptc.set_offset(mod, idx - 1, offset_val)) - SERIAL_ECHOLNPGM("Set value: ", offset_val); - else - SERIAL_ECHOLNPGM("!Invalid index. Failed to set value (note: value at index 0 is constant)."); - } - else // Print current Z-probe adjustments. Note: Values in EEPROM might differ. - ptc.print_offsets(); -} - -#endif // HAS_PTC diff --git a/src/gcode/calibrate/M100.cpp b/src/gcode/calibrate/M100.cpp deleted file mode 100644 index 338392b..0000000 --- a/src/gcode/calibrate/M100.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(M100_FREE_MEMORY_WATCHER) - -#include "../gcode.h" -#include "../queue.h" -#include "../../libs/hex_print.h" - -#include "../../MarlinCore.h" // for idle() - -/** - * 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(PGM_P const free_memory_start); - * void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size); - * - * Initial version by Roxy-3D - */ -#define M100_FREE_MEMORY_DUMPER // Enable for the `M100 D` Dump sub-command -#define M100_FREE_MEMORY_CORRUPTOR // Enable for the `M100 C` Corrupt sub-command - -#define TEST_BYTE ((char) 0xE5) - -#if EITHER(__AVR__, IS_32BIT_TEENSY) - - extern char __bss_end; - char *end_bss = &__bss_end, - *free_memory_start = end_bss, *free_memory_end = 0, - *stacklimit = 0, *heaplimit = 0; - - #define MEMORY_END_CORRECTION 0 - -#elif defined(TARGET_LPC1768) - - extern char __bss_end__, __StackLimit, __HeapLimit; - - char *end_bss = &__bss_end__, - *stacklimit = &__StackLimit, - *heaplimit = &__HeapLimit; - - #define MEMORY_END_CORRECTION 0x200 - - char *free_memory_start = heaplimit, - *free_memory_end = stacklimit - MEMORY_END_CORRECTION; - -#elif defined(__SAM3X8E__) - - extern char _ebss; - - char *end_bss = &_ebss, - *free_memory_start = end_bss, - *free_memory_end = 0, - *stacklimit = 0, - *heaplimit = 0; - - #define MEMORY_END_CORRECTION 0x10000 // need to stay well below 0x20080000 or M100 F crashes - -#elif defined(__SAMD51__) - - extern unsigned int __bss_end__, __StackLimit, __HeapLimit; - extern "C" void * _sbrk(int incr); - - void *end_bss = &__bss_end__, - *stacklimit = &__StackLimit, - *heaplimit = &__HeapLimit; - - #define MEMORY_END_CORRECTION 0x400 - - char *free_memory_start = (char *)_sbrk(0) + 0x200, // Leave some heap space - *free_memory_end = (char *)stacklimit - MEMORY_END_CORRECTION; - -#else - #error "M100 - unsupported CPU" -#endif - -// -// Utility functions -// - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-local-addr" - -// Location of a variable in its stack frame. -// The returned address will be above the stack (after it returns). -char *top_of_stack() { - char x; - return &x + 1; // x is pulled on return; -} - -#pragma GCC diagnostic pop - -// Count the number of test bytes at the specified location. -inline int32_t count_test_bytes(const char * const start_free_memory) { - for (uint32_t i = 0; i < 32000; i++) - if (char(start_free_memory[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(char *start_free_memory, char *end_free_memory) { - // - // Start and end the dump on a nice 16 byte boundary - // (even though the values are not 16-byte aligned). - // - start_free_memory = (char*)(uintptr_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary - end_free_memory = (char*)(uintptr_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory) - - // Dump command main loop - while (start_free_memory < end_free_memory) { - print_hex_address(start_free_memory); // Print the address - SERIAL_CHAR(':'); - LOOP_L_N(i, 16) { // and 16 data bytes - if (i == 8) SERIAL_CHAR('-'); - print_hex_byte(start_free_memory[i]); - SERIAL_CHAR(' '); - } - serial_delay(25); - SERIAL_CHAR('|'); // Point out non test bytes - LOOP_L_N(i, 16) { - char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken - ccc = (ccc == TEST_BYTE) ? ' ' : '?'; - SERIAL_CHAR(ccc); - } - SERIAL_EOL(); - start_free_memory += 16; - serial_delay(25); - idle(); - } - } - - void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size) { - SERIAL_ECHOLNF(title); - // - // Round the start and end locations to produce full lines of output - // - const char * const end = start + size - 1; - dump_free_memory( - (char*)(uintptr_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary - (char*)(uintptr_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory) - ); - } - -#endif // M100_FREE_MEMORY_DUMPER - -inline int check_for_free_memory_corruption(FSTR_P const title) { - SERIAL_ECHOF(title); - - char *start_free_memory = free_memory_start, *end_free_memory = free_memory_end; - int n = end_free_memory - start_free_memory; - - SERIAL_ECHOLNPGM("\nfmc() n=", n, - "\nfree_memory_start=", hex_address(free_memory_start), - " end=", hex_address(end_free_memory)); - - if (end_free_memory < start_free_memory) { - SERIAL_ECHOPGM(" end_free_memory < 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(); - serial_delay(20); - #if ENABLED(M100_FREE_MEMORY_DUMPER) - M100_dump_routine(F(" Memory corruption detected with end_free_memory 8) { - //SERIAL_ECHOPGM("Found ", j); - //SERIAL_ECHOLNPGM(" bytes free at ", hex_address(start_free_memory + i)); - i += j; - block_cnt++; - SERIAL_ECHOLNPGM(" (", block_cnt, ") found=", j); - } - } - } - SERIAL_ECHOPGM(" block_found=", block_cnt); - - if (block_cnt != 1) - 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; -} - -/** - * M100 F - * Return the number of free bytes in the memory pool, - * with other vital statistics defining the pool. - */ -inline void free_memory_pool_report(char * const start_free_memory, const int32_t size) { - int32_t max_cnt = -1, block_cnt = 0; - char *max_addr = nullptr; - // Find the longest block of test bytes in the buffer - for (int32_t i = 0; i < size; i++) { - char *addr = start_free_memory + i; - if (*addr == TEST_BYTE) { - const int32_t j = count_test_bytes(addr); - if (j > 8) { - SERIAL_ECHOLNPGM("Found ", j, " 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." - "\nLargest free block is ", max_cnt, " bytes at ", hex_address(max_addr) - ); - SERIAL_ECHOLNPGM("check_for_free_memory_corruption() = ", check_for_free_memory_corruption(F("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. - */ - inline void corrupt_free_memory(char *start_free_memory, const uintptr_t size) { - start_free_memory += 8; - const uint32_t near_top = top_of_stack() - start_free_memory - 250, // -250 to avoid interrupt activity that's altered the stack. - j = near_top / (size + 1); - - SERIAL_ECHOLNPGM("Corrupting free memory block."); - for (uint32_t i = 1; i <= size; i++) { - char * const addr = start_free_memory + i * j; - *addr = i; - SERIAL_ECHOPGM("\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.) - */ -inline void init_free_memory(char *start_free_memory, int32_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; - } - - start_free_memory += 8; // move a few bytes away from the heap just because we - // don't want to be altering memory that close to it. - memset(start_free_memory, TEST_BYTE, size); - - SERIAL_ECHO(size); - SERIAL_ECHOLNPGM(" bytes of memory initialized.\n"); - - for (int32_t i = 0; i < size; i++) { - if (start_free_memory[i] != TEST_BYTE) { - SERIAL_ECHOPGM("? address : ", hex_address(start_free_memory + i)); - SERIAL_ECHOLNPGM("=", hex_byte(start_free_memory[i])); - SERIAL_EOL(); - } - } -} - -/** - * M100: Free Memory Check - */ -void GcodeSuite::M100() { - char *sp = top_of_stack(); - if (!free_memory_end) free_memory_end = sp - MEMORY_END_CORRECTION; - SERIAL_ECHOPGM("\nbss_end : ", hex_address(end_bss)); - if (heaplimit) SERIAL_ECHOPGM("\n__heaplimit : ", hex_address(heaplimit)); - SERIAL_ECHOPGM("\nfree_memory_start : ", hex_address(free_memory_start)); - if (stacklimit) SERIAL_ECHOPGM("\n__stacklimit : ", hex_address(stacklimit)); - SERIAL_ECHOPGM("\nfree_memory_end : ", hex_address(free_memory_end)); - if (MEMORY_END_CORRECTION) - SERIAL_ECHOPGM("\nMEMORY_END_CORRECTION : ", MEMORY_END_CORRECTION); - SERIAL_ECHOLNPGM("\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(free_memory_start, free_memory_end - free_memory_start); - } - - #if ENABLED(M100_FREE_MEMORY_DUMPER) - if (parser.seen('D')) - return dump_free_memory(free_memory_start, free_memory_end); - #endif - - if (parser.seen('F')) - return free_memory_pool_report(free_memory_start, free_memory_end - free_memory_start); - - #if ENABLED(M100_FREE_MEMORY_CORRUPTOR) - if (parser.seen('C')) - return corrupt_free_memory(free_memory_start, parser.value_int()); - #endif -} - -#endif // M100_FREE_MEMORY_WATCHER diff --git a/src/gcode/calibrate/M12.cpp b/src/gcode/calibrate/M12.cpp deleted file mode 100644 index 191ff22..0000000 --- a/src/gcode/calibrate/M12.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER) - -#include "../gcode.h" -#include "../../module/planner.h" -#include "../../feature/closedloop.h" - -void GcodeSuite::M12() { - - planner.synchronize(); - - if (parser.seenval('S')) - closedloop.set(parser.value_int()); // Force a CLC set - -} - -#endif diff --git a/src/gcode/calibrate/M425.cpp b/src/gcode/calibrate/M425.cpp deleted file mode 100644 index ba262c5..0000000 --- a/src/gcode/calibrate/M425.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(BACKLASH_GCODE) - -#include "../../feature/backlash.h" -#include "../../module/planner.h" - -#include "../gcode.h" - -/** - * M425: Enable and tune backlash correction. - * - * F Enable/disable/fade-out backlash correction (0.0 to 1.0) - * S Distance over which backlash correction is spread - * X Set the backlash distance on X (0 to disable) - * Y ... on Y - * Z ... on Z - * X If a backlash measurement was done on X, copy that value - * Y ... on Y - * Z ... on Z - * - * Type M425 without any arguments to show active values. - */ -void GcodeSuite::M425() { - bool noArgs = true; - - auto axis_can_calibrate = [](const uint8_t a) { - #define _CAN_CASE(N) case N##_AXIS: return AXIS_CAN_CALIBRATE(N); - switch (a) { - default: return false; - MAIN_AXIS_MAP(_CAN_CASE) - } - }; - - LOOP_NUM_AXES(a) { - if (axis_can_calibrate(a) && parser.seen(AXIS_CHAR(a))) { - planner.synchronize(); - backlash.set_distance_mm((AxisEnum)a, parser.has_value() ? parser.value_axis_units((AxisEnum)a) : backlash.get_measurement((AxisEnum)a)); - noArgs = false; - } - } - - if (parser.seen('F')) { - planner.synchronize(); - backlash.set_correction(parser.value_float()); - noArgs = false; - } - - #ifdef BACKLASH_SMOOTHING_MM - if (parser.seen('S')) { - planner.synchronize(); - backlash.set_smoothing_mm(parser.value_linear_units()); - noArgs = false; - } - #endif - - if (noArgs) { - SERIAL_ECHOPGM("Backlash Correction "); - if (!backlash.get_correction_uint8()) SERIAL_ECHOPGM("in"); - SERIAL_ECHOLNPGM("active:"); - SERIAL_ECHOLNPGM(" Correction Amount/Fade-out: F", backlash.get_correction(), " (F1.0 = full, F0.0 = none)"); - SERIAL_ECHOPGM(" Backlash Distance (mm): "); - LOOP_NUM_AXES(a) if (axis_can_calibrate(a)) { - SERIAL_ECHOLNPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a]), backlash.get_distance_mm((AxisEnum)a)); - } - - #ifdef BACKLASH_SMOOTHING_MM - SERIAL_ECHOLNPGM(" Smoothing (mm): S", backlash.get_smoothing_mm()); - #endif - - #if ENABLED(MEASURE_BACKLASH_WHEN_PROBING) - SERIAL_ECHOPGM(" Average measured backlash (mm):"); - if (backlash.has_any_measurement()) { - LOOP_NUM_AXES(a) if (axis_can_calibrate(a) && backlash.has_measurement(AxisEnum(a))) { - SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a]), backlash.get_measurement((AxisEnum)a)); - } - } - else - SERIAL_ECHOPGM(" (Not yet measured)"); - SERIAL_EOL(); - #endif - } -} - -void GcodeSuite::M425_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_BACKLASH_COMPENSATION)); - SERIAL_ECHOLNPGM_P( - PSTR(" M425 F"), backlash.get_correction() - #ifdef BACKLASH_SMOOTHING_MM - , PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm()) - #endif - , LIST_N(DOUBLE(NUM_AXES), - SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)), - SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)), - SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)), - SP_I_STR, LINEAR_UNIT(backlash.get_distance_mm(I_AXIS)), - SP_J_STR, LINEAR_UNIT(backlash.get_distance_mm(J_AXIS)), - SP_K_STR, LINEAR_UNIT(backlash.get_distance_mm(K_AXIS)) - ) - ); -} - -#endif // BACKLASH_GCODE diff --git a/src/gcode/calibrate/M48.cpp b/src/gcode/calibrate/M48.cpp deleted file mode 100644 index 8b6ea0b..0000000 --- a/src/gcode/calibrate/M48.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST) - -#include "../gcode.h" -#include "../../module/motion.h" -#include "../../module/probe.h" -#include "../../lcd/marlinui.h" - -#include "../../feature/bedlevel/bedlevel.h" - -#if HAS_LEVELING - #include "../../module/planner.h" -#endif - -#if HAS_PTC - #include "../../feature/probe_temp_comp.h" -#endif - -/** - * 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) - * C = Enable probe temperature compensation (0 or 1, default 1) - * - * This function requires the machine to be homed before invocation. - */ - -void GcodeSuite::M48() { - - if (homing_needed_error()) return; - - const int8_t verbose_level = parser.byteval('V', 1); - if (!WITHIN(verbose_level, 0, 4)) { - SERIAL_ECHOLNPGM("?(V)erbose level implausible (0-4)."); - return; - } - - if (verbose_level > 0) - SERIAL_ECHOLNPGM("M48 Z-Probe Repeatability Test"); - - const int8_t n_samples = parser.byteval('P', 10); - if (!WITHIN(n_samples, 4, 50)) { - SERIAL_ECHOLNPGM("?Sample size not plausible (4-50)."); - return; - } - - const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE; - - // Test at the current position by default, overridden by X and Y - const xy_pos_t test_position = { - parser.linearval('X', current_position.x + probe.offset_xy.x), // If no X use the probe's current X position - parser.linearval('Y', current_position.y + probe.offset_xy.y) // If no Y, ditto - }; - - if (!probe.can_reach(test_position)) { - ui.set_status(GET_TEXT_F(MSG_M48_OUT_OF_BOUNDS), 99); - SERIAL_ECHOLNPGM("? (X,Y) out of bounds."); - return; - } - - // Get the number of leg moves per test-point - bool seen_L = parser.seen('L'); - uint8_t n_legs = seen_L ? parser.value_byte() : 0; - if (n_legs > 15) { - SERIAL_ECHOLNPGM("?Legs of movement implausible (0-15)."); - return; - } - if (n_legs == 1) n_legs = 2; - - // Schizoid motion as an optional stress-test - const bool schizoid_flag = parser.boolval('S'); - if (schizoid_flag && !seen_L) n_legs = 7; - - if (verbose_level > 2) - SERIAL_ECHOLNPGM("Positioning the probe..."); - - // Always disable Bed Level correction before probing... - - #if HAS_LEVELING - const bool was_enabled = planner.leveling_active; - set_bed_leveling_enabled(false); - #endif - - TERN_(HAS_PTC, ptc.set_enabled(!parser.seen('C') || parser.value_bool())); - - // Work with reasonable feedrates - remember_feedrate_scaling_off(); - - // Working variables - float mean = 0.0, // The average of all points so far, used to calculate deviation - sigma = 0.0, // Standard deviation of all points so far - min = 99999.9, // Smallest value sampled so far - max = -99999.9, // Largest value sampled so far - sample_set[n_samples]; // Storage for sampled values - - auto dev_report = [](const bool verbose, const_float_t mean, const_float_t sigma, const_float_t min, const_float_t max, const bool final=false) { - if (verbose) { - SERIAL_ECHOPAIR_F("Mean: ", mean, 6); - if (!final) SERIAL_ECHOPAIR_F(" Sigma: ", sigma, 6); - SERIAL_ECHOPAIR_F(" Min: ", min, 3); - SERIAL_ECHOPAIR_F(" Max: ", max, 3); - SERIAL_ECHOPAIR_F(" Range: ", max-min, 3); - if (final) SERIAL_EOL(); - } - if (final) { - SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6); - SERIAL_EOL(); - } - }; - - // Move to the first point, deploy, and probe - const float t = probe.probe_at_point(test_position, raise_after, verbose_level); - bool probing_good = !isnan(t); - - if (probing_good) { - randomSeed(millis()); - - float sample_sum = 0.0; - - LOOP_L_N(n, n_samples) { - #if HAS_STATUS_MESSAGE - // Display M48 progress in the status bar - ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples)); - #endif - - // When there are "legs" of movement move around the point before probing - if (n_legs) { - - // Pick a random direction, starting angle, and radius - const int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise - float angle = random(0, 360); - const float radius = random( - #if ENABLED(DELTA) - int(0.1250000000 * (DELTA_PRINTABLE_RADIUS)), - int(0.3333333333 * (DELTA_PRINTABLE_RADIUS)) - #else - int(5), int(0.125 * _MIN(X_BED_SIZE, Y_BED_SIZE)) - #endif - ); - if (verbose_level > 3) { - SERIAL_ECHOPGM("Start radius:", radius, " angle:", angle, " dir:"); - if (dir > 0) SERIAL_CHAR('C'); - SERIAL_ECHOLNPGM("CW"); - } - - // Move from leg to leg in rapid succession - LOOP_L_N(l, n_legs - 1) { - - // Move some distance around the perimeter - float delta_angle; - if (schizoid_flag) { - // The points of a 5 point star are 72 degrees apart. - // Skip a point and go to the next one on the star. - delta_angle = dir * 2.0 * 72.0; - } - else { - // Just move further along the perimeter. - delta_angle = dir * (float)random(25, 45); - } - angle += delta_angle; - - // Trig functions work without clamping, but just to be safe... - while (angle > 360.0) angle -= 360.0; - while (angle < 0.0) angle += 360.0; - - // Choose the next position as an offset to chosen test position - const xy_pos_t noz_pos = test_position - probe.offset_xy; - xy_pos_t next_pos = { - noz_pos.x + float(cos(RADIANS(angle))) * radius, - noz_pos.y + float(sin(RADIANS(angle))) * radius - }; - - #if ENABLED(DELTA) - // If the probe can't reach the point on a round bed... - // Simply scale the numbers to bring them closer to origin. - while (!probe.can_reach(next_pos)) { - next_pos *= 0.8f; - if (verbose_level > 3) - SERIAL_ECHOLNPGM_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y); - } - #elif HAS_ENDSTOPS - // For a rectangular bed just keep the probe in bounds - LIMIT(next_pos.x, X_MIN_POS, X_MAX_POS); - LIMIT(next_pos.y, Y_MIN_POS, Y_MAX_POS); - #endif - - if (verbose_level > 3) - SERIAL_ECHOLNPGM_P(PSTR("Going to: X"), next_pos.x, SP_Y_STR, next_pos.y); - - do_blocking_move_to_xy(next_pos); - } // n_legs loop - } // n_legs - - // Probe a single point - const float pz = probe.probe_at_point(test_position, raise_after, 0); - - // Break the loop if the probe fails - probing_good = !isnan(pz); - if (!probing_good) break; - - // Store the new sample - sample_set[n] = pz; - - // Keep track of the largest and smallest samples - NOMORE(min, pz); - NOLESS(max, pz); - - // Get the mean value of all samples thus far - sample_sum += pz; - mean = sample_sum / (n + 1); - - // Calculate the standard deviation so far. - // The value after the last sample will be the final output. - float dev_sum = 0.0; - LOOP_LE_N(j, n) dev_sum += sq(sample_set[j] - mean); - sigma = SQRT(dev_sum / (n + 1)); - - if (verbose_level > 1) { - SERIAL_ECHO(n + 1); - SERIAL_ECHOPGM(" of ", n_samples); - SERIAL_ECHOPAIR_F(": z: ", pz, 3); - SERIAL_CHAR(' '); - dev_report(verbose_level > 2, mean, sigma, min, max); - SERIAL_EOL(); - } - - } // n_samples loop - } - - probe.stow(); - - if (probing_good) { - SERIAL_ECHOLNPGM("Finished!"); - dev_report(verbose_level > 0, mean, sigma, min, max, true); - - #if HAS_STATUS_MESSAGE - // Display M48 results in the status bar - char sigma_str[8]; - ui.status_printf(0, F(S_FMT ": %s"), GET_TEXT(MSG_M48_DEVIATION), dtostrf(sigma, 2, 6, sigma_str)); - #endif - } - - restore_feedrate_and_scaling(); - - // Re-enable bed level correction if it had been on - TERN_(HAS_LEVELING, set_bed_leveling_enabled(was_enabled)); - - // Re-enable probe temperature correction - TERN_(HAS_PTC, ptc.set_enabled(true)); - - report_current_position(); -} - -#endif // Z_MIN_PROBE_REPEATABILITY_TEST diff --git a/src/gcode/calibrate/M665.cpp b/src/gcode/calibrate/M665.cpp deleted file mode 100644 index 7dc657a..0000000 --- a/src/gcode/calibrate/M665.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if IS_KINEMATIC - -#include "../gcode.h" -#include "../../module/motion.h" - -#if ENABLED(DELTA) - - #include "../../module/delta.h" - - /** - * M665: Set delta configurations - * - * H = delta height - * L = diagonal rod - * R = delta radius - * S = segments per second - * X = Alpha (Tower 1) angle trim - * Y = Beta (Tower 2) angle trim - * Z = Gamma (Tower 3) angle trim - * A = Alpha (Tower 1) diagonal rod trim - * B = Beta (Tower 2) diagonal rod trim - * C = Gamma (Tower 3) diagonal rod trim - */ - void GcodeSuite::M665() { - if (!parser.seen_any()) return M665_report(); - - if (parser.seenval('H')) delta_height = parser.value_linear_units(); - if (parser.seenval('L')) delta_diagonal_rod = parser.value_linear_units(); - if (parser.seenval('R')) delta_radius = parser.value_linear_units(); - if (parser.seenval('S')) segments_per_second = parser.value_float(); - if (parser.seenval('X')) delta_tower_angle_trim.a = parser.value_float(); - if (parser.seenval('Y')) delta_tower_angle_trim.b = parser.value_float(); - if (parser.seenval('Z')) delta_tower_angle_trim.c = parser.value_float(); - if (parser.seenval('A')) delta_diagonal_rod_trim.a = parser.value_float(); - if (parser.seenval('B')) delta_diagonal_rod_trim.b = parser.value_float(); - if (parser.seenval('C')) delta_diagonal_rod_trim.c = parser.value_float(); - recalc_delta_settings(); - } - - void GcodeSuite::M665_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_DELTA_SETTINGS)); - SERIAL_ECHOLNPGM_P( - PSTR(" M665 L"), LINEAR_UNIT(delta_diagonal_rod) - , PSTR(" R"), LINEAR_UNIT(delta_radius) - , PSTR(" H"), LINEAR_UNIT(delta_height) - , PSTR(" S"), segments_per_second - , SP_X_STR, LINEAR_UNIT(delta_tower_angle_trim.a) - , SP_Y_STR, LINEAR_UNIT(delta_tower_angle_trim.b) - , SP_Z_STR, LINEAR_UNIT(delta_tower_angle_trim.c) - , PSTR(" A"), LINEAR_UNIT(delta_diagonal_rod_trim.a) - , PSTR(" B"), LINEAR_UNIT(delta_diagonal_rod_trim.b) - , PSTR(" C"), LINEAR_UNIT(delta_diagonal_rod_trim.c) - ); - } - -#elif IS_SCARA - - #include "../../module/scara.h" - - /** - * M665: Set SCARA settings - * - * Parameters: - * - * S[segments] - Segments-per-second - * - * Without NO_WORKSPACE_OFFSETS: - * - * 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 - * Z[z-offset] - Z offset, added to Z - * - * A, P, and X are all aliases for the shoulder angle - * B, T, and Y are all aliases for the elbow angle - */ - void GcodeSuite::M665() { - if (!parser.seen_any()) return M665_report(); - - if (parser.seenval('S')) segments_per_second = parser.value_float(); - - #if HAS_SCARA_OFFSET - - if (parser.seenval('Z')) scara_home_offset.z = parser.value_linear_units(); - - const bool hasA = parser.seenval('A'), hasP = parser.seenval('P'), hasX = parser.seenval('X'); - const uint8_t sumAPX = hasA + hasP + hasX; - if (sumAPX) { - if (sumAPX == 1) - scara_home_offset.a = parser.value_float(); - else { - SERIAL_ERROR_MSG("Only one of A, P, or X is allowed."); - return; - } - } - - const bool hasB = parser.seenval('B'), hasT = parser.seenval('T'), hasY = parser.seenval('Y'); - const uint8_t sumBTY = hasB + hasT + hasY; - if (sumBTY) { - if (sumBTY == 1) - scara_home_offset.b = parser.value_float(); - else { - SERIAL_ERROR_MSG("Only one of B, T, or Y is allowed."); - return; - } - } - - #endif // HAS_SCARA_OFFSET - } - - void GcodeSuite::M665_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_SCARA_SETTINGS " (" STR_S_SEG_PER_SEC TERN_(HAS_SCARA_OFFSET, " " STR_SCARA_P_T_Z) ")")); - SERIAL_ECHOLNPGM_P( - PSTR(" M665 S"), segments_per_second - #if HAS_SCARA_OFFSET - , SP_P_STR, scara_home_offset.a - , SP_T_STR, scara_home_offset.b - , SP_Z_STR, LINEAR_UNIT(scara_home_offset.z) - #endif - ); - } - -#elif ENABLED(POLARGRAPH) - - #include "../../module/polargraph.h" - - /** - * M665: Set POLARGRAPH settings - * - * Parameters: - * - * S[segments] - Segments-per-second - * L[left] - Work area minimum X - * R[right] - Work area maximum X - * T[top] - Work area maximum Y - * B[bottom] - Work area minimum Y - * H[length] - Maximum belt length - */ - void GcodeSuite::M665() { - if (!parser.seen_any()) return M665_report(); - if (parser.seenval('S')) segments_per_second = parser.value_float(); - if (parser.seenval('L')) draw_area_min.x = parser.value_linear_units(); - if (parser.seenval('R')) draw_area_max.x = parser.value_linear_units(); - if (parser.seenval('T')) draw_area_max.y = parser.value_linear_units(); - if (parser.seenval('B')) draw_area_min.y = parser.value_linear_units(); - if (parser.seenval('H')) polargraph_max_belt_len = parser.value_linear_units(); - draw_area_size.x = draw_area_max.x - draw_area_min.x; - draw_area_size.y = draw_area_max.y - draw_area_min.y; - } - - void GcodeSuite::M665_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_POLARGRAPH_SETTINGS)); - SERIAL_ECHOLNPGM_P( - PSTR(" M665 S"), LINEAR_UNIT(segments_per_second), - PSTR(" L"), LINEAR_UNIT(draw_area_min.x), - PSTR(" R"), LINEAR_UNIT(draw_area_max.x), - SP_T_STR, LINEAR_UNIT(draw_area_max.y), - SP_B_STR, LINEAR_UNIT(draw_area_min.y), - PSTR(" H"), LINEAR_UNIT(polargraph_max_belt_len) - ); - } - -#endif - -#endif // IS_KINEMATIC diff --git a/src/gcode/calibrate/M666.cpp b/src/gcode/calibrate/M666.cpp deleted file mode 100644 index 90fad18..0000000 --- a/src/gcode/calibrate/M666.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS - -#include "../gcode.h" - -#if ENABLED(DELTA) - #include "../../module/delta.h" - #include "../../module/motion.h" -#else - #include "../../module/endstops.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -#if ENABLED(DELTA) - - /** - * M666: Set delta endstop adjustment - */ - void GcodeSuite::M666() { - DEBUG_SECTION(log_M666, "M666", DEBUGGING(LEVELING)); - bool is_err = false, is_set = false; - LOOP_NUM_AXES(i) { - if (parser.seenval(AXIS_CHAR(i))) { - is_set = true; - const float v = parser.value_linear_units(); - if (v > 0) - is_err = true; - else { - delta_endstop_adj[i] = v; - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj[", AS_CHAR(AXIS_CHAR(i)), "] = ", v); - } - } - } - if (is_err) SERIAL_ECHOLNPGM("?M666 offsets must be <= 0"); - if (!is_set) M666_report(); - } - - void GcodeSuite::M666_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_ENDSTOP_ADJUSTMENT)); - SERIAL_ECHOLNPGM_P( - PSTR(" M666 X"), LINEAR_UNIT(delta_endstop_adj.a) - , SP_Y_STR, LINEAR_UNIT(delta_endstop_adj.b) - , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c) - ); - } - -#else - - /** - * M666: Set Dual Endstops offsets for X, Y, and/or Z. - * With no parameters report current offsets. - * - * For Triple / Quad Z Endstops: - * Set Z2 Only: M666 S2 Z - * Set Z3 Only: M666 S3 Z - * Set Z4 Only: M666 S4 Z - * Set All: M666 Z - */ - void GcodeSuite::M666() { - if (!parser.seen_any()) return M666_report(); - - #if ENABLED(X_DUAL_ENDSTOPS) - if (parser.seenval('X')) endstops.x2_endstop_adj = parser.value_linear_units(); - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - if (parser.seenval('Y')) endstops.y2_endstop_adj = parser.value_linear_units(); - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - if (parser.seenval('Z')) { - const float z_adj = parser.value_linear_units(); - #if NUM_Z_STEPPERS == 2 - endstops.z2_endstop_adj = z_adj; - #else - const int ind = parser.intval('S'); - #define _SET_ZADJ(N) if (!ind || ind == N) endstops.z##N##_endstop_adj = z_adj; - REPEAT_S(2, INCREMENT(NUM_Z_STEPPERS), _SET_ZADJ) - #endif - } - #endif - } - - void GcodeSuite::M666_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_ENDSTOP_ADJUSTMENT)); - SERIAL_ECHOPGM(" M666"); - #if ENABLED(X_DUAL_ENDSTOPS) - SERIAL_ECHOLNPGM_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj)); - #endif - #if ENABLED(Y_DUAL_ENDSTOPS) - SERIAL_ECHOLNPGM_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj)); - #endif - #if ENABLED(Z_MULTI_ENDSTOPS) - #if NUM_Z_STEPPERS >= 3 - SERIAL_ECHOPGM(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj)); - report_echo_start(forReplay); - SERIAL_ECHOPGM(" M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj)); - #if NUM_Z_STEPPERS >= 4 - report_echo_start(forReplay); - SERIAL_ECHOPGM(" M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj)); - #endif - #else - SERIAL_ECHOLNPGM_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj)); - #endif - #endif - } - -#endif // HAS_EXTRA_ENDSTOPS - -#endif // DELTA || HAS_EXTRA_ENDSTOPS diff --git a/src/gcode/calibrate/M852.cpp b/src/gcode/calibrate/M852.cpp deleted file mode 100644 index 6c661dc..0000000 --- a/src/gcode/calibrate/M852.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SKEW_CORRECTION_GCODE) - -#include "../gcode.h" -#include "../../module/planner.h" - -/** - * M852: Get or set the machine skew factors. Reports current values with no arguments. - * - * S[xy_factor] - Alias for 'I' - * I[xy_factor] - New XY skew factor - * J[xz_factor] - New XZ skew factor - * K[yz_factor] - New YZ skew factor - */ -void GcodeSuite::M852() { - if (!parser.seen("SIJK")) return M852_report(); - - uint8_t badval = 0, setval = 0; - - if (parser.seenval('I') || parser.seenval('S')) { - const float value = parser.value_linear_units(); - if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { - if (planner.skew_factor.xy != value) { - planner.skew_factor.xy = value; - ++setval; - } - } - else - ++badval; - } - - #if ENABLED(SKEW_CORRECTION_FOR_Z) - - if (parser.seenval('J')) { - const float value = parser.value_linear_units(); - if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { - if (planner.skew_factor.xz != value) { - planner.skew_factor.xz = value; - ++setval; - } - } - else - ++badval; - } - - if (parser.seenval('K')) { - const float value = parser.value_linear_units(); - if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { - if (planner.skew_factor.yz != value) { - planner.skew_factor.yz = value; - ++setval; - } - } - else - ++badval; - } - - #endif - - if (badval) - SERIAL_ECHOLNPGM(STR_SKEW_MIN " " STRINGIFY(SKEW_FACTOR_MIN) " " STR_SKEW_MAX " " STRINGIFY(SKEW_FACTOR_MAX)); - - // When skew is changed the current position changes - if (setval) { - set_current_from_steppers_for_axis(ALL_AXES_ENUM); - sync_plan_position(); - report_current_position(); - } -} - -void GcodeSuite::M852_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_SKEW_FACTOR)); - SERIAL_ECHOPAIR_F(" M852 I", planner.skew_factor.xy, 6); - #if ENABLED(SKEW_CORRECTION_FOR_Z) - SERIAL_ECHOPAIR_F(" J", planner.skew_factor.xz, 6); - SERIAL_ECHOPAIR_F(" K", planner.skew_factor.yz, 6); - SERIAL_ECHOLNPGM(" ; XY, XZ, YZ"); - #else - SERIAL_ECHOLNPGM(" ; XY"); - #endif -} - -#endif // SKEW_CORRECTION_GCODE diff --git a/src/gcode/config/M200-M205.cpp b/src/gcode/config/M200-M205.cpp deleted file mode 100644 index 4190d40..0000000 --- a/src/gcode/config/M200-M205.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../MarlinCore.h" -#include "../../module/planner.h" - -#if DISABLED(NO_VOLUMETRICS) - - /** - * M200: Set filament diameter and set E axis units to cubic units - * - * T - Optional extruder number. Current extruder if omitted. - * D - Set filament diameter and enable. D0 disables volumetric. - * S - Turn volumetric ON or OFF. - * - * With VOLUMETRIC_EXTRUDER_LIMIT: - * - * L - Volumetric extruder limit (in mm^3/sec). L0 disables the limit. - */ - void GcodeSuite::M200() { - if (!parser.seen("DST" TERN_(VOLUMETRIC_EXTRUDER_LIMIT, "L"))) - return M200_report(); - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - bool vol_enable = parser.volumetric_enabled, - can_enable = true; - - if (parser.seenval('D')) { - const float dval = parser.value_linear_units(); - if (dval) { // Set filament size for volumetric calculation - planner.set_filament_size(target_extruder, dval); - vol_enable = true; // Dn = enable for compatibility - } - else - can_enable = false; // D0 = disable for compatibility - } - - // Enable or disable with S1 / S0 - parser.volumetric_enabled = can_enable && parser.boolval('S', vol_enable); - - #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - if (parser.seenval('L')) { - // Set volumetric limit (in mm^3/sec) - const float lval = parser.value_float(); - if (WITHIN(lval, 0, 20)) - planner.set_volumetric_extruder_limit(target_extruder, lval); - else - SERIAL_ECHOLNPGM("?L value out of range (0-20)."); - } - #endif - - planner.calculate_volumetric_multipliers(); - } - - void GcodeSuite::M200_report(const bool forReplay/*=true*/) { - if (!forReplay) { - report_heading(forReplay, F(STR_FILAMENT_SETTINGS), false); - if (!parser.volumetric_enabled) SERIAL_ECHOPGM(" (Disabled):"); - SERIAL_EOL(); - report_echo_start(forReplay); - } - - #if EXTRUDERS == 1 - { - SERIAL_ECHOLNPGM( - " M200 S", parser.volumetric_enabled, " D", LINEAR_UNIT(planner.filament_size[0]) - #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[0]) - #endif - ); - } - #else - SERIAL_ECHOLNPGM(" M200 S", parser.volumetric_enabled); - EXTRUDER_LOOP() { - report_echo_start(forReplay); - SERIAL_ECHOLNPGM( - " M200 T", e, " D", LINEAR_UNIT(planner.filament_size[e]) - #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) - , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[e]) - #endif - ); - } - #endif - } - -#endif // !NO_VOLUMETRICS - -/** - * M201: Set max acceleration in units/s^2 for print moves. - * - * X : Max Acceleration for X - * Y : Max Acceleration for Y - * Z : Max Acceleration for Z - * ... : etc - * E : Max Acceleration for Extruder - * T : Extruder index to set - * - * With XY_FREQUENCY_LIMIT: - * F : Frequency limit for XY...IJKUVW - * S : Speed factor percentage. - */ -void GcodeSuite::M201() { - if (!parser.seen("T" STR_AXES_LOGICAL TERN_(XY_FREQUENCY_LIMIT, "FS"))) - return M201_report(); - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - #ifdef XY_FREQUENCY_LIMIT - if (parser.seenval('F')) planner.set_frequency_limit(parser.value_byte()); - if (parser.seenval('S')) planner.xy_freq_min_speed_factor = constrain(parser.value_float(), 1, 100) / 100; - #endif - - LOOP_LOGICAL_AXES(i) { - if (parser.seenval(AXIS_CHAR(i))) { - const AxisEnum a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? E_AXIS_N(target_extruder) : (AxisEnum)i), (AxisEnum)i); - planner.set_max_acceleration(a, parser.value_axis_units(a)); - } - } -} - -void GcodeSuite::M201_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_MAX_ACCELERATION)); - SERIAL_ECHOLNPGM_P( - LIST_N(DOUBLE(NUM_AXES), - PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]), - SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]), - SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]), - SP_I_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]), - SP_J_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]), - SP_K_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]) - ) - #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS) - , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS]) - #endif - ); - #if ENABLED(DISTINCT_E_FACTORS) - LOOP_L_N(i, E_STEPPERS) { - report_echo_start(forReplay); - SERIAL_ECHOLNPGM_P( - PSTR(" M201 T"), i - , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(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. - */ -void GcodeSuite::M203() { - if (!parser.seen("T" STR_AXES_LOGICAL)) - return M203_report(); - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - LOOP_LOGICAL_AXES(i) - if (parser.seenval(AXIS_CHAR(i))) { - const AxisEnum a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? E_AXIS_N(target_extruder) : (AxisEnum)i), (AxisEnum)i); - planner.set_max_feedrate(a, parser.value_axis_units(a)); - } -} - -void GcodeSuite::M203_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_MAX_FEEDRATES)); - SERIAL_ECHOLNPGM_P( - LIST_N(DOUBLE(NUM_AXES), - PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]), - SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]), - SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]), - SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]), - SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]), - SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]) - ) - #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS) - , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS]) - #endif - ); - #if ENABLED(DISTINCT_E_FACTORS) - LOOP_L_N(i, E_STEPPERS) { - if (!forReplay) SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM_P( - PSTR(" M203 T"), i - , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS_N(i)]) - ); - } - #endif -} - -/** - * 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 - */ -void GcodeSuite::M204() { - if (!parser.seen("PRST")) - return M204_report(); - else { - //planner.synchronize(); - // 'S' for legacy compatibility. Should NOT BE USED for new development - if (parser.seenval('S')) planner.settings.travel_acceleration = planner.settings.acceleration = parser.value_linear_units(); - if (parser.seenval('P')) planner.settings.acceleration = parser.value_linear_units(); - if (parser.seenval('R')) planner.settings.retract_acceleration = parser.value_linear_units(); - if (parser.seenval('T')) planner.settings.travel_acceleration = parser.value_linear_units(); - } -} - -void GcodeSuite::M204_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_ACCELERATION_P_R_T)); - SERIAL_ECHOLNPGM_P( - PSTR(" M204 P"), LINEAR_UNIT(planner.settings.acceleration) - , PSTR(" R"), LINEAR_UNIT(planner.settings.retract_acceleration) - , SP_T_STR, LINEAR_UNIT(planner.settings.travel_acceleration) - ); -} - -/** - * M205: Set Advanced Settings - * - * B = Min Segment Time (µs) - * S = Min Feed Rate (units/s) - * T = Min Travel Feed Rate (units/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) - * J = Junction Deviation (mm) (If not using CLASSIC_JERK) - */ -void GcodeSuite::M205() { - if (!parser.seen("BST" TERN_(HAS_JUNCTION_DEVIATION, "J") TERN_(HAS_CLASSIC_JERK, "XYZE"))) - return M205_report(); - - //planner.synchronize(); - if (parser.seenval('B')) planner.settings.min_segment_time_us = parser.value_ulong(); - if (parser.seenval('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units(); - if (parser.seenval('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units(); - #if HAS_JUNCTION_DEVIATION - #if HAS_CLASSIC_JERK && AXIS_COLLISION('J') - #error "Can't set_max_jerk for 'J' axis because 'J' is used for Junction Deviation." - #endif - if (parser.seenval('J')) { - const float junc_dev = parser.value_linear_units(); - if (WITHIN(junc_dev, 0.01f, 0.3f)) { - planner.junction_deviation_mm = junc_dev; - TERN_(LIN_ADVANCE, planner.recalculate_max_e_jerk()); - } - else - SERIAL_ERROR_MSG("?J out of range (0.01 to 0.3)"); - } - #endif - #if HAS_CLASSIC_JERK - bool seenZ = false; - LOGICAL_AXIS_CODE( - if (parser.seenval('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units()), - if (parser.seenval('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units()), - if (parser.seenval('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units()), - if ((seenZ = parser.seenval('Z'))) planner.set_max_jerk(Z_AXIS, parser.value_linear_units()), - if (parser.seenval(AXIS4_NAME)) planner.set_max_jerk(I_AXIS, parser.value_linear_units()), - if (parser.seenval(AXIS5_NAME)) planner.set_max_jerk(J_AXIS, parser.value_linear_units()), - if (parser.seenval(AXIS6_NAME)) planner.set_max_jerk(K_AXIS, parser.value_linear_units()) - ); - #if HAS_MESH && DISABLED(LIMITED_JERK_EDITING) - if (seenZ && planner.max_jerk.z <= 0.1f) - SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses."); - #endif - #endif // HAS_CLASSIC_JERK -} - -void GcodeSuite::M205_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F( - "Advanced (B S T" - TERN_(HAS_JUNCTION_DEVIATION, " J") - #if HAS_CLASSIC_JERK - NUM_AXIS_GANG( - " X", " Y", " Z", - " " STR_I "", " " STR_J "", " " STR_K "" - ) - #endif - TERN_(HAS_CLASSIC_E_JERK, " E") - ")" - )); - SERIAL_ECHOLNPGM_P( - PSTR(" M205 B"), LINEAR_UNIT(planner.settings.min_segment_time_us) - , PSTR(" S"), LINEAR_UNIT(planner.settings.min_feedrate_mm_s) - , SP_T_STR, LINEAR_UNIT(planner.settings.min_travel_feedrate_mm_s) - #if HAS_JUNCTION_DEVIATION - , PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm) - #endif - #if HAS_CLASSIC_JERK - , LIST_N(DOUBLE(NUM_AXES), - SP_X_STR, LINEAR_UNIT(planner.max_jerk.x), - SP_Y_STR, LINEAR_UNIT(planner.max_jerk.y), - SP_Z_STR, LINEAR_UNIT(planner.max_jerk.z), - SP_I_STR, LINEAR_UNIT(planner.max_jerk.i), - SP_J_STR, LINEAR_UNIT(planner.max_jerk.j), - SP_K_STR, LINEAR_UNIT(planner.max_jerk.k) - ) - #if HAS_CLASSIC_E_JERK - , SP_E_STR, LINEAR_UNIT(planner.max_jerk.e) - #endif - #endif - ); -} diff --git a/src/gcode/config/M217.cpp b/src/gcode/config/M217.cpp deleted file mode 100644 index 1c80858..0000000 --- a/src/gcode/config/M217.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_MULTI_EXTRUDER - -#include "../gcode.h" -#include "../../module/tool_change.h" - -#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) - #include "../../module/motion.h" -#endif - -#include "../../MarlinCore.h" // for SP_X_STR, etc. - -/** - * M217 - Set toolchange parameters - * - * // Tool change command - * Q Prime active tool and exit - * - * // Tool change settings - * S[linear] Swap length - * B[linear] Extra Swap resume length - * E[linear] Extra Prime length (as used by M217 Q) - * P[linear/min] Prime speed - * R[linear/min] Retract speed - * U[linear/min] UnRetract speed - * V[linear] 0/1 Enable auto prime first extruder used - * W[linear] 0/1 Enable park & Z Raise - * X[linear] Park X (Requires TOOLCHANGE_PARK) - * Y[linear] Park Y (Requires TOOLCHANGE_PARK) - * I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4) - * J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5) - * K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6) - * Z[linear] Z Raise - * F[speed] Fan Speed 0-255 - * D[seconds] Fan time - * - * Tool migration settings - * A[0|1] Enable auto-migration on runout - * L[index] Last extruder to use for auto-migration - * - * Tool migration command - * T[index] Migrate to next extruder or the given extruder - */ -void GcodeSuite::M217() { - - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - - static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500); - - if (parser.seen('Q')) { tool_change_prime(); return; } - - if (parser.seenval('S')) { const float v = parser.value_linear_units(); toolchange_settings.swap_length = constrain(v, 0, max_extrude); } - if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); } - if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); } - if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); } - if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); } - if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); } - #if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN - if (parser.seenval('F')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_speed = constrain(v, 0, 255); } - if (parser.seenval('D')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_time = constrain(v, 1, 30); } - #endif - #endif - - #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) - if (parser.seenval('V')) { enable_first_prime = parser.value_linear_units(); } - #endif - - #if ENABLED(TOOLCHANGE_PARK) - if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); } - if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); } - #if HAS_Y_AXIS - if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); } - #endif - #if HAS_I_AXIS - if (parser.seenval('I')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.i = constrain(v, I_MIN_POS, I_MAX_POS); } - #endif - #if HAS_J_AXIS - if (parser.seenval('J')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.j = constrain(v, J_MIN_POS, J_MAX_POS); } - #endif - #if HAS_K_AXIS - if (parser.seenval('K')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.k = constrain(v, K_MIN_POS, K_MAX_POS); } - #endif - #endif - - #if HAS_Z_AXIS - if (parser.seenval('Z')) { toolchange_settings.z_raise = parser.value_linear_units(); } - #endif - - #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) - migration.target = 0; // 0 = disabled - - if (parser.seenval('L')) { // Last - const int16_t lval = parser.value_int(); - if (WITHIN(lval, 0, EXTRUDERS - 1)) { - migration.last = lval; - migration.automode = (active_extruder < migration.last); - } - } - - if (parser.seen('A')) // Auto on/off - migration.automode = parser.value_bool(); - - if (parser.seen('T')) { // Migrate now - if (parser.has_value()) { - const int16_t tval = parser.value_int(); - if (WITHIN(tval, 0, EXTRUDERS - 1) && tval != active_extruder) { - migration.target = tval + 1; - extruder_migration(); - migration.target = 0; // disable - return; - } - else - migration.target = 0; // disable - } - else { - extruder_migration(); - return; - } - } - - #endif - - M217_report(); -} - -void GcodeSuite::M217_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_TOOL_CHANGING)); - - SERIAL_ECHOPGM(" M217"); - - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - SERIAL_ECHOPGM(" S", LINEAR_UNIT(toolchange_settings.swap_length)); - SERIAL_ECHOPGM_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume), - SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime), - SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed)); - SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed), - " U", LINEAR_UNIT(toolchange_settings.unretract_speed), - " F", toolchange_settings.fan_speed, - " D", toolchange_settings.fan_time); - - #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) - SERIAL_ECHOPGM(" A", migration.automode); - SERIAL_ECHOPGM(" L", LINEAR_UNIT(migration.last)); - #endif - - #if ENABLED(TOOLCHANGE_PARK) - { - SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park)); - SERIAL_ECHOPGM_P( - SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x) - #if HAS_Y_AXIS - , SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y) - #endif - #if SECONDARY_AXES >= 1 - , LIST_N(DOUBLE(SECONDARY_AXES), - SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i), - SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j), - SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k) - ) - #endif - ); - } - #endif - - #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) - SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime)); - #endif - - #endif - - SERIAL_ECHOLNPGM_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise)); -} - -#endif // HAS_MULTI_EXTRUDER diff --git a/src/gcode/config/M218.cpp b/src/gcode/config/M218.cpp deleted file mode 100644 index c39447a..0000000 --- a/src/gcode/config/M218.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_HOTEND_OFFSET - -#include "../gcode.h" -#include "../../module/motion.h" - -#if ENABLED(DELTA) - #include "../../module/planner.h" -#endif - -/** - * M218 - set hotend offset (in linear units) - * - * T - * X - * Y - * Z - */ -void GcodeSuite::M218() { - - if (!parser.seen_any()) return M218_report(); - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units(); - if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units(); - if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units(); - - #if ENABLED(DELTA) - if (target_extruder == active_extruder) - do_blocking_move_to_xy(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]); - #endif -} - -void GcodeSuite::M218_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_HOTEND_OFFSETS)); - LOOP_S_L_N(e, 1, HOTENDS) { - report_echo_start(forReplay); - SERIAL_ECHOPGM_P( - PSTR(" M218 T"), e, - SP_X_STR, LINEAR_UNIT(hotend_offset[e].x), - SP_Y_STR, LINEAR_UNIT(hotend_offset[e].y) - ); - SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(hotend_offset[e].z), 3); - } -} - -#endif // HAS_HOTEND_OFFSET diff --git a/src/gcode/config/M220.cpp b/src/gcode/config/M220.cpp deleted file mode 100644 index c9070df..0000000 --- a/src/gcode/config/M220.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/motion.h" - -/** - * M220: Set speed percentage factor, aka "Feed Rate" - * - * Parameters - * S : Set the feed rate percentage factor - * - * Report the current speed percentage factor if no parameter is specified - * - * For MMU2 and MMU2S devices... - * B : Flag to back up the current factor - * R : Flag to restore the last-saved factor - */ -void GcodeSuite::M220() { - - static int16_t backup_feedrate_percentage = 100; - if (parser.seen('B')) backup_feedrate_percentage = feedrate_percentage; - if (parser.seen('R')) feedrate_percentage = backup_feedrate_percentage; - - if (parser.seenval('S')) feedrate_percentage = parser.value_int(); - - if (!parser.seen_any()) { - SERIAL_ECHOPGM("FR:", feedrate_percentage); - SERIAL_CHAR('%'); - SERIAL_EOL(); - } -} diff --git a/src/gcode/config/M221.cpp b/src/gcode/config/M221.cpp deleted file mode 100644 index f653ade..0000000 --- a/src/gcode/config/M221.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/planner.h" - -#if HAS_EXTRUDERS - -/** - * M221: Set extrusion percentage (M221 T0 S95) - */ -void GcodeSuite::M221() { - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - if (parser.seenval('S')) - planner.set_flow(target_extruder, parser.value_int()); - else { - SERIAL_ECHO_START(); - SERIAL_CHAR('E', '0' + target_extruder); - SERIAL_ECHOPGM(" Flow: ", planner.flow_percentage[target_extruder]); - SERIAL_CHAR('%'); - SERIAL_EOL(); - } -} - -#endif // EXTRUDERS diff --git a/src/gcode/config/M281.cpp b/src/gcode/config/M281.cpp deleted file mode 100644 index e4ef3ab..0000000 --- a/src/gcode/config/M281.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(EDITABLE_SERVO_ANGLES) - -#include "../gcode.h" -#include "../../module/servo.h" - -/** - * M281 - Edit / Report Servo Angles - * - * P - Servo to update - * L - Deploy Angle - * U - Stowed Angle - */ -void GcodeSuite::M281() { - if (!parser.seen_any()) return M281_report(); - - if (!parser.seenval('P')) return; - - const int servo_index = parser.value_int(); - if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { - #if ENABLED(BLTOUCH) - if (servo_index == Z_PROBE_SERVO_NR) { - SERIAL_ERROR_MSG("BLTouch angles can't be changed."); - return; - } - #endif - if (parser.seenval('L')) servo_angles[servo_index][0] = parser.value_int(); - if (parser.seenval('U')) servo_angles[servo_index][1] = parser.value_int(); - } - else - SERIAL_ERROR_MSG("Servo ", servo_index, " out of range"); -} - -void GcodeSuite::M281_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_SERVO_ANGLES)); - LOOP_L_N(i, NUM_SERVOS) { - switch (i) { - default: break; - #if ENABLED(SWITCHING_EXTRUDER) - case SWITCHING_EXTRUDER_SERVO_NR: - #if EXTRUDERS > 3 - case SWITCHING_EXTRUDER_E23_SERVO_NR: - #endif - #elif ENABLED(SWITCHING_NOZZLE) - case SWITCHING_NOZZLE_SERVO_NR: - #elif ENABLED(BLTOUCH) || (HAS_Z_SERVO_PROBE && defined(Z_SERVO_ANGLES)) - case Z_PROBE_SERVO_NR: - #endif - report_echo_start(forReplay); - SERIAL_ECHOLNPGM(" M281 P", i, " L", servo_angles[i][0], " U", servo_angles[i][1]); - } - } -} - -#endif // EDITABLE_SERVO_ANGLES diff --git a/src/gcode/config/M301.cpp b/src/gcode/config/M301.cpp deleted file mode 100644 index fc9f188..0000000 --- a/src/gcode/config/M301.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PIDTEMP) - -#include "../gcode.h" -#include "../../module/temperature.h" - -/** - * M301: Set PID parameters P I D (and optionally C, L) - * - * E[extruder] Default: 0 - * - * P[float] Kp term - * I[float] Ki term (unscaled) - * D[float] Kd term (unscaled) - * - * With PID_EXTRUSION_SCALING: - * - * C[float] Kc term - * L[int] LPQ length - * - * With PID_FAN_SCALING: - * - * F[float] Kf term - */ -void GcodeSuite::M301() { - // multi-extruder PID patch: M301 updates or prints a single extruder's PID values - // default behavior (omitting E parameter) is to update for extruder 0 only - int8_t e = E_TERN0(parser.byteval('E', -1)); // extruder being updated - - if (!parser.seen("PID" TERN_(PID_EXTRUSION_SCALING, "CL") TERN_(PID_FAN_SCALING, "F"))) - return M301_report(true E_OPTARG(e)); - - if (e == -1) e = 0; - - if (e < HOTENDS) { // catch bad input value - - if (parser.seenval('P')) PID_PARAM(Kp, e) = parser.value_float(); - if (parser.seenval('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float()); - if (parser.seenval('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float()); - - #if ENABLED(PID_EXTRUSION_SCALING) - if (parser.seenval('C')) PID_PARAM(Kc, e) = parser.value_float(); - if (parser.seenval('L')) thermalManager.lpq_len = parser.value_int(); - NOMORE(thermalManager.lpq_len, LPQ_MAX_LEN); - NOLESS(thermalManager.lpq_len, 0); - #endif - - #if ENABLED(PID_FAN_SCALING) - if (parser.seenval('F')) PID_PARAM(Kf, e) = parser.value_float(); - #endif - - thermalManager.updatePID(); - } - else - SERIAL_ERROR_MSG(STR_INVALID_EXTRUDER); -} - -void GcodeSuite::M301_report(const bool forReplay/*=true*/ E_OPTARG(const int8_t eindex/*=-1*/)) { - report_heading(forReplay, F(STR_HOTEND_PID)); - IF_DISABLED(HAS_MULTI_EXTRUDER, constexpr int8_t eindex = -1); - HOTEND_LOOP() { - if (e == eindex || eindex == -1) { - report_echo_start(forReplay); - SERIAL_ECHOPGM_P( - #if ENABLED(PID_PARAMS_PER_HOTEND) - PSTR(" M301 E"), e, SP_P_STR - #else - PSTR(" M301 P") - #endif - , PID_PARAM(Kp, e) - , PSTR(" I"), unscalePID_i(PID_PARAM(Ki, e)) - , PSTR(" D"), unscalePID_d(PID_PARAM(Kd, e)) - ); - #if ENABLED(PID_EXTRUSION_SCALING) - SERIAL_ECHOPGM_P(SP_C_STR, PID_PARAM(Kc, e)); - if (e == 0) SERIAL_ECHOPGM(" L", thermalManager.lpq_len); - #endif - #if ENABLED(PID_FAN_SCALING) - SERIAL_ECHOPGM(" F", PID_PARAM(Kf, e)); - #endif - SERIAL_EOL(); - } - } -} - -#endif // PIDTEMP diff --git a/src/gcode/config/M302.cpp b/src/gcode/config/M302.cpp deleted file mode 100644 index 9f4d569..0000000 --- a/src/gcode/config/M302.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PREVENT_COLD_EXTRUSION) - -#include "../gcode.h" -#include "../../module/temperature.h" - -#if ENABLED(DWIN_LCD_PROUI) - #include "../../lcd/e3v2/proui/dwin_defines.h" -#endif - -/** - * 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 ; disable cold extrusion checking - * M302 S0 ; always allow extrusion (disables checking) - * M302 S170 ; only allow extrusion above 170 - * M302 S170 P1 ; set min extrude temp to 170 but leave disabled - */ -void GcodeSuite::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); - TERN_(DWIN_LCD_PROUI, HMI_data.ExtMinT = thermalManager.extrude_min_temp); - } - - 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_ECHOPGM("Cold extrudes are "); - SERIAL_ECHOF(thermalManager.allow_cold_extrude ? F("en") : F("dis")); - SERIAL_ECHOLNPGM("abled (min temp ", thermalManager.extrude_min_temp, "C)"); - } -} - -#endif // PREVENT_COLD_EXTRUSION diff --git a/src/gcode/config/M304.cpp b/src/gcode/config/M304.cpp deleted file mode 100644 index c970288..0000000 --- a/src/gcode/config/M304.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PIDTEMPBED) - -#include "../gcode.h" -#include "../../module/temperature.h" - -/** - * M304 - Set and/or Report the current Bed PID values - * - * P - Set the P value - * I - Set the I value - * D - Set the D value - */ -void GcodeSuite::M304() { - if (!parser.seen("PID")) return M304_report(); - if (parser.seenval('P')) thermalManager.temp_bed.pid.Kp = parser.value_float(); - if (parser.seenval('I')) thermalManager.temp_bed.pid.Ki = scalePID_i(parser.value_float()); - if (parser.seenval('D')) thermalManager.temp_bed.pid.Kd = scalePID_d(parser.value_float()); -} - -void GcodeSuite::M304_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_BED_PID)); - SERIAL_ECHOLNPGM( - " M304 P", thermalManager.temp_bed.pid.Kp - , " I", unscalePID_i(thermalManager.temp_bed.pid.Ki) - , " D", unscalePID_d(thermalManager.temp_bed.pid.Kd) - ); -} - -#endif // PIDTEMPBED diff --git a/src/gcode/config/M305.cpp b/src/gcode/config/M305.cpp deleted file mode 100644 index e774692..0000000 --- a/src/gcode/config/M305.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_USER_THERMISTORS - -#include "../gcode.h" -#include "../../module/temperature.h" - -/** - * M305: Set (or report) custom thermistor parameters - * - * P[index] Thermistor table index - * R[ohms] Pullup resistor value - * T[ohms] Resistance at 25C - * B[beta] Thermistor "beta" value - * C[coeff] Steinhart-Hart Coefficient 'C' - * - * Format: M305 P[tbl_index] R[pullup_resistor_val] T[therm_25C_resistance] B[therm_beta] C[Steinhart_Hart_C_coeff] - * - * Examples: M305 P0 R4700 T100000 B3950 C0.0 - * M305 P0 R4700 - * M305 P0 T100000 - * M305 P0 B3950 - * M305 P0 C0.0 - */ -void GcodeSuite::M305() { - const int8_t t_index = parser.intval('P', -1); - const bool do_set = parser.seen("BCRT"); - - // A valid P index is required - if (t_index >= (USER_THERMISTORS) || (do_set && t_index < 0)) - SERIAL_ECHO_MSG("!Invalid index. (0 <= P <= ", USER_THERMISTORS - 1, ")"); - else if (do_set) { - if (parser.seenval('R')) // Pullup resistor value - if (!thermalManager.set_pull_up_res(t_index, parser.value_float())) - SERIAL_ECHO_MSG("!Invalid series resistance. (0 < R < 1000000)"); - - if (parser.seenval('T')) // Resistance at 25C - if (!thermalManager.set_res25(t_index, parser.value_float())) - SERIAL_ECHO_MSG("!Invalid 25C resistance. (0 < T < 10000000)"); - - if (parser.seenval('B')) // Beta value - if (!thermalManager.set_beta(t_index, parser.value_float())) - SERIAL_ECHO_MSG("!Invalid beta. (0 < B < 1000000)"); - - if (parser.seenval('C')) // Steinhart-Hart C coefficient - if (!thermalManager.set_sh_coeff(t_index, parser.value_float())) - SERIAL_ECHO_MSG("!Invalid Steinhart-Hart C coeff. (-0.01 < C < +0.01)"); - } // If not setting then report parameters - else if (t_index < 0) { // ...all user thermistors - LOOP_L_N(i, USER_THERMISTORS) - thermalManager.M305_report(i); - } - else // ...one user thermistor - thermalManager.M305_report(t_index); -} - -#endif // HAS_USER_THERMISTORS diff --git a/src/gcode/config/M309.cpp b/src/gcode/config/M309.cpp deleted file mode 100644 index 5770232..0000000 --- a/src/gcode/config/M309.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PIDTEMPCHAMBER) - -#include "../gcode.h" -#include "../../module/temperature.h" - -/** - * M309 - Set and/or Report the current Chamber PID values - * - * P - Set the P value - * I - Set the I value - * D - Set the D value - */ -void GcodeSuite::M309() { - if (!parser.seen("PID")) return M309_report(); - if (parser.seen('P')) thermalManager.temp_chamber.pid.Kp = parser.value_float(); - if (parser.seen('I')) thermalManager.temp_chamber.pid.Ki = scalePID_i(parser.value_float()); - if (parser.seen('D')) thermalManager.temp_chamber.pid.Kd = scalePID_d(parser.value_float()); -} - -void GcodeSuite::M309_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_CHAMBER_PID)); - SERIAL_ECHOLNPGM( - " M309 P", thermalManager.temp_chamber.pid.Kp - , " I", unscalePID_i(thermalManager.temp_chamber.pid.Ki) - , " D", unscalePID_d(thermalManager.temp_chamber.pid.Kd) - ); -} - -#endif // PIDTEMPCHAMBER diff --git a/src/gcode/config/M43.cpp b/src/gcode/config/M43.cpp deleted file mode 100644 index 688b94c..0000000 --- a/src/gcode/config/M43.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PINS_DEBUGGING) - -#include "../gcode.h" -#include "../../MarlinCore.h" // for pin_is_protected -#include "../../pins/pinsDebug.h" -#include "../../module/endstops.h" - -#if HAS_Z_SERVO_PROBE - #include "../../module/probe.h" - #include "../../module/servo.h" -#endif - -#if ENABLED(BLTOUCH) - #include "../../feature/bltouch.h" -#endif - -#if ENABLED(HOST_PROMPT_SUPPORT) - #include "../../feature/host_actions.h" -#endif - -#if ENABLED(EXTENSIBLE_UI) - #include "../../lcd/extui/ui_api.h" -#endif - -#if HAS_RESUME_CONTINUE - #include "../../lcd/marlinui.h" -#endif - -#ifndef GET_PIN_MAP_PIN_M43 - #define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q) -#endif - -inline void toggle_pins() { - const bool ignore_protection = parser.boolval('I'); - const int repeat = parser.intval('R', 1), - start = PARSED_PIN_INDEX('S', 0), - end = PARSED_PIN_INDEX('L', NUM_DIGITAL_PINS - 1), - wait = parser.intval('W', 500); - - LOOP_S_LE_N(i, start, end) { - pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) { - report_pin_state_extended(pin, ignore_protection, true, F("Untouched ")); - SERIAL_EOL(); - } - else { - hal.watchdog_refresh(); - report_pin_state_extended(pin, ignore_protection, true, F("Pulsing ")); - #ifdef __STM32F1__ - const auto prior_mode = _GET_MODE(i); - #else - const bool prior_mode = GET_PINMODE(pin); - #endif - #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO - if (pin == TEENSY_E2) { - SET_OUTPUT(TEENSY_E2); - 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++) { - hal.watchdog_refresh(); extDigitalWrite(pin, 0); safe_delay(wait); - hal.watchdog_refresh(); extDigitalWrite(pin, 1); safe_delay(wait); - hal.watchdog_refresh(); extDigitalWrite(pin, 0); safe_delay(wait); - hal.watchdog_refresh(); - } - } - #ifdef __STM32F1__ - _SET_MODE(i, prior_mode); - #else - pinMode(pin, prior_mode); - #endif - } - SERIAL_EOL(); - } - SERIAL_ECHOLNPGM(STR_DONE); - -} // toggle_pins - -inline void servo_probe_test() { - - #if !(NUM_SERVOS > 0 && HAS_SERVO_0) - - SERIAL_ERROR_MSG("SERVO not set up."); - - #elif !HAS_Z_SERVO_PROBE - - SERIAL_ERROR_MSG("Z_PROBE_SERVO_NR not set up."); - - #else // HAS_Z_SERVO_PROBE - - const uint8_t probe_index = parser.byteval('P', Z_PROBE_SERVO_NR); - - SERIAL_ECHOLNPGM("Servo probe test\n" - ". using index: ", probe_index, - ", deploy angle: ", servo_angles[probe_index][0], - ", stow angle: ", servo_angles[probe_index][1] - ); - - bool deploy_state = false, stow_state; - - #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - - #define PROBE_TEST_PIN Z_MIN_PIN - constexpr bool probe_inverting = Z_MIN_ENDSTOP_INVERTING; - - SERIAL_ECHOLNPGM(". Probe Z_MIN_PIN: ", PROBE_TEST_PIN); - SERIAL_ECHOPGM(". Z_MIN_ENDSTOP_INVERTING: "); - - #else - - #define PROBE_TEST_PIN Z_MIN_PROBE_PIN - constexpr bool probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING; - - SERIAL_ECHOLNPGM(". Probe Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN); - SERIAL_ECHOPGM( ". Z_MIN_PROBE_ENDSTOP_INVERTING: "); - - #endif - - serialprint_truefalse(probe_inverting); - SERIAL_EOL(); - - SET_INPUT_PULLUP(PROBE_TEST_PIN); - - // First, check for a probe that recognizes an advanced BLTouch sequence. - // In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning) - // to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or - // BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually - // configured a BLTouch as being present. If the user has not configured this, - // the BLTouch will be detected in the last phase of these tests (see further on). - bool blt = false; - // This code will try to detect a BLTouch probe or clone - #if ENABLED(BLTOUCH) - SERIAL_ECHOLNPGM(". Check for BLTOUCH"); - bltouch._reset(); - bltouch._stow(); - if (probe_inverting == READ(PROBE_TEST_PIN)) { - bltouch._set_SW_mode(); - if (probe_inverting != READ(PROBE_TEST_PIN)) { - bltouch._deploy(); - if (probe_inverting == READ(PROBE_TEST_PIN)) { - bltouch._stow(); - SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected."); - // Check for a 3.1 by letting the user trigger it, later - blt = true; - } - } - } - #endif - - // The following code is common to all kinds of servo probes. - // Since it could be a real servo or a BLTouch (any kind) or a clone, - // use only "common" functions - i.e. SERVO_MOVE. No bltouch.xxxx stuff. - - // If it is already recognised as a being a BLTouch, no need for this test - if (!blt) { - // DEPLOY and STOW 4 times and see if the signal follows - // Then it is a mechanical switch - uint8_t i = 0; - SERIAL_ECHOLNPGM(". Deploy & stow 4 times"); - do { - servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy - safe_delay(500); - deploy_state = READ(PROBE_TEST_PIN); - servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][1]); // Stow - safe_delay(500); - stow_state = READ(PROBE_TEST_PIN); - } while (++i < 4); - - if (probe_inverting != deploy_state) SERIAL_ECHOLNPGM("WARNING: INVERTING setting probably backwards."); - - if (deploy_state != stow_state) { - SERIAL_ECHOLNPGM("= Mechanical Switch detected"); - if (deploy_state) { - SERIAL_ECHOLNPGM(" DEPLOYED state: HIGH (logic 1)", - " STOWED (triggered) state: LOW (logic 0)"); - } - else { - SERIAL_ECHOLNPGM(" DEPLOYED state: LOW (logic 0)", - " STOWED (triggered) state: HIGH (logic 1)"); - } - #if ENABLED(BLTOUCH) - SERIAL_ECHOLNPGM("FAIL: BLTOUCH enabled - Set up this device as a Servo Probe with INVERTING set to 'true'."); - #endif - return; - } - } - - // Ask the user for a trigger event and measure the pulse width. - servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy - safe_delay(500); - SERIAL_ECHOLNPGM("** Please trigger probe within 30 sec **"); - uint16_t probe_counter = 0; - - // Wait 30 seconds for user to trigger probe - for (uint16_t j = 0; j < 500 * 30 && probe_counter == 0 ; j++) { - safe_delay(2); - - if (0 == j % (500 * 1)) gcode.reset_stepper_timeout(); // Keep steppers powered - - if (deploy_state != READ(PROBE_TEST_PIN)) { // probe triggered - for (probe_counter = 0; probe_counter < 15 && deploy_state != READ(PROBE_TEST_PIN); ++probe_counter) safe_delay(2); - - SERIAL_ECHOPGM(". Pulse width"); - if (probe_counter == 15) - SERIAL_ECHOLNPGM(": 30ms or more"); - else - SERIAL_ECHOLNPGM(" (+/- 4ms): ", probe_counter * 2); - - if (probe_counter >= 4) { - if (probe_counter == 15) { - if (blt) SERIAL_ECHOPGM("= BLTouch V3.1"); - else SERIAL_ECHOPGM("= Z Servo Probe"); - } - else SERIAL_ECHOPGM("= BLTouch pre V3.1 (or compatible)"); - SERIAL_ECHOLNPGM(" detected."); - } - else SERIAL_ECHOLNPGM("FAIL: Noise detected - please re-run test"); - - servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][1]); // Stow - return; - } - } - - if (!probe_counter) SERIAL_ECHOLNPGM("FAIL: No trigger detected"); - - #endif // HAS_Z_SERVO_PROBE - -} // 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 - * - Cannot 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 continuing to next pin - * W - Wait time (in milliseconds) between pulses. If not given will default to 500 - * - * M43 S - Servo probe test - * P - Probe index (optional - defaults to 0 - */ -void GcodeSuite::M43() { - - // 'T' must be first. It uses 'S' and 'E' differently. - if (parser.seen('T')) return toggle_pins(); - - // 'E' Enable or disable endstop monitoring and return - if (parser.seen('E')) { - endstops.monitor_flag = parser.value_bool(); - SERIAL_ECHOPGM("endstop monitor "); - SERIAL_ECHOF(endstops.monitor_flag ? F("en") : F("dis")); - SERIAL_ECHOLNPGM("abled"); - return; - } - - // 'S' Run servo probe test and return - if (parser.seen('S')) return servo_probe_test(); - - // 'P' Get the range of pins to test or watch - uint8_t first_pin = PARSED_PIN_INDEX('P', 0), - last_pin = parser.seenval('P') ? first_pin : TERN(HAS_HIGH_ANALOG_PINS, NUM_DIGITAL_PINS, NUMBER_PINS_TOTAL) - 1; - - if (first_pin > last_pin) return; - - // 'I' to ignore protected pins - const bool ignore_protection = parser.boolval('I'); - - // 'W' Watch until click, M108, or reset - if (parser.boolval('W')) { - SERIAL_ECHOLNPGM("Watching pins"); - #ifdef ARDUINO_ARCH_SAM - NOLESS(first_pin, 2); // Don't hijack the UART pins - #endif - uint8_t pin_state[last_pin - first_pin + 1]; - LOOP_S_LE_N(i, first_pin, last_pin) { - pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; - pinMode(pin, INPUT_PULLUP); - delay(1); - /* - if (IS_ANALOG(pin)) - pin_state[pin - first_pin] = analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)); // int16_t pin_state[...] - else - //*/ - pin_state[i - first_pin] = extDigitalRead(pin); - } - - #if HAS_RESUME_CONTINUE - KEEPALIVE_STATE(PAUSED_FOR_USER); - wait_for_user = true; - TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("M43 Wait Called"), FPSTR(CONTINUE_STR))); - TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("M43 Wait Called"))); - #endif - - for (;;) { - LOOP_S_LE_N(i, first_pin, last_pin) { - pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; - if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; - const byte val = - /* - IS_ANALOG(pin) - ? analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)) : // int16_t val - : - //*/ - extDigitalRead(pin); - if (val != pin_state[i - first_pin]) { - report_pin_state_extended(pin, ignore_protection, false); - pin_state[i - first_pin] = val; - } - } - - #if HAS_RESUME_CONTINUE - ui.update(); - if (!wait_for_user) break; - #endif - - safe_delay(200); - } - } - else { - // Report current state of selected pin(s) - LOOP_S_LE_N(i, first_pin, last_pin) { - pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true); - } - } -} - -#endif // PINS_DEBUGGING diff --git a/src/gcode/config/M540.cpp b/src/gcode/config/M540.cpp deleted file mode 100644 index e751248..0000000 --- a/src/gcode/config/M540.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) - -#include "../gcode.h" -#include "../../module/planner.h" - -/** - * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>) - */ -void GcodeSuite::M540() { - - if (parser.seen('S')) - planner.abort_on_endstop_hit = parser.value_bool(); - -} - -#endif // SD_ABORT_ON_ENDSTOP_HIT diff --git a/src/gcode/config/M575.cpp b/src/gcode/config/M575.cpp deleted file mode 100644 index 2c12428..0000000 --- a/src/gcode/config/M575.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(BAUD_RATE_GCODE) - -#include "../gcode.h" - -/** - * M575 - Change serial baud rate - * - * P - Serial port index. Omit for all. - * B - Baud rate (bits per second) - */ -void GcodeSuite::M575() { - int32_t baud = parser.ulongval('B'); - switch (baud) { - case 24: - case 96: - case 192: - case 384: - case 576: - case 1152: baud *= 100; break; - case 250: - case 500: baud *= 1000; break; - case 19: baud = 19200; break; - case 38: baud = 38400; break; - case 57: baud = 57600; break; - case 115: baud = 115200; break; - } - switch (baud) { - case 2400: case 9600: case 19200: case 38400: case 57600: - case 115200: case 250000: case 500000: case 1000000: { - const int8_t port = parser.intval('P', -99); - const bool set1 = (port == -99 || port == 0); - if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud); - #if HAS_MULTI_SERIAL - const bool set2 = (port == -99 || port == 1); - if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud); - #ifdef SERIAL_PORT_3 - const bool set3 = (port == -99 || port == 2); - if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud); - #endif - #endif - - SERIAL_FLUSH(); - - if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); } - #if HAS_MULTI_SERIAL - if (set2) { MYSERIAL2.end(); MYSERIAL2.begin(baud); } - #ifdef SERIAL_PORT_3 - if (set3) { MYSERIAL3.end(); MYSERIAL3.begin(baud); } - #endif - #endif - - } break; - default: SERIAL_ECHO_MSG("?(B)aud rate implausible."); - } -} - -#endif // BAUD_RATE_GCODE diff --git a/src/gcode/config/M672.cpp b/src/gcode/config/M672.cpp deleted file mode 100644 index 257b494..0000000 --- a/src/gcode/config/M672.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) - -#include "../gcode.h" -#include "../../HAL/shared/Delay.h" -#include "../parser.h" - -/** - * The Marlin format for the M672 command is different than shown in the Duet Smart Effector - * documentation https://duet3d.dozuki.com/Wiki/Smart_effector_and_carriage_adapters_for_delta_printer - * - * To set custom sensitivity: - * Duet: M672 S105:aaa:bbb - * Marlin: M672 Saaa - * - * (where aaa is the desired sensitivity and bbb is 255 - aaa). - * - * Revert sensitivity to factory settings: - * Duet: M672 S105:131:131 - * Marlin: M672 R - */ - -#define M672_PROGBYTE 105 // magic byte to start programming custom sensitivity -#define M672_ERASEBYTE 131 // magic byte to clear custom sensitivity - -// -// Smart Effector byte send protocol: -// -// 0 0 1 0 ... always 0010 -// b7 b6 b5 b4 ~b4 ... hi bits, NOT last bit -// b3 b2 b1 b0 ~b0 ... lo bits, NOT last bit -// -void M672_send(uint8_t b) { // bit rate requirement: 1kHz +/- 30% - LOOP_L_N(bits, 14) { - switch (bits) { - default: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); b <<= 1; break; } // send bit, shift next into place - case 7: - case 12: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); break; } // send bit. no shift - case 8: - case 13: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !(b & 0x80)); b <<= 1; break; } // send inverted previous bit - case 0: case 1: // 00 - case 3: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); break; } // 0010 - case 2: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, HIGH); break; } // 001 - } - DELAY_US(1000); - } -} - -/** - * M672 - Set/reset Duet Smart Effector sensitivity - * - * One of these is required: - * S - 0-255 - * R - Flag to reset sensitivity to default - */ -void GcodeSuite::M672() { - if (parser.seen('R')) { - M672_send(M672_ERASEBYTE); - M672_send(M672_ERASEBYTE); - } - else if (parser.seenval('S')) { - const int8_t M672_sensitivity = parser.value_byte(); - M672_send(M672_PROGBYTE); - M672_send(M672_sensitivity); - M672_send(255 - M672_sensitivity); - } - else { - SERIAL_ECHO_MSG("!'S' or 'R' parameter required."); - return; - } - - OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Keep Smart Effector in NORMAL mode -} - -#endif // DUET_SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN diff --git a/src/gcode/config/M92.cpp b/src/gcode/config/M92.cpp deleted file mode 100644 index b2ec3be..0000000 --- a/src/gcode/config/M92.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/planner.h" - -/** - * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, [I, [J, [K]]] and E. - * (Follows the same syntax as G92) - * - * With multiple extruders use T to specify which one. - * - * If no argument is given print the current values. - * - * With MAGIC_NUMBERS_GCODE: - * - * Use 'H' and/or 'L' to get ideal layer-height information. - * H - Specify micro-steps to use. Best guess if not supplied. - * L - Desired layer height in current units. Nearest good heights are shown. - */ -void GcodeSuite::M92() { - - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; - - // No arguments? Show M92 report. - if (!parser.seen(STR_AXES_LOGICAL TERN_(MAGIC_NUMBERS_GCODE, "HL"))) - return M92_report(true, target_extruder); - - LOOP_LOGICAL_AXES(i) { - if (parser.seenval(AXIS_CHAR(i))) { - if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) - planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_units((AxisEnum)i); - else { - #if HAS_EXTRUDERS - const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder))); - if (value < 20) { - float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab. - #if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK - planner.max_jerk.e *= factor; - #endif - planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor; - planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor; - } - planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value; - #endif - } - } - } - planner.refresh_positioning(); - - #if ENABLED(MAGIC_NUMBERS_GCODE) - #ifndef Z_MICROSTEPS - #define Z_MICROSTEPS 16 - #endif - const float wanted = parser.linearval('L'); - if (parser.seen('H') || wanted) { - const uint16_t argH = parser.ushortval('H'), - micro_steps = argH ?: Z_MICROSTEPS; - const float z_full_step_mm = micro_steps * planner.mm_per_step[Z_AXIS]; - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("{ micro_steps:", micro_steps, ", z_full_step_mm:", z_full_step_mm); - if (wanted) { - const float best = uint16_t(wanted / z_full_step_mm) * z_full_step_mm; - SERIAL_ECHOPGM(", best:[", best); - if (best != wanted) { SERIAL_CHAR(','); SERIAL_DECIMAL(best + z_full_step_mm); } - SERIAL_CHAR(']'); - } - SERIAL_ECHOLNPGM(" }"); - } - #endif -} - -void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) { - report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT)); - SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES), - PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]), - SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]), - SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]), - SP_I_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]), - SP_J_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]), - SP_K_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[K_AXIS])) - ); - #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS) - SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS])); - #endif - SERIAL_EOL(); - - #if ENABLED(DISTINCT_E_FACTORS) - LOOP_L_N(i, E_STEPPERS) { - if (e >= 0 && i != e) continue; - report_echo_start(forReplay); - SERIAL_ECHOLNPGM_P( - PSTR(" M92 T"), i, - SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)]) - ); - } - #else - UNUSED(e); - #endif -} diff --git a/src/gcode/control/M10-M11.cpp b/src/gcode/control/M10-M11.cpp deleted file mode 100644 index d5a69dc..0000000 --- a/src/gcode/control/M10-M11.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(AIR_EVACUATION) - -#include "../gcode.h" -#include "../../feature/spindle_laser.h" - -/** - * M10: Vacuum or Blower On - */ -void GcodeSuite::M10() { - cutter.air_evac_enable(); // Turn on Vacuum or Blower motor -} - -/** - * M11: Vacuum or Blower OFF - */ -void GcodeSuite::M11() { - cutter.air_evac_disable(); // Turn off Vacuum or Blower motor -} - -#endif // AIR_EVACUATION diff --git a/src/gcode/control/M108_M112_M410.cpp b/src/gcode/control/M108_M112_M410.cpp deleted file mode 100644 index 39f9c04..0000000 --- a/src/gcode/control/M108_M112_M410.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if DISABLED(EMERGENCY_PARSER) - -#include "../gcode.h" -#include "../../MarlinCore.h" // for wait_for_heatup, kill, M112_KILL_STR -#include "../../module/motion.h" // for quickstop_stepper - -/** - * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature. - */ -void GcodeSuite::M108() { - TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); - wait_for_heatup = false; -} - -/** - * M112: Full Shutdown - */ -void GcodeSuite::M112() { - kill(FPSTR(M112_KILL_STR), nullptr, true); -} - -/** - * 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. - */ -void GcodeSuite::M410() { - quickstop_stepper(); -} - -#endif // !EMERGENCY_PARSER diff --git a/src/gcode/control/M111.cpp b/src/gcode/control/M111.cpp deleted file mode 100644 index a92d334..0000000 --- a/src/gcode/control/M111.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" - -/** - * M111: Set the debug level - */ -void GcodeSuite::M111() { - if (parser.seenval('S')) marlin_debug_flags = parser.value_byte(); - - static PGMSTR(str_debug_1, STR_DEBUG_ECHO); - static PGMSTR(str_debug_2, STR_DEBUG_INFO); - static PGMSTR(str_debug_4, STR_DEBUG_ERRORS); - static PGMSTR(str_debug_8, STR_DEBUG_DRYRUN); - static PGMSTR(str_debug_16, STR_DEBUG_COMMUNICATION); - #if ENABLED(DEBUG_LEVELING_FEATURE) - static PGMSTR(str_debug_detail, STR_DEBUG_DETAIL); - #endif - - static PGM_P const debug_strings[] PROGMEM = { - str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16, - TERN_(DEBUG_LEVELING_FEATURE, str_debug_detail) - }; - - SERIAL_ECHO_START(); - SERIAL_ECHOPGM(STR_DEBUG_PREFIX); - if (marlin_debug_flags) { - uint8_t comma = 0; - LOOP_L_N(i, COUNT(debug_strings)) { - if (TEST(marlin_debug_flags, i)) { - if (comma++) SERIAL_CHAR(','); - SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&debug_strings[i])); - } - } - } - else { - SERIAL_ECHOPGM(STR_DEBUG_OFF); - #if !defined(__AVR__) || !defined(USBCON) - #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) - SERIAL_ECHOPGM("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns()); - #endif - - #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) - SERIAL_ECHOPGM("\nFraming Errors: ", MYSERIAL1.framing_errors()); - #endif - - #if ENABLED(SERIAL_STATS_DROPPED_RX) - SERIAL_ECHOPGM("\nDropped bytes: ", MYSERIAL1.dropped()); - #endif - - #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) - SERIAL_ECHOPGM("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued()); - #endif - #endif // !__AVR__ || !USBCON - } - SERIAL_EOL(); -} diff --git a/src/gcode/control/M120_M121.cpp b/src/gcode/control/M120_M121.cpp deleted file mode 100644 index 570f2e9..0000000 --- a/src/gcode/control/M120_M121.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/endstops.h" - -/** - * M120: Enable endstops and set non-homing endstop state to "enabled" - */ -void GcodeSuite::M120() { endstops.enable_globally(true); } - -/** - * M121: Disable endstops and set non-homing endstop state to "disabled" - */ -void GcodeSuite::M121() { endstops.enable_globally(false); } diff --git a/src/gcode/control/M17_M18_M84.cpp b/src/gcode/control/M17_M18_M84.cpp deleted file mode 100644 index ebe48d9..0000000 --- a/src/gcode/control/M17_M18_M84.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../MarlinCore.h" // for stepper_inactive_time, disable_e_steppers -#include "../../lcd/marlinui.h" -#include "../../module/motion.h" // for e_axis_mask -#include "../../module/planner.h" -#include "../../module/stepper.h" - -#if ENABLED(AUTO_BED_LEVELING_UBL) - #include "../../feature/bedlevel/bedlevel.h" -#endif - -#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE) -#include "../../core/debug_out.h" -#include "../../libs/hex_print.h" - -inline stepper_flags_t selected_axis_bits() { - stepper_flags_t selected{0}; - #if HAS_EXTRUDERS - if (parser.seen('E')) { - if (E_TERN0(parser.has_value())) { - const uint8_t e = parser.value_int(); - if (e < EXTRUDERS) - selected.bits = _BV(INDEX_OF_AXIS(E_AXIS, e)); - } - else - selected.bits = e_axis_mask; - } - #endif - selected.bits |= NUM_AXIS_GANG( - (parser.seen_test('X') << X_AXIS), - | (parser.seen_test('Y') << Y_AXIS), - | (parser.seen_test('Z') << Z_AXIS), - | (parser.seen_test(AXIS4_NAME) << I_AXIS), - | (parser.seen_test(AXIS5_NAME) << J_AXIS), - | (parser.seen_test(AXIS6_NAME) << K_AXIS) - ); - return selected; -} - -// Enable specified axes and warn about other affected axes -void do_enable(const stepper_flags_t to_enable) { - const ena_mask_t was_enabled = stepper.axis_enabled.bits, - shall_enable = to_enable.bits & ~was_enabled; - - DEBUG_ECHOLNPGM("Now Enabled: ", hex_word(stepper.axis_enabled.bits), " Enabling: ", hex_word(to_enable.bits), " | ", shall_enable); - - if (!shall_enable) return; // All specified axes already enabled? - - ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap - - // Enable all flagged axes - LOOP_NUM_AXES(a) { - if (TEST(shall_enable, a)) { - stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis - DEBUG_ECHOLNPGM("Enabled ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits)); - also_enabled |= enable_overlap[a]; - } - } - #if HAS_EXTRUDERS - EXTRUDER_LOOP() { - const uint8_t a = INDEX_OF_AXIS(E_AXIS, e); - if (TEST(shall_enable, a)) { - stepper.ENABLE_EXTRUDER(e); - DEBUG_ECHOLNPGM("Enabled E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ", hex_word(stepper.axis_enabled.bits)); - also_enabled |= enable_overlap[a]; - } - } - #endif - - if ((also_enabled &= ~(shall_enable | was_enabled))) { - SERIAL_CHAR('('); - LOOP_NUM_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(AXIS_CHAR(a), ' '); - #if HAS_EXTRUDERS - #define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' '); - REPEAT(EXTRUDERS, _EN_ALSO) - #endif - SERIAL_ECHOLNPGM("also enabled)"); - } - - DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits)); -} - -/** - * M17: Enable stepper motor power for one or more axes. - * Print warnings for axes that share an ENABLE_PIN. - * - * Examples: - * - * M17 XZ ; Enable X and Z axes - * M17 E ; Enable all E steppers - * M17 E1 ; Enable just the E1 stepper - */ -void GcodeSuite::M17() { - if (parser.seen_axis()) { - if (any_enable_overlap()) - do_enable(selected_axis_bits()); - else { - #if HAS_EXTRUDERS - if (parser.seen('E')) { - if (parser.has_value()) { - const uint8_t e = parser.value_int(); - if (e < EXTRUDERS) stepper.ENABLE_EXTRUDER(e); - } - else - stepper.enable_e_steppers(); - } - #endif - LOOP_NUM_AXES(a) - if (parser.seen_test(AXIS_CHAR(a))) stepper.enable_axis((AxisEnum)a); - } - } - else { - LCD_MESSAGE(MSG_NO_MOVE); - stepper.enable_all_steppers(); - } -} - -void try_to_disable(const stepper_flags_t to_disable) { - ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits; - - DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled)); - - if (!still_enabled) return; - - // Attempt to disable all flagged axes - LOOP_NUM_AXES(a) - if (TEST(to_disable.bits, a)) { - DEBUG_ECHOPGM("Try to disable ", AXIS_CHAR(a), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... "); - if (stepper.disable_axis(AxisEnum(a))) { // Mark the requested axis and request to disable - DEBUG_ECHOPGM("OK"); - still_enabled &= ~(_BV(a) | enable_overlap[a]); // If actually disabled, clear one or more tracked bits - } - else - DEBUG_ECHOPGM("OVERLAP"); - DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled)); - } - #if HAS_EXTRUDERS - EXTRUDER_LOOP() { - const uint8_t a = INDEX_OF_AXIS(E_AXIS, e); - if (TEST(to_disable.bits, a)) { - DEBUG_ECHOPGM("Try to disable E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... "); - if (stepper.DISABLE_EXTRUDER(e)) { - DEBUG_ECHOPGM("OK"); - still_enabled &= ~(_BV(a) | enable_overlap[a]); - } - else - DEBUG_ECHOPGM("OVERLAP"); - DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled)); - } - } - #endif - - auto overlap_warning = [](const ena_mask_t axis_bits) { - SERIAL_ECHOPGM(" not disabled. Shared with"); - LOOP_NUM_AXES(a) if (TEST(axis_bits, a)) SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_STR[a])); - #if HAS_EXTRUDERS - #define _EN_STILLON(N) if (TEST(axis_bits, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR(' ', 'E', '0' + N); - REPEAT(EXTRUDERS, _EN_STILLON) - #endif - SERIAL_ECHOLNPGM("."); - }; - - // If any of the requested axes are still enabled, give a warning - LOOP_NUM_AXES(a) { - if (TEST(still_enabled, a)) { - SERIAL_CHAR(AXIS_CHAR(a)); - overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]); - } - } - #if HAS_EXTRUDERS - EXTRUDER_LOOP() { - const uint8_t a = INDEX_OF_AXIS(E_AXIS, e); - if (TEST(still_enabled, a)) { - SERIAL_CHAR('E', '0' + e); - overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]); - } - } - #endif - - DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits)); -} - -/** - * M18, M84: Disable stepper motor power for one or more axes. - * Print warnings for axes that share an ENABLE_PIN. - */ -void GcodeSuite::M18_M84() { - if (parser.seenval('S')) { - reset_stepper_timeout(); - #if HAS_DISABLE_INACTIVE_AXIS - const millis_t ms = parser.value_millis_from_seconds(); - #if LASER_SAFETY_TIMEOUT_MS > 0 - if (ms && ms <= LASER_SAFETY_TIMEOUT_MS) { - SERIAL_ECHO_MSG("M18 timeout must be > ", MS_TO_SEC(LASER_SAFETY_TIMEOUT_MS + 999), " s for laser safety."); - return; - } - #endif - stepper_inactive_time = ms; - #endif - } - else { - if (parser.seen_axis()) { - planner.synchronize(); - if (any_enable_overlap()) - try_to_disable(selected_axis_bits()); - else { - #if HAS_EXTRUDERS - if (parser.seen('E')) { - if (E_TERN0(parser.has_value())) - stepper.DISABLE_EXTRUDER(parser.value_int()); - else - stepper.disable_e_steppers(); - } - #endif - LOOP_NUM_AXES(a) - if (parser.seen_test(AXIS_CHAR(a))) stepper.disable_axis((AxisEnum)a); - } - } - else - planner.finish_and_disable(); - - TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled()); - } -} diff --git a/src/gcode/control/M211.cpp b/src/gcode/control/M211.cpp deleted file mode 100644 index 95ae052..0000000 --- a/src/gcode/control/M211.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if HAS_SOFTWARE_ENDSTOPS - -#include "../gcode.h" -#include "../../module/motion.h" - -/** - * M211: Enable, Disable, and/or Report software endstops - * - * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report - */ -void GcodeSuite::M211() { - if (parser.seen('S')) - soft_endstop._enabled = parser.value_bool(); - else - M211_report(); -} - -void GcodeSuite::M211_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_SOFT_ENDSTOPS)); - SERIAL_ECHOPGM(" M211 S", AS_DIGIT(soft_endstop._enabled), " ; "); - serialprintln_onoff(soft_endstop._enabled); - - report_echo_start(forReplay); - const xyz_pos_t l_soft_min = soft_endstop.min.asLogical(), - l_soft_max = soft_endstop.max.asLogical(); - print_pos(l_soft_min, F(STR_SOFT_MIN), F(" ")); - print_pos(l_soft_max, F(STR_SOFT_MAX)); -} - -#endif // HAS_SOFTWARE_ENDSTOPS diff --git a/src/gcode/control/M226.cpp b/src/gcode/control/M226.cpp deleted file mode 100644 index 4eb3db4..0000000 --- a/src/gcode/control/M226.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DIRECT_PIN_CONTROL) - -#include "../gcode.h" -#include "../../MarlinCore.h" // for pin_is_protected and idle() -#include "../../module/planner.h" - -void protected_pin_err(); - -/** - * M226: Wait until the specified pin reaches the state required (M226 P S) - */ -void GcodeSuite::M226() { - if (parser.seen('P')) { - const int pin_number = PARSED_PIN_INDEX('P', 0), - pin_state = parser.intval('S', -1); // required pin state - default is inverted - const pin_t pin = GET_PIN_MAP_PIN(pin_number); - - if (WITHIN(pin_state, -1, 1) && pin > -1) { - if (pin_is_protected(pin)) - protected_pin_err(); - else { - int target = LOW; - planner.synchronize(); - pinMode(pin, INPUT); - switch (pin_state) { - case 1: target = HIGH; break; - case 0: target = LOW; break; - case -1: target = !extDigitalRead(pin); break; - } - while (int(extDigitalRead(pin)) != target) idle(); - } - } // pin_state -1 0 1 && pin > -1 - } // parser.seen('P') -} - -#endif // DIRECT_PIN_CONTROL diff --git a/src/gcode/control/M280.cpp b/src/gcode/control/M280.cpp deleted file mode 100644 index 82981e4..0000000 --- a/src/gcode/control/M280.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_SERVOS - -#include "../gcode.h" -#include "../../module/servo.h" -#include "../../module/planner.h" - -/** - * M280: Get or set servo position. - * P - Servo index - * S - Angle to set, omit to read current angle, or use -1 to detach - * - * With POLARGRAPH: - * T - Duration of servo move - */ -void GcodeSuite::M280() { - - if (!parser.seenval('P')) return; - - TERN_(POLARGRAPH, planner.synchronize()); - - const int servo_index = parser.value_int(); - if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { - if (parser.seenval('S')) { - const int anew = parser.value_int(); - if (anew >= 0) { - #if ENABLED(POLARGRAPH) - if (parser.seenval('T')) { // (ms) Total duration of servo move - const int16_t t = constrain(parser.value_int(), 0, 10000); - const int aold = servo[servo_index].read(); - millis_t now = millis(); - const millis_t start = now, end = start + t; - while (PENDING(now, end)) { - safe_delay(50); - now = _MIN(millis(), end); - servo[servo_index].move(LROUND(aold + (anew - aold) * (float(now - start) / t))); - } - } - #endif // POLARGRAPH - servo[servo_index].move(anew); - } - else - servo[servo_index].detach(); - } - else - SERIAL_ECHO_MSG(" Servo ", servo_index, ": ", servo[servo_index].read()); - } - else - SERIAL_ERROR_MSG("Servo ", servo_index, " out of range"); - -} - -#endif // HAS_SERVOS diff --git a/src/gcode/control/M282.cpp b/src/gcode/control/M282.cpp deleted file mode 100644 index 3ac5ac9..0000000 --- a/src/gcode/control/M282.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(SERVO_DETACH_GCODE) - -#include "../gcode.h" -#include "../../module/servo.h" - -/** - * M282: Detach Servo. P - */ -void GcodeSuite::M282() { - - if (!parser.seenval('P')) return; - - const int servo_index = parser.value_int(); - if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) - servo[servo_index].detach(); - else - SERIAL_ECHO_MSG("Servo ", servo_index, " out of range"); - -} - -#endif // SERVO_DETACH_GCODE diff --git a/src/gcode/control/M3-M5.cpp b/src/gcode/control/M3-M5.cpp deleted file mode 100644 index 5d5d44e..0000000 --- a/src/gcode/control/M3-M5.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_CUTTER - -#include "../gcode.h" -#include "../../feature/spindle_laser.h" -#include "../../module/planner.h" - -/** - * Laser: - * M3 - Laser ON/Power (Ramped power) - * M4 - Laser ON/Power (Ramped power) - * M5 - Set power output to 0 (leaving inline mode unchanged). - * - * M3I - Enable continuous inline power to be processed by the planner, with power - * calculated and set in the planner blocks, processed inline during stepping. - * Within inline mode M3 S-Values will set the power for the next moves e.g. G1 X10 Y10 powers on with the last S-Value. - * M3I must be set before using planner-synced M3 inline S-Values (LASER_POWER_SYNC). - * - * M4I - Set dynamic mode which calculates laser power OCR based on the current feedrate. - * - * M5I - Clear inline mode and set power to 0. - * - * Spindle: - * M3 - Spindle ON (Clockwise) - * M4 - Spindle ON (Counter-clockwise) - * M5 - Spindle OFF - * - * Parameters: - * S - Set power. S0 will turn the spindle/laser off. - * - * If no PWM pin is defined then M3/M4 just turns it on or off. - * - * At least 12.8kHz (50Hz * 256) is needed for Spindle PWM. - * Hardware PWM is required on AVR. 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_ENA_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). - */ -void GcodeSuite::M3_M4(const bool is_M4) { - #if LASER_SAFETY_TIMEOUT_MS > 0 - reset_stepper_timeout(); // Reset timeout to allow subsequent G-code to power the laser (imm.) - #endif - - if (cutter.cutter_mode == CUTTER_MODE_STANDARD) - planner.synchronize(); // Wait for previous movement commands (G0/G1/G2/G3) to complete before changing power - - #if ENABLED(LASER_FEATURE) - if (parser.seen_test('I')) { - cutter.cutter_mode = is_M4 ? CUTTER_MODE_DYNAMIC : CUTTER_MODE_CONTINUOUS; - cutter.inline_power(0); - cutter.set_enabled(true); - } - #endif - - auto get_s_power = [] { - float u; - if (parser.seenval('S')) { - const float v = parser.value_float(); - u = TERN(LASER_POWER_TRAP, v, cutter.power_to_range(v)); - } - else if (cutter.cutter_mode == CUTTER_MODE_STANDARD) - u = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP); - - cutter.menuPower = cutter.unitPower = u; - - // PWM not implied, power converted to OCR from unit definition and on/off if not PWM. - cutter.power = TERN(SPINDLE_LASER_USE_PWM, cutter.upower_to_ocr(u), u > 0 ? 255 : 0); - return u; - }; - - if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS || cutter.cutter_mode == CUTTER_MODE_DYNAMIC) { // Laser power in inline mode - #if ENABLED(LASER_FEATURE) - planner.laser_inline.status.isPowered = true; // M3 or M4 is powered either way - get_s_power(); // Update cutter.power if seen - #if ENABLED(LASER_POWER_SYNC) - // With power sync we only set power so it does not effect queued inline power sets - planner.buffer_sync_block(BLOCK_BIT_LASER_PWR); // Send the flag, queueing inline power - #else - planner.synchronize(); - cutter.inline_power(cutter.power); - #endif - #endif - } - else { - cutter.set_enabled(true); - get_s_power(); - cutter.apply_power( - #if ENABLED(SPINDLE_SERVO) - cutter.unitPower - #elif ENABLED(SPINDLE_LASER_USE_PWM) - cutter.upower_to_ocr(cutter.unitPower) - #else - cutter.unitPower > 0 ? 255 : 0 - #endif - ); - TERN_(SPINDLE_CHANGE_DIR, cutter.set_reverse(is_M4)); - } -} - -/** - * M5 - Cutter OFF (when moves are complete) - */ -void GcodeSuite::M5() { - planner.synchronize(); - cutter.power = 0; - cutter.apply_power(0); // M5 just kills power, leaving inline mode unchanged - if (cutter.cutter_mode != CUTTER_MODE_STANDARD) { - if (parser.seen_test('I')) { - TERN_(LASER_FEATURE, cutter.inline_power(cutter.power)); - cutter.set_enabled(false); // Needs to happen while we are in inline mode to clear inline power. - cutter.cutter_mode = CUTTER_MODE_STANDARD; // Switch from inline to standard mode. - } - } - cutter.set_enabled(false); // Disable enable output setting -} - -#endif // HAS_CUTTER diff --git a/src/gcode/control/M350_M351.cpp b/src/gcode/control/M350_M351.cpp deleted file mode 100644 index ac6b5a3..0000000 --- a/src/gcode/control/M350_M351.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_MICROSTEPS - -#include "../gcode.h" -#include "../../module/stepper.h" - -#if NUM_AXES == XYZ && EXTRUDERS >= 1 - #define HAS_M350_B_PARAM 1 // "5th axis" (after E0) for an original XYZEB setup. - #if AXIS_COLLISION('B') - #error "M350 parameter 'B' collision with axis name." - #endif -#endif - -/** - * M350: Set axis microstepping modes. S sets mode for all drivers. - * - * Warning: Steps-per-unit remains unchanged. - */ -void GcodeSuite::M350() { - if (parser.seen('S')) LOOP_DISTINCT_AXES(i) stepper.microstep_mode(i, parser.value_byte()); - LOOP_LOGICAL_AXES(i) if (parser.seenval(AXIS_CHAR(i))) stepper.microstep_mode(i, parser.value_byte()); - TERN_(HAS_M350_B_PARAM, if (parser.seenval('B')) stepper.microstep_mode(E_AXIS + 1, parser.value_byte())); - stepper.microstep_readings(); -} - -/** - * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z . . . E [B] - * S# determines MS1, MS2 or MS3, X# sets the pin high/low. - * - * Parameter 'B' sets "5th axis" (after E0) only for an original XYZEB setup. - */ -void GcodeSuite::M351() { - const int8_t bval = TERN(HAS_M350_B_PARAM, parser.byteval('B', -1), -1); UNUSED(bval); - if (parser.seenval('S')) switch (parser.value_byte()) { - case 1: - LOOP_LOGICAL_AXES(i) if (parser.seenval(AXIS_CHAR(i))) stepper.microstep_ms(i, parser.value_byte(), -1, -1); - TERN_(HAS_M350_B_PARAM, if (bval >= 0) stepper.microstep_ms(E_AXIS + 1, bval != 0, -1, -1)); - break; - case 2: - LOOP_LOGICAL_AXES(i) if (parser.seenval(AXIS_CHAR(i))) stepper.microstep_ms(i, -1, parser.value_byte(), -1); - TERN_(HAS_M350_B_PARAM, if (bval >= 0) stepper.microstep_ms(E_AXIS + 1, -1, bval != 0, -1)); - break; - case 3: - LOOP_LOGICAL_AXES(i) if (parser.seenval(AXIS_CHAR(i))) stepper.microstep_ms(i, -1, -1, parser.value_byte()); - TERN_(HAS_M350_B_PARAM, if (bval >= 0) stepper.microstep_ms(E_AXIS + 1, -1, -1, bval != 0)); - break; - } - stepper.microstep_readings(); -} - -#endif // HAS_MICROSTEPS diff --git a/src/gcode/control/M380_M381.cpp b/src/gcode/control/M380_M381.cpp deleted file mode 100644 index 6bcec89..0000000 --- a/src/gcode/control/M380_M381.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL) - -#include "../gcode.h" -#include "../../feature/solenoid.h" -#include "../../module/motion.h" - -/** - * M380: Enable solenoid on the active extruder - * - * S to specify a solenoid (Requires MANUAL_SOLENOID_CONTROL) - */ -void GcodeSuite::M380() { - #if ENABLED(MANUAL_SOLENOID_CONTROL) - enable_solenoid(parser.intval('S', active_extruder)); - #else - enable_solenoid(active_extruder); - #endif -} - -/** - * M381: Disable all solenoids if EXT_SOLENOID - * Disable selected/active solenoid if MANUAL_SOLENOID_CONTROL - */ -void GcodeSuite::M381() { - #if ENABLED(MANUAL_SOLENOID_CONTROL) - disable_solenoid(parser.intval('S', active_extruder)); - #else - disable_all_solenoids(); - #endif -} - -#endif // EXT_SOLENOID || MANUAL_SOLENOID_CONTROL diff --git a/src/gcode/control/M400.cpp b/src/gcode/control/M400.cpp deleted file mode 100644 index 6058fb8..0000000 --- a/src/gcode/control/M400.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/planner.h" - -/** - * M400: Finish all moves - */ -void GcodeSuite::M400() { - - planner.synchronize(); - -} diff --git a/src/gcode/control/M42.cpp b/src/gcode/control/M42.cpp deleted file mode 100644 index 1b3a29d..0000000 --- a/src/gcode/control/M42.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(DIRECT_PIN_CONTROL) - -#include "../gcode.h" -#include "../../MarlinCore.h" // for pin_is_protected - -#if HAS_FAN - #include "../../module/temperature.h" -#endif - -#ifdef MAPLE_STM32F1 - // these are enums on the F1... - #define INPUT_PULLDOWN INPUT_PULLDOWN - #define INPUT_ANALOG INPUT_ANALOG - #define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN -#endif - -void protected_pin_err() { - SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN); -} - -/** - * M42: Change pin status via GCode - * - * P Pin number (LED if omitted) - * For LPC1768 specify pin P1_02 as M42 P102, - * P1_20 as M42 P120, etc. - * - * S Pin status from 0 - 255 - * I Flag to ignore Marlin's pin protection - * - * T Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN - */ -void GcodeSuite::M42() { - const int pin_index = PARSED_PIN_INDEX('P', GET_PIN_MAP_INDEX(LED_PIN)); - if (pin_index < 0) return; - - const pin_t pin = GET_PIN_MAP_PIN(pin_index); - - if (!parser.boolval('I') && pin_is_protected(pin)) return protected_pin_err(); - - bool avoidWrite = false; - if (parser.seenval('T')) { - switch (parser.value_byte()) { - case 0: pinMode(pin, INPUT); avoidWrite = true; break; - case 1: pinMode(pin, OUTPUT); break; - case 2: pinMode(pin, INPUT_PULLUP); avoidWrite = true; break; - #ifdef INPUT_PULLDOWN - case 3: pinMode(pin, INPUT_PULLDOWN); avoidWrite = true; break; - #endif - #ifdef INPUT_ANALOG - case 4: pinMode(pin, INPUT_ANALOG); avoidWrite = true; break; - #endif - #ifdef OUTPUT_OPEN_DRAIN - case 5: pinMode(pin, OUTPUT_OPEN_DRAIN); break; - #endif - default: SERIAL_ECHOLNPGM("Invalid Pin Mode"); return; - } - } - - if (!parser.seenval('S')) return; - const byte pin_status = parser.value_byte(); - - #if HAS_FAN - switch (pin) { - #if HAS_FAN0 - case FAN0_PIN: thermalManager.fan_speed[0] = pin_status; return; - #endif - #if HAS_FAN1 - case FAN1_PIN: thermalManager.fan_speed[1] = pin_status; return; - #endif - #if HAS_FAN2 - case FAN2_PIN: thermalManager.fan_speed[2] = pin_status; return; - #endif - #if HAS_FAN3 - case FAN3_PIN: thermalManager.fan_speed[3] = pin_status; return; - #endif - #if HAS_FAN4 - case FAN4_PIN: thermalManager.fan_speed[4] = pin_status; return; - #endif - #if HAS_FAN5 - case FAN5_PIN: thermalManager.fan_speed[5] = pin_status; return; - #endif - #if HAS_FAN6 - case FAN6_PIN: thermalManager.fan_speed[6] = pin_status; return; - #endif - #if HAS_FAN7 - case FAN7_PIN: thermalManager.fan_speed[7] = pin_status; return; - #endif - } - #endif - - if (avoidWrite) { - SERIAL_ECHOLNPGM("?Cannot write to INPUT"); - return; - } - - // An OUTPUT_OPEN_DRAIN should not be changed to normal OUTPUT (STM32) - // Use M42 Px M1/5 S0/1 to set the output type and then set value - #ifndef OUTPUT_OPEN_DRAIN - pinMode(pin, OUTPUT); - #endif - extDigitalWrite(pin, pin_status); - - #ifdef ARDUINO_ARCH_STM32 - // A simple I/O will be set to 0 by hal.set_pwm_duty() - if (pin_status <= 1 && !PWM_PIN(pin)) return; - #endif - hal.set_pwm_duty(pin, pin_status); -} - -#endif // DIRECT_PIN_CONTROL diff --git a/src/gcode/control/M605.cpp b/src/gcode/control/M605.cpp deleted file mode 100644 index e3ca43e..0000000 --- a/src/gcode/control/M605.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if HAS_DUPLICATION_MODE - -//#define DEBUG_DXC_MODE - -#include "../gcode.h" -#include "../../module/motion.h" -#include "../../module/tool_change.h" -#include "../../module/planner.h" - -#define DEBUG_OUT ENABLED(DEBUG_DXC_MODE) -#include "../../core/debug_out.h" - -#if ENABLED(DUAL_X_CARRIAGE) - - /** - * M605: Set dual x-carriage movement mode - * - * M605 S0 : (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 S1 : (AUTO_PARK) The firmware automatically parks and unparks the X-carriages on tool-change so that - * additional slicer support is not required. - * - * M605 S2 X R : (DUPLICATION) The firmware moves the second X-carriage and extruder in synchronization with - * the first X-carriage and extruder, to print 2 copies of the same object at the same time. - * Set the constant X-offset and temperature differential with M605 S2 X[offs] R[deg] and - * follow with "M605 S2" to initiate duplicated movement. For example, use "M605 S2 X100 R2" to - * make a copy 100mm to the right with E1 2° hotter than E0. - * - * M605 S3 : (MIRRORED) Formbot/Vivedino-inspired mirrored mode in which the second extruder duplicates - * the movement of the first except the second extruder is reversed in the X axis. - * The temperature differential and initial X offset must be set with "M605 S2 X[offs] R[deg]", - * then followed by "M605 S3" to initiate mirrored movement. - * - * M605 W : IDEX What? command. - * - * Note: the X axis should be homed after changing Dual X-carriage mode. - */ - void GcodeSuite::M605() { - planner.synchronize(); - - if (parser.seenval('S')) { - const DualXMode previous_mode = dual_x_carriage_mode; - - dual_x_carriage_mode = (DualXMode)parser.value_byte(); - idex_set_mirrored_mode(false); - - switch (dual_x_carriage_mode) { - - case DXC_FULL_CONTROL_MODE: - case DXC_AUTO_PARK_MODE: - break; - - case DXC_DUPLICATION_MODE: - // Set the X offset, but no less than the safety gap - if (parser.seenval('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS)); - if (parser.seenval('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff(); - // Always switch back to tool 0 - if (active_extruder != 0) tool_change(0); - break; - - case DXC_MIRRORED_MODE: { - if (previous_mode != DXC_DUPLICATION_MODE) { - SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to "); - SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE."); - dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; - return; - } - idex_set_mirrored_mode(true); - - // Do a small 'jog' motion in the X axis - xyze_pos_t dest = current_position; dest.x -= 0.1f; - for (uint8_t i = 2; --i;) { - planner.buffer_line(dest, feedrate_mm_s, 0); - dest.x += 0.1f; - } - } return; - - default: - dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; - break; - } - - idex_set_parked(false); - set_duplication_enabled(false); - - #ifdef EVENT_GCODE_IDEX_AFTER_MODECHANGE - process_subcommands_now(F(EVENT_GCODE_IDEX_AFTER_MODECHANGE)); - #endif - } - else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default - dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE; - - #ifdef DEBUG_DXC_MODE - - if (parser.seen('W')) { - DEBUG_ECHO_START(); - DEBUG_ECHOPGM("Dual X Carriage Mode "); - switch (dual_x_carriage_mode) { - case DXC_FULL_CONTROL_MODE: DEBUG_ECHOPGM("FULL_CONTROL"); break; - case DXC_AUTO_PARK_MODE: DEBUG_ECHOPGM("AUTO_PARK"); break; - case DXC_DUPLICATION_MODE: DEBUG_ECHOPGM("DUPLICATION"); break; - case DXC_MIRRORED_MODE: DEBUG_ECHOPGM("MIRRORED"); break; - } - DEBUG_ECHOPGM("\nActive Ext: ", active_extruder); - if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT "); - DEBUG_ECHOPGM(" parked."); - DEBUG_ECHOPGM("\nactive_extruder_x_pos: ", current_position.x); - DEBUG_ECHOPGM("\ninactive_extruder_x: ", inactive_extruder_x); - DEBUG_ECHOPGM("\nextruder_duplication_enabled: ", extruder_duplication_enabled); - DEBUG_ECHOPGM("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset); - DEBUG_ECHOPGM("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset); - DEBUG_ECHOPGM("\ndelayed_move_time: ", delayed_move_time); - DEBUG_ECHOPGM("\nX1 Home X: ", x_home_pos(0), "\nX1_MIN_POS=", X1_MIN_POS, "\nX1_MAX_POS=", X1_MAX_POS); - DEBUG_ECHOPGM("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", X2_MIN_POS, "\nX2_MAX_POS=", X2_MAX_POS); - DEBUG_ECHOPGM("\nX2_HOME_DIR=", X2_HOME_DIR, "\nX2_HOME_POS=", X2_HOME_POS); - DEBUG_ECHOPGM("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE)); - DEBUG_ECHOPGM("\toolchange_settings.z_raise=", toolchange_settings.z_raise); - DEBUG_ECHOPGM("\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET); - DEBUG_EOL(); - - HOTEND_LOOP() { - DEBUG_ECHOPGM_P(SP_T_STR, e); - LOOP_NUM_AXES(a) DEBUG_ECHOPGM(" hotend_offset[", e, "].", AS_CHAR(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]); - DEBUG_EOL(); - } - DEBUG_EOL(); - } - #endif // DEBUG_DXC_MODE - } - -#elif ENABLED(MULTI_NOZZLE_DUPLICATION) - - /** - * M605: Set multi-nozzle duplication mode - * - * S2 - Enable duplication mode - * P[mask] - Bit-mask of nozzles to include in the duplication set. - * A value of 0 disables duplication. - * E[index] - Last nozzle index to include in the duplication set. - * A value of 0 disables duplication. - */ - void GcodeSuite::M605() { - bool ena = false; - if (parser.seen("EPS")) { - planner.synchronize(); - if (parser.seenval('P')) duplication_e_mask = parser.value_int(); // Set the mask directly - else if (parser.seenval('E')) duplication_e_mask = pow(2, parser.value_int() + 1) - 1; // Set the mask by E index - ena = (2 == parser.intval('S', extruder_duplication_enabled ? 2 : 0)); - set_duplication_enabled(ena && (duplication_e_mask >= 3)); - } - SERIAL_ECHO_START(); - SERIAL_ECHOPGM(STR_DUPLICATION_MODE); - serialprint_onoff(extruder_duplication_enabled); - if (ena) { - SERIAL_ECHOPGM(" ( "); - HOTEND_LOOP() if (TEST(duplication_e_mask, e)) { SERIAL_ECHO(e); SERIAL_CHAR(' '); } - SERIAL_CHAR(')'); - } - SERIAL_EOL(); - } - -#endif // MULTI_NOZZLE_DUPLICATION - -#endif // HAS_DUPICATION_MODE diff --git a/src/gcode/control/M7-M9.cpp b/src/gcode/control/M7-M9.cpp deleted file mode 100644 index ccde4f5..0000000 --- a/src/gcode/control/M7-M9.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfigPre.h" - -#if ANY(COOLANT_MIST, COOLANT_FLOOD, AIR_ASSIST) - -#include "../gcode.h" -#include "../../module/planner.h" - -#if ENABLED(COOLANT_MIST) - /** - * M7: Mist Coolant On - */ - void GcodeSuite::M7() { - planner.synchronize(); // Wait for move to arrive - WRITE(COOLANT_MIST_PIN, !(COOLANT_MIST_INVERT)); // Turn on Mist coolant - } -#endif - -#if EITHER(COOLANT_FLOOD, AIR_ASSIST) - - #if ENABLED(AIR_ASSIST) - #include "../../feature/spindle_laser.h" - #endif - - /** - * M8: Flood Coolant / Air Assist ON - */ - void GcodeSuite::M8() { - planner.synchronize(); // Wait for move to arrive - #if ENABLED(COOLANT_FLOOD) - WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant - #endif - #if ENABLED(AIR_ASSIST) - cutter.air_assist_enable(); // Turn on Air Assist - #endif - } - -#endif - -/** - * M9: Coolant / Air Assist OFF - */ -void GcodeSuite::M9() { - planner.synchronize(); // Wait for move to arrive - #if ENABLED(COOLANT_MIST) - WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant - #endif - #if ENABLED(COOLANT_FLOOD) - WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant - #endif - #if ENABLED(AIR_ASSIST) - cutter.air_assist_disable(); // Turn off Air Assist - #endif -} - -#endif // COOLANT_MIST | COOLANT_FLOOD | AIR_ASSIST diff --git a/src/gcode/control/M80_M81.cpp b/src/gcode/control/M80_M81.cpp deleted file mode 100644 index 90b25e7..0000000 --- a/src/gcode/control/M80_M81.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" - -#include "../../module/temperature.h" -#include "../../module/planner.h" // for planner.finish_and_disable -#include "../../module/printcounter.h" // for print_job_timer.stop -#include "../../lcd/marlinui.h" // for LCD_MESSAGE_F - -#include "../../inc/MarlinConfig.h" - -#if ENABLED(PSU_CONTROL) - #include "../queue.h" - #include "../../feature/power.h" -#endif - -#if HAS_SUICIDE - #include "../../MarlinCore.h" -#endif - -#if ENABLED(PSU_CONTROL) - - /** - * M80 : Turn on the Power Supply - * M80 S : Report the current state and exit - */ - void GcodeSuite::M80() { - - // S: Report the current power supply state and exit - if (parser.seen('S')) { - SERIAL_ECHOF(powerManager.psu_on ? F("PS:1\n") : F("PS:0\n")); - return; - } - - powerManager.power_on(); - - /** - * 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, !SUICIDE_PIN_STATE); - #endif - - TERN_(HAS_MARLINUI_MENU, ui.reset_status()); - } - -#endif // PSU_CONTROL - -/** - * M81: Turn off Power, including Power Supply, if there is one. - * - * This code should ALWAYS be available for FULL SHUTDOWN! - */ -void GcodeSuite::M81() { - planner.finish_and_disable(); - thermalManager.cooldown(); - - print_job_timer.stop(); - - #if BOTH(HAS_FAN, PROBING_FANS_OFF) - thermalManager.fans_paused = false; - ZERO(thermalManager.saved_fan_speed); - #endif - - safe_delay(1000); // Wait 1 second before switching off - - LCD_MESSAGE_F(MACHINE_NAME " " STR_OFF "."); - - bool delayed_power_off = false; - - #if ENABLED(POWER_OFF_TIMER) - if (parser.seenval('D')) { - uint16_t delay = parser.value_ushort(); - if (delay > 1) { // skip already observed 1s delay - delayed_power_off = true; - powerManager.setPowerOffTimer(SEC_TO_MS(delay - 1)); - } - } - #endif - - #if ENABLED(POWER_OFF_WAIT_FOR_COOLDOWN) - if (parser.boolval('S')) { - delayed_power_off = true; - powerManager.setPowerOffOnCooldown(true); - } - #endif - - if (delayed_power_off) { - SERIAL_ECHOLNPGM(STR_DELAYED_POWEROFF); - return; - } - - #if HAS_SUICIDE - suicide(); - #elif ENABLED(PSU_CONTROL) - powerManager.power_off_soon(); - #endif -} diff --git a/src/gcode/control/M85.cpp b/src/gcode/control/M85.cpp deleted file mode 100644 index ee86834..0000000 --- a/src/gcode/control/M85.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" - -/** - * M85: Set inactivity shutdown timer with parameter S. To disable set zero (default) - */ -void GcodeSuite::M85() { - - if (parser.seen('S')) { - reset_stepper_timeout(); - const millis_t ms = parser.value_millis_from_seconds(); - #if LASER_SAFETY_TIMEOUT_MS > 0 - if (ms && ms <= LASER_SAFETY_TIMEOUT_MS) { - SERIAL_ECHO_MSG("M85 timeout must be > ", MS_TO_SEC(LASER_SAFETY_TIMEOUT_MS + 999), " s for laser safety."); - return; - } - #endif - max_inactive_time = ms; - } - -} diff --git a/src/gcode/control/M993_M994.cpp b/src/gcode/control/M993_M994.cpp deleted file mode 100644 index 252792e..0000000 --- a/src/gcode/control/M993_M994.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../inc/MarlinConfig.h" - -#if ALL(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE) - -#include "../gcode.h" -#include "../../sd/cardreader.h" -#include "../../libs/W25Qxx.h" - -/** - * M993: Backup SPI Flash to SD - */ -void GcodeSuite::M993() { - if (!card.isMounted()) card.mount(); - - char fname[] = "spiflash.bin"; - card.openFileWrite(fname); - if (!card.isFileOpen()) { - SERIAL_ECHOLNPGM("Failed to open ", fname, " to write."); - return; - } - - uint8_t buf[1024]; - uint32_t addr = 0; - W25QXX.init(SPI_QUARTER_SPEED); - SERIAL_ECHOPGM("Save SPI Flash"); - while (addr < SPI_FLASH_SIZE) { - W25QXX.SPI_FLASH_BufferRead(buf, addr, COUNT(buf)); - addr += COUNT(buf); - card.write(buf, COUNT(buf)); - if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.'); - } - SERIAL_ECHOLNPGM(" done"); - - card.closefile(); -} - -/** - * M994: Load a backup from SD to SPI Flash - */ -void GcodeSuite::M994() { - if (!card.isMounted()) card.mount(); - - char fname[] = "spiflash.bin"; - card.openFileRead(fname); - if (!card.isFileOpen()) { - SERIAL_ECHOLNPGM("Failed to open ", fname, " to read."); - return; - } - - uint8_t buf[1024]; - uint32_t addr = 0; - W25QXX.init(SPI_QUARTER_SPEED); - W25QXX.SPI_FLASH_BulkErase(); - SERIAL_ECHOPGM("Load SPI Flash"); - while (addr < SPI_FLASH_SIZE) { - card.read(buf, COUNT(buf)); - W25QXX.SPI_FLASH_BufferWrite(buf, addr, COUNT(buf)); - addr += COUNT(buf); - if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.'); - } - SERIAL_ECHOLNPGM(" done"); - - card.closefile(); -} - -#endif // HAS_SPI_FLASH && SDSUPPORT && MARLIN_DEV_MODE diff --git a/src/gcode/control/M997.cpp b/src/gcode/control/M997.cpp deleted file mode 100644 index 74ed8b0..0000000 --- a/src/gcode/control/M997.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" - -#if ENABLED(PLATFORM_M997_SUPPORT) - -#if ENABLED(DWIN_LCD_PROUI) - #include "../../lcd/e3v2/proui/dwin.h" -#endif - -/** - * M997: Perform in-application firmware update - */ -void GcodeSuite::M997() { - - TERN_(DWIN_LCD_PROUI, DWIN_RebootScreen()); - - flashFirmware(parser.intval('S')); - -} - -#endif diff --git a/src/gcode/control/M999.cpp b/src/gcode/control/M999.cpp deleted file mode 100644 index b7d6db9..0000000 --- a/src/gcode/control/M999.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" - -#include "../../lcd/marlinui.h" // for ui.reset_alert_level -#include "../../MarlinCore.h" // for marlin_state -#include "../queue.h" // for flush_and_request_resend - -/** - * M999: Restart after being stopped - * - * Default behavior 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. - */ -void GcodeSuite::M999() { - marlin_state = MF_RUNNING; - ui.reset_alert_level(); - - if (parser.boolval('S')) return; - - queue.flush_and_request_resend(queue.ring_buffer.command_port()); -} diff --git a/src/gcode/control/T.cpp b/src/gcode/control/T.cpp deleted file mode 100644 index 5e8f6b5..0000000 --- a/src/gcode/control/T.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General 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 "../gcode.h" -#include "../../module/tool_change.h" - -#if EITHER(HAS_MULTI_EXTRUDER, DEBUG_LEVELING_FEATURE) - #include "../../module/motion.h" -#endif - -#if HAS_PRUSA_MMU2 - #include "../../feature/mmu/mmu2.h" -#endif - -#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) -#include "../../core/debug_out.h" - -/** - * T0-T: Switch tool, usually switching extruders - * - * F[units/min] Set the movement feedrate - * S1 Don't move the tool in XY after change - * - * For PRUSA_MMU2(S) and EXTENDABLE_EMU_MMU2(S) - * T[n] Gcode to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels. - * T? Gcode to extrude shouldn't have to follow. Load to extruder wheels is done automatically. - * Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load. - * Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated. - */ -void GcodeSuite::T(const int8_t tool_index) { - - DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING)); - if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")"); - - // Count this command as movement / activity - reset_stepper_timeout(); - - #if HAS_PRUSA_MMU2 - if (parser.string_arg) { - mmu2.tool_change(parser.string_arg); // Special commands T?/Tx/Tc - return; - } - #endif - - tool_change(tool_index - #if HAS_MULTI_EXTRUDER - , TERN(PARKING_EXTRUDER, false, tool_index == active_extruder) // For PARKING_EXTRUDER motion is decided in tool_change() - || parser.boolval('S') - #endif - ); -} diff --git a/src/gcode/eeprom/M500-M504.cpp b/src/gcode/eeprom/M500-M504.cpp deleted file mode 100644 index 412d003..0000000 --- a/src/gcode/eeprom/M500-M504.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../gcode.h" -#include "../../module/settings.h" -#include "../../core/serial.h" -#include "../../inc/MarlinConfig.h" - -#if ENABLED(CONFIGURATION_EMBEDDING) - #include "../../sd/SdBaseFile.h" - #include "../../mczip.h" -#endif - -/** - * M500: Store settings in EEPROM - */ -void GcodeSuite::M500() { - (void)settings.save(); -} - -/** - * M501: Read settings from EEPROM - */ -void GcodeSuite::M501() { - (void)settings.load(); -} - -/** - * M502: Revert to default settings - */ -void GcodeSuite::M502() { - (void)settings.reset(); -} - -#if DISABLED(DISABLE_M503) - - /** - * M503: print settings currently in memory - * - * S : Include / exclude header comments in the output. (Default: S1) - * - * With CONFIGURATION_EMBEDDING: - * C : Save the full Marlin configuration to SD Card as "mc.zip" - */ - void GcodeSuite::M503() { - (void)settings.report(!parser.boolval('S', true)); - - #if ENABLED(CONFIGURATION_EMBEDDING) - if (parser.seen_test('C')) { - SdBaseFile file; - const uint16_t size = sizeof(mc_zip); - // Need to create the config size on the SD card - if (file.open("mc.zip", O_WRITE|O_CREAT) && file.write(pgm_read_ptr(mc_zip), size) != -1 && file.close()) - SERIAL_ECHO_MSG("Configuration saved as 'mc.zip'"); - } - #endif - } - -#endif // !DISABLE_M503 - -#if ENABLED(EEPROM_SETTINGS) - - #if ENABLED(MARLIN_DEV_MODE) - #include "../../libs/hex_print.h" - #endif - - /** - * M504: Validate EEPROM Contents - */ - void GcodeSuite::M504() { - #if ENABLED(MARLIN_DEV_MODE) - const bool dowrite = parser.seenval('W'); - if (dowrite || parser.seenval('R')) { - uint8_t val = 0; - int addr = parser.value_ushort(); - if (dowrite) { - val = parser.byteval('V'); - persistentStore.write_data(addr, &val); - SERIAL_ECHOLNPGM("Wrote address ", addr, " with ", val); - } - else { - if (parser.seenval('T')) { - const int endaddr = parser.value_ushort(); - while (addr <= endaddr) { - persistentStore.read_data(addr, &val); - SERIAL_ECHOLNPGM("0x", hex_word(addr), ":", hex_byte(val)); - addr++; - safe_delay(10); - } - SERIAL_EOL(); - } - else { - persistentStore.read_data(addr, &val); - SERIAL_ECHOLNPGM("Read address ", addr, " and got ", val); - } - } - return; - } - #endif - - if (settings.validate()) - SERIAL_ECHO_MSG("EEPROM OK"); - } - -#endif diff --git a/src/gcode/feature/L6470/M122.cpp b/src/gcode/feature/L6470/M122.cpp deleted file mode 100644 index 4a5629b..0000000 --- a/src/gcode/feature/L6470/M122.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_L64XX - -#include "../../gcode.h" -#include "../../../libs/L64XX/L64XX_Marlin.h" -#include "../../../module/stepper/indirection.h" - -void echo_yes_no(const bool yes); - -inline void L6470_say_status(const L64XX_axis_t axis) { - if (L64xxManager.spi_abort) return; - const L64XX_Marlin::L64XX_shadow_t &sh = L64xxManager.shadow; - L64xxManager.get_status(axis); - L64xxManager.say_axis(axis); - #if ENABLED(L6470_CHITCHAT) - char temp_buf[20]; - sprintf_P(temp_buf, PSTR(" status: %4x "), sh.STATUS_AXIS_RAW); - SERIAL_ECHO(temp_buf); - print_bin(sh.STATUS_AXIS_RAW); - switch (sh.STATUS_AXIS_LAYOUT) { - case L6470_STATUS_LAYOUT: SERIAL_ECHOPGM(" L6470"); break; - case L6474_STATUS_LAYOUT: SERIAL_ECHOPGM(" L6474"); break; - case L6480_STATUS_LAYOUT: SERIAL_ECHOPGM(" L6480/powerSTEP01"); break; - } - #endif - SERIAL_ECHOPGM("\n...OUTPUT: "); - SERIAL_ECHOF(sh.STATUS_AXIS & STATUS_HIZ ? F("OFF") : F("ON ")); - SERIAL_ECHOPGM(" BUSY: "); echo_yes_no((sh.STATUS_AXIS & STATUS_BUSY) == 0); - SERIAL_ECHOPGM(" DIR: "); - SERIAL_ECHOF((((sh.STATUS_AXIS & STATUS_DIR) >> 4) ^ L64xxManager.index_to_dir[axis]) ? F("FORWARD") : F("REVERSE")); - if (sh.STATUS_AXIS_LAYOUT == L6480_STATUS_LAYOUT) { - SERIAL_ECHOPGM(" Last Command: "); - if (sh.STATUS_AXIS & sh.STATUS_AXIS_WRONG_CMD) SERIAL_ECHOPGM("VALID"); - else SERIAL_ECHOPGM("ERROR"); - SERIAL_ECHOPGM("\n...THERMAL: "); - switch ((sh.STATUS_AXIS & (sh.STATUS_AXIS_TH_SD | sh.STATUS_AXIS_TH_WRN)) >> 11) { - case 0: SERIAL_ECHOPGM("DEVICE SHUTDOWN"); break; - case 1: SERIAL_ECHOPGM("BRIDGE SHUTDOWN"); break; - case 2: SERIAL_ECHOPGM("WARNING "); break; - case 3: SERIAL_ECHOPGM("OK "); break; - } - } - else { - SERIAL_ECHOPGM(" Last Command: "); - if (!(sh.STATUS_AXIS & sh.STATUS_AXIS_WRONG_CMD)) SERIAL_ECHOPGM("IN"); - SERIAL_ECHOPGM("VALID "); - SERIAL_ECHOF(sh.STATUS_AXIS & sh.STATUS_AXIS_NOTPERF_CMD ? F("COMPLETED ") : F("Not PERFORMED")); - SERIAL_ECHOPGM("\n...THERMAL: ", !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_SD) ? "SHUTDOWN " : !(sh.STATUS_AXIS & sh.STATUS_AXIS_TH_WRN) ? "WARNING " : "OK "); - } - SERIAL_ECHOPGM(" OVERCURRENT:"); echo_yes_no((sh.STATUS_AXIS & sh.STATUS_AXIS_OCD) == 0); - if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) { - SERIAL_ECHOPGM(" STALL:"); echo_yes_no((sh.STATUS_AXIS & sh.STATUS_AXIS_STEP_LOSS_A) == 0 || (sh.STATUS_AXIS & sh.STATUS_AXIS_STEP_LOSS_B) == 0); - SERIAL_ECHOPGM(" STEP-CLOCK MODE:"); echo_yes_no((sh.STATUS_AXIS & sh.STATUS_AXIS_SCK_MOD) != 0); - } - else { - SERIAL_ECHOPGM(" STALL: NA " - " STEP-CLOCK MODE: NA" - " UNDER VOLTAGE LOCKOUT: "); echo_yes_no((sh.STATUS_AXIS & sh.STATUS_AXIS_UVLO) == 0); - } - SERIAL_EOL(); -} - -/** - * M122: Debug L6470 drivers - */ -void GcodeSuite::M122() { - L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status - L64xxManager.spi_active = true; // Tell set_directions() a series of SPI transfers is underway - - //if (parser.seen('S')) - // tmc_set_report_interval(parser.value_bool()); - //else - - #if AXIS_IS_L64XX(X) - L6470_say_status(X); - #endif - #if AXIS_IS_L64XX(X2) - L6470_say_status(X2); - #endif - #if AXIS_IS_L64XX(Y) - L6470_say_status(Y); - #endif - #if AXIS_IS_L64XX(Y2) - L6470_say_status(Y2); - #endif - #if AXIS_IS_L64XX(Z) - L6470_say_status(Z); - #endif - #if AXIS_IS_L64XX(Z2) - L6470_say_status(Z2); - #endif - #if AXIS_IS_L64XX(Z3) - L6470_say_status(Z3); - #endif - #if AXIS_IS_L64XX(Z4) - L6470_say_status(Z4); - #endif - #if AXIS_IS_L64XX(E0) - L6470_say_status(E0); - #endif - #if AXIS_IS_L64XX(E1) - L6470_say_status(E1); - #endif - #if AXIS_IS_L64XX(E2) - L6470_say_status(E2); - #endif - #if AXIS_IS_L64XX(E3) - L6470_say_status(E3); - #endif - #if AXIS_IS_L64XX(E4) - L6470_say_status(E4); - #endif - #if AXIS_IS_L64XX(E5) - L6470_say_status(E5); - #endif - #if AXIS_IS_L64XX(E6) - L6470_say_status(E6); - #endif - #if AXIS_IS_L64XX(E7) - L6470_say_status(E7); - #endif - - L64xxManager.spi_active = false; // done with all SPI transfers - clear handshake flags - L64xxManager.spi_abort = false; - L64xxManager.pause_monitor(false); -} - -#endif // HAS_L64XX diff --git a/src/gcode/feature/L6470/M906.cpp b/src/gcode/feature/L6470/M906.cpp deleted file mode 100644 index ee0211d..0000000 --- a/src/gcode/feature/L6470/M906.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_L64XX - -#if AXIS_COLLISION('I') - #error "M906 parameter 'I' collision with axis name." -#endif - -#include "../../gcode.h" -#include "../../../libs/L64XX/L64XX_Marlin.h" -#include "../../../module/stepper/indirection.h" -#include "../../../module/planner.h" - -#define DEBUG_OUT ENABLED(L6470_CHITCHAT) -#include "../../../core/debug_out.h" - -/** - * MACRO to fetch information on the items associated with current limiting - * and maximum voltage output. - * - * L6470 can be setup to shutdown if either current threshold is exceeded. - * - * L6470 output current can not be set directly. It is set indirectly by - * setting the maximum effective output voltage. - * - * Effective output voltage is set by PWM duty cycle. - * - * Maximum effective output voltage is affected by MANY variables. The main ones are: - * KVAL_HOLD - * KVAL_RUN - * KVAL_ACC - * KVAL_DEC - * Vs compensation (if enabled) - */ -void L64XX_report_current(L64XX &motor, const L64XX_axis_t axis) { - - if (L64xxManager.spi_abort) return; // don't do anything if set_directions() has occurred - - const L64XX_Marlin::L64XX_shadow_t &sh = L64xxManager.shadow; - const uint16_t status = L64xxManager.get_status(axis); //also populates shadow structure - const uint8_t OverCurrent_Threshold = uint8_t(motor.GetParam(L6470_OCD_TH)); - - auto say_axis_status = [](const L64XX_axis_t axis, const uint16_t status) { - L64xxManager.say_axis(axis); - #if ENABLED(L6470_CHITCHAT) - char tmp[10]; - sprintf_P(tmp, PSTR("%4x "), status); - DEBUG_ECHOPGM(" status: ", tmp); - print_bin(status); - #else - UNUSED(status); - #endif - SERIAL_EOL(); - }; - - char temp_buf[10]; - - switch (sh.STATUS_AXIS_LAYOUT) { - case L6470_STATUS_LAYOUT: // L6470 - case L6480_STATUS_LAYOUT: { // L6480 & powerstep01 - const uint16_t Stall_Threshold = (uint8_t)motor.GetParam(L6470_STALL_TH), - motor_status = (status & (STATUS_MOT_STATUS)) >> 5, - L6470_ADC_out = motor.GetParam(L6470_ADC_OUT), - L6470_ADC_out_limited = constrain(L6470_ADC_out, 8, 24); - const float comp_coef = 1600.0f / L6470_ADC_out_limited; - const uint16_t MicroSteps = _BV(motor.GetParam(L6470_STEP_MODE) & 0x07); - - say_axis_status(axis, sh.STATUS_AXIS_RAW); - - SERIAL_ECHOPGM("...OverCurrent Threshold: "); - sprintf_P(temp_buf, PSTR("%2d ("), OverCurrent_Threshold); - SERIAL_ECHO(temp_buf); - SERIAL_ECHO((OverCurrent_Threshold + 1) * motor.OCD_CURRENT_CONSTANT_INV); - SERIAL_ECHOPGM(" mA)"); - SERIAL_ECHOPGM(" Stall Threshold: "); - sprintf_P(temp_buf, PSTR("%2d ("), Stall_Threshold); - SERIAL_ECHO(temp_buf); - SERIAL_ECHO((Stall_Threshold + 1) * motor.STALL_CURRENT_CONSTANT_INV); - SERIAL_ECHOPGM(" mA)"); - SERIAL_ECHOPGM(" Motor Status: "); - switch (motor_status) { - case 0: SERIAL_ECHOPGM("stopped"); break; - case 1: SERIAL_ECHOPGM("accelerating"); break; - case 2: SERIAL_ECHOPGM("decelerating"); break; - case 3: SERIAL_ECHOPGM("at constant speed"); break; - } - SERIAL_EOL(); - - SERIAL_ECHOPGM("...MicroSteps: ", MicroSteps, - " ADC_OUT: ", L6470_ADC_out); - SERIAL_ECHOPGM(" Vs_compensation: "); - SERIAL_ECHOF((motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_EN_VSCOMP) ? F("ENABLED ") : F("DISABLED")); - SERIAL_ECHOLNPGM(" Compensation coefficient: ~", comp_coef * 0.01f); - - SERIAL_ECHOPGM("...KVAL_HOLD: ", motor.GetParam(L6470_KVAL_HOLD), - " KVAL_RUN : ", motor.GetParam(L6470_KVAL_RUN), - " KVAL_ACC: ", motor.GetParam(L6470_KVAL_ACC), - " KVAL_DEC: ", motor.GetParam(L6470_KVAL_DEC), - " V motor max = "); - switch (motor_status) { - case 0: SERIAL_ECHO(motor.GetParam(L6470_KVAL_HOLD) * 100 / 256); SERIAL_ECHOPGM("% (KVAL_HOLD)"); break; - case 1: SERIAL_ECHO(motor.GetParam(L6470_KVAL_RUN) * 100 / 256); SERIAL_ECHOPGM("% (KVAL_RUN)"); break; - case 2: SERIAL_ECHO(motor.GetParam(L6470_KVAL_ACC) * 100 / 256); SERIAL_ECHOPGM("% (KVAL_ACC)"); break; - case 3: SERIAL_ECHO(motor.GetParam(L6470_KVAL_DEC) * 100 / 256); SERIAL_ECHOPGM("% (KVAL_HOLD)"); break; - } - SERIAL_EOL(); - - #if ENABLED(L6470_CHITCHAT) - DEBUG_ECHOPGM("...SLEW RATE: "); - switch (sh.STATUS_AXIS_LAYOUT) { - case L6470_STATUS_LAYOUT: { - switch ((motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_POW_SR) >> CONFIG_POW_SR_BIT) { - case 0: { DEBUG_ECHOLNPGM("320V/uS") ; break; } - case 1: { DEBUG_ECHOLNPGM("75V/uS") ; break; } - case 2: { DEBUG_ECHOLNPGM("110V/uS") ; break; } - case 3: { DEBUG_ECHOLNPGM("260V/uS") ; break; } - } - break; - } - case L6480_STATUS_LAYOUT: { - switch (motor.GetParam(L6470_GATECFG1) & CONFIG1_SR ) { - case CONFIG1_SR_220V_us: { DEBUG_ECHOLNPGM("220V/uS") ; break; } - case CONFIG1_SR_400V_us: { DEBUG_ECHOLNPGM("400V/uS") ; break; } - case CONFIG1_SR_520V_us: { DEBUG_ECHOLNPGM("520V/uS") ; break; } - case CONFIG1_SR_980V_us: { DEBUG_ECHOLNPGM("980V/uS") ; break; } - default: { DEBUG_ECHOLNPGM("unknown") ; break; } - } - } - } - #endif - SERIAL_EOL(); - break; - } - - case L6474_STATUS_LAYOUT: { // L6474 - const uint16_t L6470_ADC_out = motor.GetParam(L6470_ADC_OUT) & 0x1F, - L6474_TVAL_val = motor.GetParam(L6474_TVAL) & 0x7F; - - say_axis_status(axis, sh.STATUS_AXIS_RAW); - - SERIAL_ECHOPGM("...OverCurrent Threshold: "); - sprintf_P(temp_buf, PSTR("%2d ("), OverCurrent_Threshold); - SERIAL_ECHO(temp_buf); - SERIAL_ECHO((OverCurrent_Threshold + 1) * motor.OCD_CURRENT_CONSTANT_INV); - SERIAL_ECHOPGM(" mA)"); - SERIAL_ECHOPGM(" TVAL: "); - sprintf_P(temp_buf, PSTR("%2d ("), L6474_TVAL_val); - SERIAL_ECHO(temp_buf); - SERIAL_ECHO((L6474_TVAL_val + 1) * motor.STALL_CURRENT_CONSTANT_INV); - SERIAL_ECHOLNPGM(" mA) Motor Status: NA"); - - const uint16_t MicroSteps = _BV(motor.GetParam(L6470_STEP_MODE) & 0x07); //NOMORE(MicroSteps, 16); - SERIAL_ECHOPGM("...MicroSteps: ", MicroSteps, - " ADC_OUT: ", L6470_ADC_out); - - SERIAL_ECHOLNPGM(" Vs_compensation: NA\n"); - SERIAL_ECHOLNPGM("...KVAL_HOLD: NA" - " KVAL_RUN : NA" - " KVAL_ACC: NA" - " KVAL_DEC: NA" - " V motor max = NA"); - - #if ENABLED(L6470_CHITCHAT) - DEBUG_ECHOPGM("...SLEW RATE: "); - switch ((motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_POW_SR) >> CONFIG_POW_SR_BIT) { - case 0: DEBUG_ECHOLNPGM("320V/uS") ; break; - case 1: DEBUG_ECHOLNPGM("75V/uS") ; break; - case 2: DEBUG_ECHOLNPGM("110V/uS") ; break; - case 3: DEBUG_ECHOLNPGM("260V/uS") ; break; - default: DEBUG_ECHOLNPGM("slew rate: ", (motor.GetParam(sh.L6470_AXIS_CONFIG) & CONFIG_POW_SR) >> CONFIG_POW_SR_BIT); break; - } - #endif - SERIAL_EOL(); - SERIAL_EOL(); - break; - } - } -} - -/** - * M906: report or set KVAL_HOLD which sets the maximum effective voltage provided by the - * PWMs to the steppers - * - * On L6474 this sets the TVAL register (same address). - * - * I - select which driver(s) to change on multi-driver axis - * (default) all drivers on the axis - * 0 - monitor only the first XYZ... driver - * 1 - monitor only X2, Y2, Z2 - * 2 - monitor only Z3 - * 3 - monitor only Z4 - * Xxxx, Yxxx, Zxxx, Axxx, Bxxx, Cxxx, Exxx - axis to change (optional) - * L6474 - current in mA (4A max) - * All others - 0-255 - * - * Sets KVAL_HOLD which affects the current being driven through the stepper. - * - * L6470 is used in the STEP-CLOCK mode. KVAL_HOLD is the only KVAL_xxx - * that affects the effective voltage seen by the stepper. - */ -void GcodeSuite::M906() { - - L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status - - #define L6470_SET_KVAL_HOLD(Q) (AXIS_IS_L64XX(Q) ? stepper##Q.setTVALCurrent(value) : stepper##Q.SetParam(L6470_KVAL_HOLD, uint8_t(value))) - - DEBUG_ECHOLNPGM("M906"); - - uint8_t report_current = true; - - #if AXIS_IS_L64XX(X2) || AXIS_IS_L64XX(Y2) || AXIS_IS_L64XX(Z2) || AXIS_IS_L64XX(Z3) || AXIS_IS_L64XX(Z4) - const int8_t index = parser.byteval('I', -1); - #else - constexpr int8_t index = -1; - #endif - - LOOP_LOGICAL_AXES(i) if (uint16_t value = parser.intval(AXIS_CHAR(i))) { - - report_current = false; - - if (planner.has_blocks_queued() || planner.cleaning_buffer_counter) { - SERIAL_ECHOLNPGM("Test aborted. Can't set KVAL_HOLD while steppers are moving."); - return; - } - - switch (i) { - #if AXIS_IS_L64XX(X) || AXIS_IS_L64XX(X2) - case X_AXIS: - #if AXIS_IS_L64XX(X) - if (index < 0 || index == 0) L6470_SET_KVAL_HOLD(X); - #endif - #if AXIS_IS_L64XX(X2) - if (index < 0 || index == 1) L6470_SET_KVAL_HOLD(X2); - #endif - break; - #endif - - #if AXIS_IS_L64XX(Y) || AXIS_IS_L64XX(Y2) - case Y_AXIS: - #if AXIS_IS_L64XX(Y) - if (index < 0 || index == 0) L6470_SET_KVAL_HOLD(Y); - #endif - #if AXIS_IS_L64XX(Y2) - if (index < 0 || index == 1) L6470_SET_KVAL_HOLD(Y2); - #endif - break; - #endif - - #if AXIS_IS_L64XX(Z) || AXIS_IS_L64XX(Z2) || AXIS_IS_L64XX(Z3) || AXIS_IS_L64XX(Z4) - case Z_AXIS: - #if AXIS_IS_L64XX(Z) - if (index < 0 || index == 0) L6470_SET_KVAL_HOLD(Z); - #endif - #if AXIS_IS_L64XX(Z2) - if (index < 0 || index == 1) L6470_SET_KVAL_HOLD(Z2); - #endif - #if AXIS_IS_L64XX(Z3) - if (index < 0 || index == 2) L6470_SET_KVAL_HOLD(Z3); - #endif - #if AXIS_IS_L64XX(Z4) - if (index < 0 || index == 3) L6470_SET_KVAL_HOLD(Z4); - #endif - break; - #endif - - #if AXIS_IS_L64XX(E0) || AXIS_IS_L64XX(E1) || AXIS_IS_L64XX(E2) || AXIS_IS_L64XX(E3) || AXIS_IS_L64XX(E4) || AXIS_IS_L64XX(E5) || AXIS_IS_L64XX(E6) || AXIS_IS_L64XX(E7) - case E_AXIS: { - const int8_t eindex = get_target_e_stepper_from_command(-2); - #if AXIS_IS_L64XX(E0) - if (eindex < 0 || eindex == 0) L6470_SET_KVAL_HOLD(E0); - #endif - #if AXIS_IS_L64XX(E1) - if (eindex < 0 || eindex == 1) L6470_SET_KVAL_HOLD(E1); - #endif - #if AXIS_IS_L64XX(E2) - if (eindex < 0 || eindex == 2) L6470_SET_KVAL_HOLD(E2); - #endif - #if AXIS_IS_L64XX(E3) - if (eindex < 0 || eindex == 3) L6470_SET_KVAL_HOLD(E3); - #endif - #if AXIS_IS_L64XX(E4) - if (eindex < 0 || eindex == 4) L6470_SET_KVAL_HOLD(E4); - #endif - #if AXIS_IS_L64XX(E5) - if (eindex < 0 || eindex == 5) L6470_SET_KVAL_HOLD(E5); - #endif - #if AXIS_IS_L64XX(E6) - if (eindex < 0 || eindex == 6) L6470_SET_KVAL_HOLD(E6); - #endif - #if AXIS_IS_L64XX(E7) - if (eindex < 0 || eindex == 7) L6470_SET_KVAL_HOLD(E7); - #endif - } break; - #endif - } - } - - if (report_current) { - #define L64XX_REPORT_CURRENT(Q) L64XX_report_current(stepper##Q, Q) - - L64xxManager.spi_active = true; // Tell set_directions() a series of SPI transfers is underway - - #if AXIS_IS_L64XX(X) - L64XX_REPORT_CURRENT(X); - #endif - #if AXIS_IS_L64XX(X2) - L64XX_REPORT_CURRENT(X2); - #endif - #if AXIS_IS_L64XX(Y) - L64XX_REPORT_CURRENT(Y); - #endif - #if AXIS_IS_L64XX(Y2) - L64XX_REPORT_CURRENT(Y2); - #endif - #if AXIS_IS_L64XX(Z) - L64XX_REPORT_CURRENT(Z); - #endif - #if AXIS_IS_L64XX(Z2) - L64XX_REPORT_CURRENT(Z2); - #endif - #if AXIS_IS_L64XX(Z3) - L64XX_REPORT_CURRENT(Z3); - #endif - #if AXIS_IS_L64XX(Z4) - L64XX_REPORT_CURRENT(Z4); - #endif - #if AXIS_IS_L64XX(E0) - L64XX_REPORT_CURRENT(E0); - #endif - #if AXIS_IS_L64XX(E1) - L64XX_REPORT_CURRENT(E1); - #endif - #if AXIS_IS_L64XX(E2) - L64XX_REPORT_CURRENT(E2); - #endif - #if AXIS_IS_L64XX(E3) - L64XX_REPORT_CURRENT(E3); - #endif - #if AXIS_IS_L64XX(E4) - L64XX_REPORT_CURRENT(E4); - #endif - #if AXIS_IS_L64XX(E5) - L64XX_REPORT_CURRENT(E5); - #endif - #if AXIS_IS_L64XX(E6) - L64XX_REPORT_CURRENT(E6); - #endif - #if AXIS_IS_L64XX(E7) - L64XX_REPORT_CURRENT(E7); - #endif - - L64xxManager.spi_active = false; // done with all SPI transfers - clear handshake flags - L64xxManager.spi_abort = false; - L64xxManager.pause_monitor(false); - } -} - -#endif // HAS_L64XX diff --git a/src/gcode/feature/L6470/M916-M918.cpp b/src/gcode/feature/L6470/M916-M918.cpp deleted file mode 100644 index 9e1f1b9..0000000 --- a/src/gcode/feature/L6470/M916-M918.cpp +++ /dev/null @@ -1,650 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -// -// NOTE: All tests assume each axis uses matching driver chips. -// - -#include "../../../inc/MarlinConfig.h" - -#if HAS_L64XX - -#include "../../gcode.h" -#include "../../../module/stepper/indirection.h" -#include "../../../module/planner.h" -#include "../../../libs/L64XX/L64XX_Marlin.h" - -#define DEBUG_OUT ENABLED(L6470_CHITCHAT) -#include "../../../core/debug_out.h" - -/** - * M916: increase KVAL_HOLD until get thermal warning - * NOTE - on L6474 it is TVAL that is used - * - * J - select which driver(s) to monitor on multi-driver axis - * 0 - (default) monitor all drivers on the axis or E0 - * 1 - monitor only X, Y, Z, E1 - * 2 - monitor only X2, Y2, Z2, E2 - * 3 - monitor only Z3, E3 - * 4 - monitor only Z4, E4 - * - * Xxxx, Yxxx, Zxxx, Exxx - axis to be monitored with displacement - * xxx (1-255) is distance moved on either side of current position - * - * F - feedrate - * optional - will use default max feedrate from configuration.h if not specified - * - * T - current (mA) setting for TVAL (0 - 4A in 31.25mA increments, rounds down) - L6474 only - * optional - will report current value from driver if not specified - * - * K - value for KVAL_HOLD (0 - 255) (ignored for L6474) - * optional - will report current value from driver if not specified - * - * D - time (in seconds) to run each setting of KVAL_HOLD/TVAL - * optional - defaults to zero (runs each setting once) - */ - -/** - * This routine is also useful for determining the approximate KVAL_HOLD - * where the stepper stops losing steps. The sound will get noticeably quieter - * as it stops losing steps. - */ - -void GcodeSuite::M916() { - - DEBUG_ECHOLNPGM("M916"); - - L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status - - // Variables used by L64xxManager.get_user_input function - some may not be used - char axis_mon[3][3] = { {" "}, {" "}, {" "} }; // list of Axes to be monitored - L64XX_axis_t axis_index[3]; - uint16_t axis_status[3]; - uint8_t driver_count = 1; - float position_max; - float position_min; - float final_feedrate; - uint8_t kval_hold; - uint8_t OCD_TH_val = 0; - uint8_t STALL_TH_val = 0; - uint16_t over_current_threshold; - constexpr uint8_t over_current_flag = false; // M916 doesn't play with the overcurrent thresholds - - #define DRIVER_TYPE_L6474(Q) AXIS_DRIVER_TYPE_##Q(L6474) - - uint8_t j; // general purpose counter - - if (L64xxManager.get_user_input(driver_count, axis_index, axis_mon, position_max, position_min, final_feedrate, kval_hold, over_current_flag, OCD_TH_val, STALL_TH_val, over_current_threshold)) - return; // quit if invalid user input - - DEBUG_ECHOLNPGM("feedrate = ", final_feedrate); - - planner.synchronize(); // wait for all current movement commands to complete - - const L64XX_Marlin::L64XX_shadow_t &sh = L64xxManager.shadow; - for (j = 0; j < driver_count; j++) - L64xxManager.get_status(axis_index[j]); // clear out any pre-existing error flags - - char temp_axis_string[] = " "; - temp_axis_string[0] = axis_mon[0][0]; // need to have a string for use within sprintf format section - char gcode_string[80]; - uint16_t status_composite = 0; - - uint16_t M91x_counter = kval_hold; - uint16_t M91x_counter_max; - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) { - M91x_counter_max = 128; // TVAL is 7 bits - LIMIT(M91x_counter, 0U, 127U); - } - else - M91x_counter_max = 256; // KVAL_HOLD is 8 bits - - uint8_t M91x_delay_s = parser.byteval('D'); // get delay in seconds - millis_t M91x_delay_ms = SEC_TO_MS(M91x_delay_s * 60); - millis_t M91x_delay_end; - - DEBUG_ECHOLNPGM(".\n."); - - do { - - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) - DEBUG_ECHOLNPGM("TVAL current (mA) = ", (M91x_counter + 1) * sh.AXIS_STALL_CURRENT_CONSTANT_INV); // report TVAL current for this run - else - DEBUG_ECHOLNPGM("kval_hold = ", M91x_counter); // report KVAL_HOLD for this run - - for (j = 0; j < driver_count; j++) - L64xxManager.set_param(axis_index[j], L6470_KVAL_HOLD, M91x_counter); //set KVAL_HOLD or TVAL (same register address) - - M91x_delay_end = millis() + M91x_delay_ms; - do { - // turn the motor(s) both directions - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(final_feedrate)); - process_subcommands_now(gcode_string); - - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(final_feedrate)); - process_subcommands_now(gcode_string); - - // get the status after the motors have stopped - planner.synchronize(); - - status_composite = 0; // clear out the old bits - - for (j = 0; j < driver_count; j++) { - axis_status[j] = (~L64xxManager.get_status(axis_index[j])) & sh.L6470_ERROR_MASK; // bits of interest are all active low - status_composite |= axis_status[j] ; - } - - if (status_composite) break; - } while (millis() < M91x_delay_end); - - if (status_composite) break; - - M91x_counter++; - - } while (!(status_composite & (sh.STATUS_AXIS_TH_WRN | sh.STATUS_AXIS_TH_SD)) && (M91x_counter < M91x_counter_max)); - - DEBUG_ECHOLNPGM("."); - - #if ENABLED(L6470_CHITCHAT) - if (status_composite) { - L64xxManager.error_status_decode(status_composite, axis_index[0], - sh.STATUS_AXIS_TH_SD, sh.STATUS_AXIS_TH_WRN, - sh.STATUS_AXIS_STEP_LOSS_A, sh.STATUS_AXIS_STEP_LOSS_B, - sh.STATUS_AXIS_OCD, sh.STATUS_AXIS_LAYOUT); - DEBUG_ECHOLNPGM("."); - } - #endif - - if ((status_composite & (sh.STATUS_AXIS_TH_WRN | sh.STATUS_AXIS_TH_SD))) - DEBUG_ECHOLNPGM(".\n.\nTest completed normally - Thermal warning/shutdown has occurred"); - else if (status_composite) - DEBUG_ECHOLNPGM(".\n.\nTest completed abnormally - non-thermal error has occurred"); - else - DEBUG_ECHOLNPGM(".\n.\nTest completed normally - Unable to get to thermal warning/shutdown"); - - L64xxManager.pause_monitor(false); -} - -/** - * M917: Find minimum current thresholds - * - * Decrease OCD current until overcurrent error - * Increase OCD until overcurrent error goes away - * Decrease stall threshold until stall (not done on L6474) - * Increase stall until stall error goes away (not done on L6474) - * - * J - select which driver(s) to monitor on multi-driver axis - * 0 - (default) monitor all drivers on the axis or E0 - * 1 - monitor only X, Y, Z, E1 - * 2 - monitor only X2, Y2, Z2, E2 - * Xxxx, Yxxx, Zxxx, Exxx - axis to be monitored with displacement - * xxx (1-255) is distance moved on either side of current position - * - * F - feedrate - * optional - will use default max feedrate from Configuration.h if not specified - * - * I - starting over-current threshold - * optional - will report current value from driver if not specified - * if there are multiple drivers on the axis then all will be set the same - * - * T - current (mA) setting for TVAL (0 - 4A in 31.25mA increments, rounds down) - L6474 only - * optional - will report current value from driver if not specified - * - * K - value for KVAL_HOLD (0 - 255) (ignored for L6474) - * optional - will report current value from driver if not specified - */ -void GcodeSuite::M917() { - - DEBUG_ECHOLNPGM("M917"); - - L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status - - char axis_mon[3][3] = { {" "}, {" "}, {" "} }; // list of Axes to be monitored - L64XX_axis_t axis_index[3]; - uint16_t axis_status[3]; - uint8_t driver_count = 1; - float position_max; - float position_min; - float final_feedrate; - uint8_t kval_hold; - uint8_t OCD_TH_val = 0; - uint8_t STALL_TH_val = 0; - uint16_t over_current_threshold; - constexpr uint8_t over_current_flag = true; - - uint8_t j; // general purpose counter - - if (L64xxManager.get_user_input(driver_count, axis_index, axis_mon, position_max, position_min, final_feedrate, kval_hold, over_current_flag, OCD_TH_val, STALL_TH_val, over_current_threshold)) - return; // quit if invalid user input - - DEBUG_ECHOLNPGM("feedrate = ", final_feedrate); - - planner.synchronize(); // wait for all current movement commands to complete - - const L64XX_Marlin::L64XX_shadow_t &sh = L64xxManager.shadow; - for (j = 0; j < driver_count; j++) - L64xxManager.get_status(axis_index[j]); // clear error flags - char temp_axis_string[] = " "; - temp_axis_string[0] = axis_mon[0][0]; // need a sprintf format string - char gcode_string[80]; - uint16_t status_composite = 0; - uint8_t test_phase = 0; // 0 - decreasing OCD - exit when OCD warning occurs (ignore STALL) - // 1 - increasing OCD - exit when OCD warning stops (ignore STALL) - // 2 - OCD finalized - decreasing STALL - exit when STALL warning happens - // 3 - OCD finalized - increasing STALL - exit when STALL warning stop - // 4 - all testing completed - DEBUG_ECHOPGM(".\n.\n.\nover_current threshold : ", (OCD_TH_val + 1) * 375); // first status display - DEBUG_ECHOPGM(" (OCD_TH: : ", OCD_TH_val); - if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) { - DEBUG_ECHOPGM(") Stall threshold: ", (STALL_TH_val + 1) * 31.25); - DEBUG_ECHOPGM(" (STALL_TH: ", STALL_TH_val); - } - DEBUG_ECHOLNPGM(")"); - - do { - - if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) DEBUG_ECHOPGM("STALL threshold : ", (STALL_TH_val + 1) * 31.25); - DEBUG_ECHOLNPGM(" OCD threshold : ", (OCD_TH_val + 1) * 375); - - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(final_feedrate)); - process_subcommands_now(gcode_string); - - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(final_feedrate)); - process_subcommands_now(gcode_string); - - planner.synchronize(); - - status_composite = 0; // clear out the old bits - - for (j = 0; j < driver_count; j++) { - axis_status[j] = (~L64xxManager.get_status(axis_index[j])) & sh.L6470_ERROR_MASK; // bits of interest are all active low - status_composite |= axis_status[j]; - } - - if (status_composite && (status_composite & sh.STATUS_AXIS_UVLO)) { - DEBUG_ECHOLNPGM("Test aborted (Undervoltage lockout active)"); - #if ENABLED(L6470_CHITCHAT) - for (j = 0; j < driver_count; j++) { - if (j) DEBUG_ECHOPGM("..."); - L64xxManager.error_status_decode(axis_status[j], axis_index[j], - sh.STATUS_AXIS_TH_SD, sh.STATUS_AXIS_TH_WRN, - sh.STATUS_AXIS_STEP_LOSS_A, sh.STATUS_AXIS_STEP_LOSS_B, - sh.STATUS_AXIS_OCD, sh.STATUS_AXIS_LAYOUT); - } - #endif - return; - } - - if (status_composite & (sh.STATUS_AXIS_TH_WRN | sh.STATUS_AXIS_TH_SD)) { - DEBUG_ECHOLNPGM("thermal problem - waiting for chip(s) to cool down "); - uint16_t status_composite_temp = 0; - uint8_t k = 0; - do { - k++; - if (!(k % 4)) { - kval_hold *= 0.95; - DEBUG_EOL(); - DEBUG_ECHOLNPGM("Lowering KVAL_HOLD by about 5% to ", kval_hold); - for (j = 0; j < driver_count; j++) - L64xxManager.set_param(axis_index[j], L6470_KVAL_HOLD, kval_hold); - } - DEBUG_ECHOLNPGM("."); - reset_stepper_timeout(); // keep steppers powered - safe_delay(5000); - status_composite_temp = 0; - for (j = 0; j < driver_count; j++) { - axis_status[j] = (~L64xxManager.get_status(axis_index[j])) & sh.L6470_ERROR_MASK; // bits of interest are all active low - status_composite_temp |= axis_status[j]; - } - } - while (status_composite_temp & (sh.STATUS_AXIS_TH_WRN | sh.STATUS_AXIS_TH_SD)); - DEBUG_EOL(); - } - if (status_composite & (sh.STATUS_AXIS_STEP_LOSS_A | sh.STATUS_AXIS_STEP_LOSS_B | sh.STATUS_AXIS_OCD)) { - switch (test_phase) { - - case 0: { - if (status_composite & sh.STATUS_AXIS_OCD) { - // phase 0 with OCD warning - time to go to next phase - if (OCD_TH_val >= sh.AXIS_OCD_TH_MAX) { - OCD_TH_val = sh.AXIS_OCD_TH_MAX; // limit to max - test_phase = 2; // at highest value so skip phase 1 - //DEBUG_ECHOLNPGM("LOGIC E0A OCD at highest - skip to 2"); - DEBUG_ECHOLNPGM("OCD at highest - OCD finalized"); - } - else { - OCD_TH_val++; // normal exit to next phase - test_phase = 1; // setup for first pass of phase 1 - //DEBUG_ECHOLNPGM("LOGIC E0B - inc OCD & go to 1"); - DEBUG_ECHOLNPGM("inc OCD"); - } - } - else { // phase 0 without OCD warning - keep on decrementing if can - if (OCD_TH_val) { - OCD_TH_val--; // try lower value - //DEBUG_ECHOLNPGM("LOGIC E0C - dec OCD"); - DEBUG_ECHOLNPGM("dec OCD"); - } - else { - test_phase = 2; // at lowest value without warning so skip phase 1 - //DEBUG_ECHOLNPGM("LOGIC E0D - OCD at latest - go to 2"); - DEBUG_ECHOLNPGM("OCD finalized"); - } - } - } break; - - case 1: { - if (status_composite & sh.STATUS_AXIS_OCD) { - // phase 1 with OCD warning - increment if can - if (OCD_TH_val >= sh.AXIS_OCD_TH_MAX) { - OCD_TH_val = sh.AXIS_OCD_TH_MAX; // limit to max - test_phase = 2; // at highest value so go to next phase - //DEBUG_ECHOLNPGM("LOGIC E1A - OCD at max - go to 2"); - DEBUG_ECHOLNPGM("OCD finalized"); - } - else { - OCD_TH_val++; // try a higher value - //DEBUG_ECHOLNPGM("LOGIC E1B - inc OCD"); - DEBUG_ECHOLNPGM("inc OCD"); - } - } - else { // phase 1 without OCD warning - normal exit to phase 2 - test_phase = 2; - //DEBUG_ECHOLNPGM("LOGIC E1C - no OCD warning - go to 1"); - DEBUG_ECHOLNPGM("OCD finalized"); - } - } break; - - case 2: { - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) { // skip all STALL_TH steps if L6474 - test_phase = 4; - break; - } - if (status_composite & (sh.STATUS_AXIS_STEP_LOSS_A | sh.STATUS_AXIS_STEP_LOSS_B)) { - // phase 2 with stall warning - time to go to next phase - if (STALL_TH_val >= 127) { - STALL_TH_val = 127; // limit to max - //DEBUG_ECHOLNPGM("LOGIC E2A - STALL warning, STALL at max, quit"); - DEBUG_ECHOLNPGM("finished - STALL at maximum value but still have stall warning"); - test_phase = 4; - } - else { - test_phase = 3; // normal exit to next phase (found failing value of STALL) - STALL_TH_val++; // setup for first pass of phase 3 - //DEBUG_ECHOLNPGM("LOGIC E2B - INC - STALL warning, inc Stall, go to 3"); - DEBUG_ECHOLNPGM("inc Stall"); - } - } - else { // phase 2 without stall warning - decrement if can - if (STALL_TH_val) { - STALL_TH_val--; // try a lower value - //DEBUG_ECHOLNPGM("LOGIC E2C - no STALL, dec STALL"); - DEBUG_ECHOLNPGM("dec STALL"); - } - else { - DEBUG_ECHOLNPGM("finished - STALL at lowest value but still do NOT have stall warning"); - test_phase = 4; - //DEBUG_ECHOLNPGM("LOGIC E2D - no STALL, at lowest so quit"); - } - } - } break; - - case 3: { - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) { // skip all STALL_TH steps if L6474 - test_phase = 4; - break; - } - if (status_composite & (sh.STATUS_AXIS_STEP_LOSS_A | sh.STATUS_AXIS_STEP_LOSS_B)) { - // phase 3 with stall warning - increment if can - if (STALL_TH_val >= 127) { - STALL_TH_val = 127; // limit to max - DEBUG_ECHOLNPGM("finished - STALL at maximum value but still have stall warning"); - test_phase = 4; - //DEBUG_ECHOLNPGM("LOGIC E3A - STALL, at max so quit"); - } - else { - STALL_TH_val++; // still looking for passing value - //DEBUG_ECHOLNPGM("LOGIC E3B - STALL, inc stall"); - DEBUG_ECHOLNPGM("inc stall"); - } - } - else { //phase 3 without stall warning but have OCD warning - DEBUG_ECHOLNPGM("Hardware problem - OCD warning without STALL warning"); - test_phase = 4; - //DEBUG_ECHOLNPGM("LOGIC E3C - not STALLED, hardware problem (quit)"); - } - } break; - - } - - } - else { - switch (test_phase) { - case 0: { // phase 0 without OCD warning - keep on decrementing if can - if (OCD_TH_val) { - OCD_TH_val--; // try lower value - //DEBUG_ECHOLNPGM("LOGIC N0A - DEC OCD"); - DEBUG_ECHOLNPGM("DEC OCD"); - } - else { - test_phase = 2; // at lowest value without warning so skip phase 1 - //DEBUG_ECHOLNPGM("LOGIC N0B - OCD at lowest (go to phase 2)"); - DEBUG_ECHOLNPGM("OCD finalized"); - } - } break; - - case 1: //DEBUG_ECHOLNPGM("LOGIC N1 (go directly to 2)"); // phase 1 without OCD warning - drop directly to phase 2 - DEBUG_ECHOLNPGM("OCD finalized"); - - case 2: { // phase 2 without stall warning - keep on decrementing if can - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) { // skip all STALL_TH steps if L6474 - test_phase = 4; - break; - } - if (STALL_TH_val) { - STALL_TH_val--; // try a lower value (stay in phase 2) - //DEBUG_ECHOLNPGM("LOGIC N2B - dec STALL"); - DEBUG_ECHOLNPGM("dec STALL"); - } - else { - DEBUG_ECHOLNPGM("finished - STALL at lowest value but still no stall warning"); - test_phase = 4; - //DEBUG_ECHOLNPGM("LOGIC N2C - STALL at lowest (quit)"); - } - } break; - - case 3: { - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) { // skip all STALL_TH steps if L6474 - test_phase = 4; - break; - } - test_phase = 4; - //DEBUG_ECHOLNPGM("LOGIC N3 - finished!"); - DEBUG_ECHOLNPGM("finished!"); - } break; // phase 3 without any warnings - desired exit - } // - } // end of status checks - - if (test_phase != 4) { - for (j = 0; j < driver_count; j++) { // update threshold(s) - L64xxManager.set_param(axis_index[j], L6470_OCD_TH, OCD_TH_val); - if (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT) L64xxManager.set_param(axis_index[j], L6470_STALL_TH, STALL_TH_val); - if (L64xxManager.get_param(axis_index[j], L6470_OCD_TH) != OCD_TH_val) DEBUG_ECHOLNPGM("OCD mismatch"); - if ((L64xxManager.get_param(axis_index[j], L6470_STALL_TH) != STALL_TH_val) && (sh.STATUS_AXIS_LAYOUT != L6474_STATUS_LAYOUT)) DEBUG_ECHOLNPGM("STALL mismatch"); - } - } - - } while (test_phase != 4); - - DEBUG_ECHOLNPGM("."); - if (status_composite) { - #if ENABLED(L6470_CHITCHAT) - for (j = 0; j < driver_count; j++) { - if (j) DEBUG_ECHOPGM("..."); - L64xxManager.error_status_decode(axis_status[j], axis_index[j], - sh.STATUS_AXIS_TH_SD, sh.STATUS_AXIS_TH_WRN, - sh.STATUS_AXIS_STEP_LOSS_A, sh.STATUS_AXIS_STEP_LOSS_B, - sh.STATUS_AXIS_OCD, sh.STATUS_AXIS_LAYOUT); - } - DEBUG_ECHOLNPGM("."); - #endif - DEBUG_ECHOLNPGM("Completed with errors"); - } - else - DEBUG_ECHOLNPGM("Completed with no errors"); - DEBUG_ECHOLNPGM("."); - - L64xxManager.pause_monitor(false); -} - -/** - * M918: increase speed until error or max feedrate achieved (as shown in configuration.h)) - * - * J - select which driver(s) to monitor on multi-driver axis - * 0 - (default) monitor all drivers on the axis or E0 - * 1 - monitor only X, Y, Z, E1 - * 2 - monitor only X2, Y2, Z2, E2 - * Xxxx, Yxxx, Zxxx, Exxx - axis to be monitored with displacement - * xxx (1-255) is distance moved on either side of current position - * - * I - over current threshold - * optional - will report current value from driver if not specified - * - * T - current (mA) setting for TVAL (0 - 4A in 31.25mA increments, rounds down) - L6474 only - * optional - will report current value from driver if not specified - * - * K - value for KVAL_HOLD (0 - 255) (ignored for L6474) - * optional - will report current value from driver if not specified - * - * M - value for microsteps (1 - 128) (optional) - * optional - will report current value from driver if not specified - */ -void GcodeSuite::M918() { - - DEBUG_ECHOLNPGM("M918"); - - L64xxManager.pause_monitor(true); // Keep monitor_driver() from stealing status - - char axis_mon[3][3] = { {" "}, {" "}, {" "} }; // list of Axes to be monitored - L64XX_axis_t axis_index[3]; - uint16_t axis_status[3]; - uint8_t driver_count = 1; - float position_max, position_min; - float final_feedrate; - uint8_t kval_hold; - uint8_t OCD_TH_val = 0; - uint8_t STALL_TH_val = 0; - uint16_t over_current_threshold; - constexpr uint8_t over_current_flag = true; - - const L64XX_Marlin::L64XX_shadow_t &sh = L64xxManager.shadow; - - uint8_t j; // general purpose counter - - if (L64xxManager.get_user_input(driver_count, axis_index, axis_mon, position_max, position_min, final_feedrate, kval_hold, over_current_flag, OCD_TH_val, STALL_TH_val, over_current_threshold)) - return; // quit if invalid user input - - L64xxManager.get_status(axis_index[0]); // populate shadow array - - uint8_t m_steps = parser.byteval('M'); - - if (m_steps != 0) { - LIMIT(m_steps, 1, sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT ? 16 : 128); // L6474 - - uint8_t stepVal; - for (stepVal = 0; stepVal < 8; stepVal++) { // convert to L64xx register value - if (m_steps == 1) break; - m_steps >>= 1; - } - - if (sh.STATUS_AXIS_LAYOUT == L6474_STATUS_LAYOUT) - stepVal |= 0x98; // NO SYNC - else - stepVal |= (!SYNC_EN) | SYNC_SEL_1 | stepVal; - - for (j = 0; j < driver_count; j++) { - L64xxManager.set_param(axis_index[j], dSPIN_HARD_HIZ, 0); // can't write STEP register if stepper being powered - // results in an extra NOOP being sent (data 00) - L64xxManager.set_param(axis_index[j], L6470_STEP_MODE, stepVal); // set microsteps - } - } - m_steps = L64xxManager.get_param(axis_index[0], L6470_STEP_MODE) & 0x07; // get microsteps - - DEBUG_ECHOLNPGM("Microsteps = ", _BV(m_steps)); - DEBUG_ECHOLNPGM("target (maximum) feedrate = ", final_feedrate); - - const float feedrate_inc = final_feedrate / 10, // Start at 1/10 of max & go up by 1/10 per step - fr_limit = final_feedrate * 0.99f; // Rounding-safe comparison value - float current_feedrate = 0; - - planner.synchronize(); // Wait for moves to complete - - for (j = 0; j < driver_count; j++) - L64xxManager.get_status(axis_index[j]); // Clear error flags - - char temp_axis_string[2] = " "; - temp_axis_string[0] = axis_mon[0][0]; // Need a sprintf format string - //temp_axis_string[1] = '\n'; - - char gcode_string[80]; - uint16_t status_composite = 0; - DEBUG_ECHOLNPGM(".\n.\n."); // Make feedrate outputs easier to read - - do { - current_feedrate += feedrate_inc; - DEBUG_ECHOLNPGM("...feedrate = ", current_feedrate); - - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_min), uint16_t(current_feedrate)); - process_subcommands_now(gcode_string); - - sprintf_P(gcode_string, PSTR("G0 %s%03d F%03d"), temp_axis_string, uint16_t(position_max), uint16_t(current_feedrate)); - process_subcommands_now(gcode_string); - - planner.synchronize(); - - for (j = 0; j < driver_count; j++) { - axis_status[j] = (~L64xxManager.get_status(axis_index[j])) & 0x0800; // Bits of interest are all active LOW - status_composite |= axis_status[j]; - } - if (status_composite) break; // Break on any error - } while (current_feedrate < fr_limit); - - DEBUG_ECHOPGM("Completed with "); - if (status_composite) { - DEBUG_ECHOLNPGM("errors"); - #if ENABLED(L6470_CHITCHAT) - for (j = 0; j < driver_count; j++) { - if (j) DEBUG_ECHOPGM("..."); - L64xxManager.error_status_decode(axis_status[j], axis_index[j], - sh.STATUS_AXIS_TH_SD, sh.STATUS_AXIS_TH_WRN, - sh.STATUS_AXIS_STEP_LOSS_A, sh.STATUS_AXIS_STEP_LOSS_B, - sh.STATUS_AXIS_OCD, sh.STATUS_AXIS_LAYOUT); - } - #endif - } - else - DEBUG_ECHOLNPGM("no errors"); - - L64xxManager.pause_monitor(false); -} - -#endif // HAS_L64XX diff --git a/src/gcode/feature/adc/M3426.cpp b/src/gcode/feature/adc/M3426.cpp deleted file mode 100644 index 2820c8b..0000000 --- a/src/gcode/feature/adc/M3426.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(HAS_MCP3426_ADC) - -#include "../../gcode.h" - -#include "../../../feature/adc/adc_mcp3426.h" - -#define MCP3426_BASE_ADDR (0b1101 << 3) - -/** - * M3426: Read 16 bit (signed) value from I2C MCP3426 ADC device - * - * M3426 C channel 1 or 2 - * M3426 G gain 1, 2, 4 or 8 - * M3426 I 0 or 1, invert reply - */ -void GcodeSuite::M3426() { - uint8_t channel = parser.byteval('C', 1), // Channel 1 or 2 - gain = parser.byteval('G', 1), // Gain 1, 2, 4, or 8 - address = parser.byteval('A', 3); // Address 0-7 (or 104-111) - const bool inverted = parser.boolval('I'); - - if (address <= 7) address += MCP3426_BASE_ADDR; - - if (WITHIN(channel, 1, 2) && (gain == 1 || gain == 2 || gain == 4 || gain == 8) && WITHIN(address, MCP3426_BASE_ADDR, MCP3426_BASE_ADDR + 7)) { - int16_t result = mcp3426.ReadValue(channel, gain, address); - - if (mcp3426.Error == false) { - if (inverted) { - // Should we invert the reading (32767 - ADC value) ? - // Caters to end devices that expect values to increase when in reality they decrease. - // e.g., A pressure sensor in a vacuum when the end device expects a positive pressure. - result = INT16_MAX - result; - } - //SERIAL_ECHOPGM(STR_OK); - SERIAL_ECHOLNPGM("V:", result, " C:", channel, " G:", gain, " I:", inverted ? 1 : 0); - } - else - SERIAL_ERROR_MSG("MCP342X i2c error"); - } - else - SERIAL_ERROR_MSG("MCP342X Bad request"); -} - -#endif // HAS_MCP3426_ADC diff --git a/src/gcode/feature/advance/M900.cpp b/src/gcode/feature/advance/M900.cpp deleted file mode 100644 index db09faa..0000000 --- a/src/gcode/feature/advance/M900.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(LIN_ADVANCE) - -#include "../../gcode.h" -#include "../../../module/planner.h" - -#if ENABLED(EXTRA_LIN_ADVANCE_K) - float other_extruder_advance_K[EXTRUDERS]; - uint8_t lin_adv_slot = 0; -#endif - -/** - * M900: Get or Set Linear Advance K-factor - * T Which tool to address - * K Set current advance K factor (Slot 0). - * L Set secondary advance K factor (Slot 1). Requires EXTRA_LIN_ADVANCE_K. - * S<0/1> Activate slot 0 or 1. Requires EXTRA_LIN_ADVANCE_K. - */ -void GcodeSuite::M900() { - - auto echo_value_oor = [](const char ltr, const bool ten=true) { - SERIAL_CHAR('?', ltr); - SERIAL_ECHOPGM(" value out of range"); - if (ten) SERIAL_ECHOPGM(" (0-10)"); - SERIAL_ECHOLNPGM("."); - }; - - #if EXTRUDERS < 2 - constexpr uint8_t tool_index = 0; - #else - const uint8_t tool_index = parser.intval('T', active_extruder); - if (tool_index >= EXTRUDERS) { - echo_value_oor('T', false); - return; - } - #endif - - float &kref = planner.extruder_advance_K[tool_index], newK = kref; - const float oldK = newK; - - #if ENABLED(EXTRA_LIN_ADVANCE_K) - - float &lref = other_extruder_advance_K[tool_index]; - - const bool old_slot = TEST(lin_adv_slot, tool_index), // The tool's current slot (0 or 1) - new_slot = parser.boolval('S', old_slot); // The passed slot (default = current) - - // If a new slot is being selected swap the current and - // saved K values. Do here so K/L will apply correctly. - if (new_slot != old_slot) { // Not the same slot? - SET_BIT_TO(lin_adv_slot, tool_index, new_slot); // Update the slot for the tool - newK = lref; // Get new K value from backup - lref = oldK; // Save K to backup - } - - // Set the main K value. Apply if the main slot is active. - if (parser.seenval('K')) { - const float K = parser.value_float(); - if (!WITHIN(K, 0, 10)) echo_value_oor('K'); - else if (new_slot) lref = K; // S1 Knn - else newK = K; // S0 Knn - } - - // Set the extra K value. Apply if the extra slot is active. - if (parser.seenval('L')) { - const float L = parser.value_float(); - if (!WITHIN(L, 0, 10)) echo_value_oor('L'); - else if (!new_slot) lref = L; // S0 Lnn - else newK = L; // S1 Lnn - } - - #else - - if (parser.seenval('K')) { - const float K = parser.value_float(); - if (WITHIN(K, 0, 10)) - newK = K; - else - echo_value_oor('K'); - } - - #endif - - if (newK != oldK) { - planner.synchronize(); - kref = newK; - } - - if (!parser.seen_any()) { - - #if ENABLED(EXTRA_LIN_ADVANCE_K) - - #if EXTRUDERS < 2 - SERIAL_ECHOLNPGM("Advance S", new_slot, " K", kref, "(S", !new_slot, " K", lref, ")"); - #else - EXTRUDER_LOOP() { - const bool slot = TEST(lin_adv_slot, e); - SERIAL_ECHOLNPGM("Advance T", e, " S", slot, " K", planner.extruder_advance_K[e], - "(S", !slot, " K", other_extruder_advance_K[e], ")"); - SERIAL_EOL(); - } - #endif - - #else - - SERIAL_ECHO_START(); - #if EXTRUDERS < 2 - SERIAL_ECHOLNPGM("Advance K=", planner.extruder_advance_K[0]); - #else - SERIAL_ECHOPGM("Advance K"); - EXTRUDER_LOOP() { - SERIAL_CHAR(' ', '0' + e, ':'); - SERIAL_DECIMAL(planner.extruder_advance_K[e]); - } - SERIAL_EOL(); - #endif - - #endif - } - -} - -void GcodeSuite::M900_report(const bool forReplay/*=true*/) { - report_heading(forReplay, F(STR_LINEAR_ADVANCE)); - #if EXTRUDERS < 2 - report_echo_start(forReplay); - SERIAL_ECHOLNPGM(" M900 K", planner.extruder_advance_K[0]); - #else - EXTRUDER_LOOP() { - report_echo_start(forReplay); - SERIAL_ECHOLNPGM(" M900 T", e, " K", planner.extruder_advance_K[e]); - } - #endif -} - -#endif // LIN_ADVANCE diff --git a/src/gcode/feature/baricuda/M126-M129.cpp b/src/gcode/feature/baricuda/M126-M129.cpp deleted file mode 100644 index edeba0d..0000000 --- a/src/gcode/feature/baricuda/M126-M129.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(BARICUDA) - -#include "../../gcode.h" -#include "../../../feature/baricuda.h" - -#if HAS_HEATER_1 - - /** - * M126: Heater 1 valve open - */ - void GcodeSuite::M126() { baricuda_valve_pressure = parser.byteval('S', 255); } - - /** - * M127: Heater 1 valve close - */ - void GcodeSuite::M127() { baricuda_valve_pressure = 0; } - -#endif // HAS_HEATER_1 - -#if HAS_HEATER_2 - - /** - * M128: Heater 2 valve open - */ - void GcodeSuite::M128() { baricuda_e_to_p_pressure = parser.byteval('S', 255); } - - /** - * M129: Heater 2 valve close - */ - void GcodeSuite::M129() { baricuda_e_to_p_pressure = 0; } - -#endif // HAS_HEATER_2 - -#endif // BARICUDA diff --git a/src/gcode/feature/camera/M240.cpp b/src/gcode/feature/camera/M240.cpp deleted file mode 100644 index 19051ff..0000000 --- a/src/gcode/feature/camera/M240.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(PHOTO_GCODE) - -#include "../../gcode.h" -#include "../../../module/motion.h" // for active_extruder and current_position - -#if PIN_EXISTS(CHDK) - millis_t chdk_timeout; // = 0 -#endif - -#if defined(PHOTO_POSITION) && PHOTO_DELAY_MS > 0 - #include "../../../MarlinCore.h" // for idle() -#endif - -#ifdef PHOTO_RETRACT_MM - - #define _PHOTO_RETRACT_MM (PHOTO_RETRACT_MM + 0) - - #include "../../../module/planner.h" - #include "../../../module/temperature.h" - - #if ENABLED(ADVANCED_PAUSE_FEATURE) - #include "../../../feature/pause.h" - #endif - - #ifdef PHOTO_RETRACT_MM - inline void e_move_m240(const float length, const_feedRate_t fr_mm_s) { - if (length && thermalManager.hotEnoughToExtrude(active_extruder)) - unscaled_e_move(length, fr_mm_s); - } - #endif - -#endif - -#if PIN_EXISTS(PHOTOGRAPH) - - FORCE_INLINE void set_photo_pin(const uint8_t state) { - constexpr uint32_t pulse_length = ( - #ifdef PHOTO_PULSES_US - PHOTO_PULSE_DELAY_US - #else - 15 // 15.24 from _delay_ms(0.01524) - #endif - ); - WRITE(PHOTOGRAPH_PIN, state); - delayMicroseconds(pulse_length); - } - - FORCE_INLINE void tweak_photo_pin() { set_photo_pin(HIGH); set_photo_pin(LOW); } - - #ifdef PHOTO_PULSES_US - - inline void pulse_photo_pin(const uint32_t duration, const uint8_t state) { - if (state) { - for (const uint32_t stop = micros() + duration; micros() < stop;) - tweak_photo_pin(); - } - else - delayMicroseconds(duration); - } - - inline void spin_photo_pin() { - static constexpr uint32_t sequence[] = PHOTO_PULSES_US; - LOOP_L_N(i, COUNT(sequence)) - pulse_photo_pin(sequence[i], !(i & 1)); - } - - #else - - constexpr uint8_t NUM_PULSES = 16; - inline void spin_photo_pin() { for (uint8_t i = NUM_PULSES; i--;) tweak_photo_pin(); } - - #endif -#endif - -/** - * M240: Trigger a camera by... - * - * - CHDK : Emulate a Canon RC-1 with a configurable ON duration. - * https://captain-slow.dk/2014/03/09/3d-printing-timelapses/ - * - PHOTOGRAPH_PIN : Pulse a digital pin 16 times. - * See https://www.doc-diy.net/photo/rc-1_hacked/ - * - PHOTO_SWITCH_POSITION : Bump a physical switch with the X-carriage using a - * configured position, delay, and retract length. - * - * PHOTO_POSITION parameters: - * A - X offset to the return position - * B - Y offset to the return position - * F - Override the XY movement feedrate - * R - Retract/recover length (current units) - * S - Retract/recover feedrate (mm/m) - * X - Move to X before triggering the shutter - * Y - Move to Y before triggering the shutter - * Z - Raise Z by a distance before triggering the shutter - * - * PHOTO_SWITCH_POSITION parameters: - * D - Duration (ms) to hold down switch (Requires PHOTO_SWITCH_MS) - * P - Delay (ms) after triggering the shutter (Requires PHOTO_SWITCH_MS) - * I - Switch trigger position override X - * J - Switch trigger position override Y - */ -void GcodeSuite::M240() { - - #ifdef PHOTO_POSITION - - if (homing_needed_error()) return; - - const xyz_pos_t old_pos = { - current_position.x + parser.linearval('A'), - current_position.y + parser.linearval('B'), - current_position.z - }; - - #ifdef PHOTO_RETRACT_MM - const float rval = parser.linearval('R', _PHOTO_RETRACT_MM); - const feedRate_t sval = parser.feedrateval('S', TERN(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_RETRACT_FEEDRATE, TERN(FWRETRACT, RETRACT_FEEDRATE, 45))); - e_move_m240(-rval, sval); - #endif - - feedRate_t fr_mm_s = MMM_TO_MMS(parser.linearval('F')); - if (fr_mm_s) NOLESS(fr_mm_s, 10.0f); - - constexpr xyz_pos_t photo_position = PHOTO_POSITION; - xyz_pos_t raw = { - parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : photo_position.x, - parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_position.y, - (parser.seenval('Z') ? parser.value_linear_units() : photo_position.z) + current_position.z - }; - apply_motion_limits(raw); - do_blocking_move_to(raw, fr_mm_s); - - #ifdef PHOTO_SWITCH_POSITION - constexpr xy_pos_t photo_switch_position = PHOTO_SWITCH_POSITION; - const xy_pos_t sraw = { - parser.seenval('I') ? RAW_X_POSITION(parser.value_linear_units()) : photo_switch_position.x, - parser.seenval('J') ? RAW_Y_POSITION(parser.value_linear_units()) : photo_switch_position.y - }; - do_blocking_move_to_xy(sraw, get_homing_bump_feedrate(X_AXIS)); - #if PHOTO_SWITCH_MS > 0 - safe_delay(parser.intval('D', PHOTO_SWITCH_MS)); - #endif - do_blocking_move_to(raw); - #endif - - #endif - - #if PIN_EXISTS(CHDK) - - OUT_WRITE(CHDK_PIN, HIGH); - chdk_timeout = millis() + parser.intval('D', PHOTO_SWITCH_MS); - - #elif HAS_PHOTOGRAPH - - spin_photo_pin(); - delay(7.33); - spin_photo_pin(); - - #endif - - #ifdef PHOTO_POSITION - #if PHOTO_DELAY_MS > 0 - const millis_t timeout = millis() + parser.intval('P', PHOTO_DELAY_MS); - while (PENDING(millis(), timeout)) idle(); - #endif - do_blocking_move_to(old_pos, fr_mm_s); - #ifdef PHOTO_RETRACT_MM - e_move_m240(rval, sval); - #endif - #endif -} - -#endif // PHOTO_GCODE diff --git a/src/gcode/feature/cancel/M486.cpp b/src/gcode/feature/cancel/M486.cpp deleted file mode 100644 index c1e90d1..0000000 --- a/src/gcode/feature/cancel/M486.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(CANCEL_OBJECTS) - -#include "../../gcode.h" -#include "../../../feature/cancel_object.h" - -/** - * M486: A simple interface to cancel objects - * - * T[count] : Reset objects and/or set the count - * S : Start an object with the given index - * P : Cancel the object with the given index - * U : Un-cancel object with the given index - * C : Cancel the current object (the last index given by S) - * S-1 : Start a non-object like a brim or purge tower that should always print - */ -void GcodeSuite::M486() { - - if (parser.seen('T')) { - cancelable.reset(); - cancelable.object_count = parser.intval('T', 1); - } - - if (parser.seenval('S')) - cancelable.set_active_object(parser.value_int()); - - if (parser.seen('C')) cancelable.cancel_active_object(); - - if (parser.seenval('P')) cancelable.cancel_object(parser.value_int()); - - if (parser.seenval('U')) cancelable.uncancel_object(parser.value_int()); -} - -#endif // CANCEL_OBJECTS diff --git a/src/gcode/feature/caselight/M355.cpp b/src/gcode/feature/caselight/M355.cpp deleted file mode 100644 index b3b863f..0000000 --- a/src/gcode/feature/caselight/M355.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(CASE_LIGHT_ENABLE) - -#include "../../../feature/caselight.h" -#include "../../gcode.h" - -/** - * M355: Turn case light on/off and set brightness - * - * P Set case light brightness (PWM pin required - ignored otherwise) - * - * S Set case light on/off - * - * When S turns on the light on a PWM pin then the current brightness level is used/restored - * - * M355 P200 S0 turns off the light & sets the brightness level - * M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin) - */ -void GcodeSuite::M355() { - bool didset = false; - #if CASELIGHT_USES_BRIGHTNESS - if (parser.seenval('P')) { - didset = true; - caselight.brightness = parser.value_byte(); - } - #endif - const bool sflag = parser.seenval('S'); - if (sflag) { - didset = true; - caselight.on = parser.value_bool(); - } - if (didset) caselight.update(sflag); - - // Always report case light status - SERIAL_ECHO_START(); - SERIAL_ECHOPGM("Case light: "); - if (!caselight.on) - SERIAL_ECHOLNPGM(STR_OFF); - else { - #if CASELIGHT_USES_BRIGHTNESS - if (TERN(CASE_LIGHT_USE_NEOPIXEL, true, TERN0(NEED_CASE_LIGHT_PIN, PWM_PIN(CASE_LIGHT_PIN)))) { - SERIAL_ECHOLN(int(caselight.brightness)); - return; - } - #endif - SERIAL_ECHOLNPGM(STR_ON); - } -} - -#endif // CASE_LIGHT_ENABLE diff --git a/src/gcode/feature/clean/G12.cpp b/src/gcode/feature/clean/G12.cpp deleted file mode 100644 index 0113170..0000000 --- a/src/gcode/feature/clean/G12.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(NOZZLE_CLEAN_FEATURE) - -#include "../../../libs/nozzle.h" - -#include "../../gcode.h" -#include "../../parser.h" -#include "../../../module/motion.h" - -#if HAS_LEVELING - #include "../../../module/planner.h" - #include "../../../feature/bedlevel/bedlevel.h" -#endif - -/** - * G12: Clean the nozzle - * - * E : 0=Never or 1=Always apply the "software endstop" limits - * P0 S : Stroke cleaning with S strokes - * P1 Sn T : Zigzag cleaning with S repeats and T zigzags - * P2 Sn R : Circle cleaning with S repeats and R radius - * X, Y, Z : Specify axes to move during cleaning. Default: ALL. - */ -void GcodeSuite::G12() { - - // Don't allow nozzle cleaning without homing first - constexpr main_axes_bits_t clean_axis_mask = main_axes_mask & ~TERN0(NOZZLE_CLEAN_NO_Z, Z_AXIS) & ~TERN0(NOZZLE_CLEAN_NO_Y, Y_AXIS); - if (homing_needed_error(clean_axis_mask)) return; - - #ifdef WIPE_SEQUENCE_COMMANDS - if (!parser.seen_any()) { - process_subcommands_now(F(WIPE_SEQUENCE_COMMANDS)); - return; - } - #endif - - const uint8_t pattern = parser.ushortval('P', 0), - strokes = parser.ushortval('S', NOZZLE_CLEAN_STROKES), - objects = parser.ushortval('T', NOZZLE_CLEAN_TRIANGLES); - const float radius = parser.linearval('R', NOZZLE_CLEAN_CIRCLE_RADIUS); - - const bool seenxyz = parser.seen("XYZ"); - const uint8_t cleans = (!seenxyz || parser.boolval('X') ? _BV(X_AXIS) : 0) - | (!seenxyz || parser.boolval('Y') ? _BV(Y_AXIS) : 0) - | TERN(NOZZLE_CLEAN_NO_Z, 0, (!seenxyz || parser.boolval('Z') ? _BV(Z_AXIS) : 0)) - ; - - #if HAS_LEVELING - // Disable bed leveling if cleaning Z - TEMPORARY_BED_LEVELING_STATE(!TEST(cleans, Z_AXIS) && planner.leveling_active); - #endif - - SET_SOFT_ENDSTOP_LOOSE(!parser.boolval('E')); - - nozzle.clean(pattern, strokes, radius, objects, cleans); - - SET_SOFT_ENDSTOP_LOOSE(false); -} - -#endif // NOZZLE_CLEAN_FEATURE diff --git a/src/gcode/feature/controllerfan/M710.cpp b/src/gcode/feature/controllerfan/M710.cpp deleted file mode 100644 index b98d888..0000000 --- a/src/gcode/feature/controllerfan/M710.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfigPre.h" - -#if ENABLED(CONTROLLER_FAN_EDITABLE) - -#include "../../gcode.h" -#include "../../../feature/controllerfan.h" - -/** - * M710: Set controller fan settings - * - * R : Reset to defaults - * S[0-255] : Fan speed when motors are active - * I[0-255] : Fan speed when motors are idle - * A[0|1] : Turn auto mode on or off - * D : Set auto mode idle duration - * - * Examples: - * M710 ; Report current Settings - * M710 R ; Reset SIAD to defaults - * M710 I64 ; Set controller fan Idle Speed to 25% - * M710 S255 ; Set controller fan Active Speed to 100% - * M710 S0 ; Set controller fan Active Speed to OFF - * M710 I255 A0 ; Set controller fan Idle Speed to 100% with Auto Mode OFF - * M710 I127 A1 S255 D160 ; Set controller fan idle speed 50%, AutoMode On, Fan speed 100%, duration to 160 Secs - */ -void GcodeSuite::M710() { - - const bool seenR = parser.seen('R'); - if (seenR) controllerFan.reset(); - - const bool seenS = parser.seenval('S'); - if (seenS) controllerFan.settings.active_speed = parser.value_byte(); - - const bool seenI = parser.seenval('I'); - if (seenI) controllerFan.settings.idle_speed = parser.value_byte(); - - const bool seenA = parser.seenval('A'); - if (seenA) controllerFan.settings.auto_mode = parser.value_bool(); - - const bool seenD = parser.seenval('D'); - if (seenD) controllerFan.settings.duration = parser.value_ushort(); - - if (!(seenR || seenS || seenI || seenA || seenD)) - M710_report(); -} - -void GcodeSuite::M710_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_CONTROLLER_FAN)); - SERIAL_ECHOLNPGM(" M710" - " S", int(controllerFan.settings.active_speed), - " I", int(controllerFan.settings.idle_speed), - " A", int(controllerFan.settings.auto_mode), - " D", controllerFan.settings.duration, - " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%" - " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)" - ); -} - -#endif // CONTROLLER_FAN_EDITABLE diff --git a/src/gcode/feature/digipot/M907-M910.cpp b/src/gcode/feature/digipot/M907-M910.cpp deleted file mode 100644 index 372cb4b..0000000 --- a/src/gcode/feature/digipot/M907-M910.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC - -#include "../../gcode.h" - -#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM - #include "../../../module/stepper.h" -#endif - -#if HAS_MOTOR_CURRENT_I2C - #include "../../../feature/digipot/digipot.h" -#endif - -#if HAS_MOTOR_CURRENT_DAC - #include "../../../feature/dac/stepper_dac.h" -#endif - -/** - * M907: Set digital trimpot motor current using axis codes X [Y] [Z] [I] [J] [K] [E] - * B - Special case for E1 (Requires DIGIPOTSS_PIN or DIGIPOT_MCP4018 or DIGIPOT_MCP4451) - * C - Special case for E2 (Requires DIGIPOTSS_PIN or DIGIPOT_MCP4018 or DIGIPOT_MCP4451) - * S - Set current in mA for all axes (Requires DIGIPOTSS_PIN or DIGIPOT_MCP4018 or DIGIPOT_MCP4451), or - * Set percentage of max current for all axes (Requires HAS_DIGIPOT_DAC) - */ -void GcodeSuite::M907() { - #if HAS_MOTOR_CURRENT_SPI - - if (!parser.seen("BS" STR_AXES_LOGICAL)) - return M907_report(); - - if (parser.seenval('S')) LOOP_L_N(i, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(i, parser.value_int()); - LOOP_LOGICAL_AXES(i) if (parser.seenval(IAXIS_CHAR(i))) stepper.set_digipot_current(i, parser.value_int()); // X Y Z (I J K) E (map to drivers according to DIGIPOT_CHANNELS. Default with NUM_AXES 3: map X Y Z E to X Y Z E0) - // Additional extruders use B,C. - // TODO: Change these parameters because 'E' is used and D should be reserved for debugging. B? - #if E_STEPPERS >= 2 - if (parser.seenval('B')) stepper.set_digipot_current(E_AXIS + 1, parser.value_int()); - #if E_STEPPERS >= 3 - if (parser.seenval('C')) stepper.set_digipot_current(E_AXIS + 2, parser.value_int()); - #endif - #endif - - #elif HAS_MOTOR_CURRENT_PWM - - #if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_I, MOTOR_CURRENT_PWM_J, MOTOR_CURRENT_PWM_K) - #define HAS_X_Y_XY_I_J_K 1 - #endif - - #if HAS_X_Y_XY_I_J_K || ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_Z) - - if (!parser.seen("S" - #if HAS_X_Y_XY_I_J_K - "XY" SECONDARY_AXIS_GANG("I", "J", "K") - #endif - #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - "Z" - #endif - #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - "E" - #endif - )) return M907_report(); - - if (parser.seenval('S')) LOOP_L_N(a, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(a, parser.value_int()); - - #if HAS_X_Y_XY_I_J_K - if (NUM_AXIS_GANG( - parser.seenval('X'), || parser.seenval('Y'), || false, - || parser.seenval('I'), || parser.seenval('J'), || parser.seenval('K') - )) stepper.set_digipot_current(0, parser.value_int()); - #endif - #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z) - if (parser.seenval('Z')) stepper.set_digipot_current(1, parser.value_int()); - #endif - #if PIN_EXISTS(MOTOR_CURRENT_PWM_E) - if (parser.seenval('E')) stepper.set_digipot_current(2, parser.value_int()); - #endif - - #endif - - #endif // HAS_MOTOR_CURRENT_PWM - - #if HAS_MOTOR_CURRENT_I2C - // this one uses actual amps in floating point - if (parser.seenval('S')) LOOP_L_N(q, DIGIPOT_I2C_NUM_CHANNELS) digipot_i2c.set_current(q, parser.value_float()); - LOOP_LOGICAL_AXES(i) if (parser.seenval(IAXIS_CHAR(i))) digipot_i2c.set_current(i, parser.value_float()); // X Y Z (I J K) E (map to drivers according to pots adresses. Default with NUM_AXES 3 X Y Z E: map to X Y Z E0) - // Additional extruders use B,C,D. - // TODO: Change these parameters because 'E' is used and because 'D' should be reserved for debugging. B? - #if E_STEPPERS >= 2 - for (uint8_t i = E_AXIS + 1; i < _MAX(DIGIPOT_I2C_NUM_CHANNELS, (NUM_AXES + 3)); i++) - if (parser.seenval('B' + i - (E_AXIS + 1))) digipot_i2c.set_current(i, parser.value_float()); - #endif - #endif - - #if HAS_MOTOR_CURRENT_DAC - if (parser.seenval('S')) { - const float dac_percent = parser.value_float(); - LOOP_LOGICAL_AXES(i) stepper_dac.set_current_percent(i, dac_percent); - } - LOOP_LOGICAL_AXES(i) if (parser.seenval(IAXIS_CHAR(i))) stepper_dac.set_current_percent(i, parser.value_float()); // X Y Z (I J K) E (map to drivers according to DAC_STEPPER_ORDER. Default with NUM_AXES 3: X Y Z E map to X Y Z E0) - #endif -} - -#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM - - void GcodeSuite::M907_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_STEPPER_MOTOR_CURRENTS)); - #if HAS_MOTOR_CURRENT_PWM - SERIAL_ECHOLNPGM_P( // PWM-based has 3 values: - PSTR(" M907 X"), stepper.motor_current_setting[0] // X, Y, (I, J, K) - , SP_Z_STR, stepper.motor_current_setting[1] // Z - , SP_E_STR, stepper.motor_current_setting[2] // E - ); - #elif HAS_MOTOR_CURRENT_SPI - SERIAL_ECHOPGM(" M907"); // SPI-based has 5 values: - LOOP_LOGICAL_AXES(q) { // X Y Z (I J K) E (map to X Y Z (I J K) E0 by default) - SERIAL_CHAR(' ', IAXIS_CHAR(q)); - SERIAL_ECHO(stepper.motor_current_setting[q]); - } - #if E_STEPPERS >= 2 - SERIAL_ECHOPGM_P(PSTR(" B"), stepper.motor_current_setting[E_AXIS + 1] // B (maps to E1 with NUM_AXES 3 according to DIGIPOT_CHANNELS) - #if E_STEPPERS >= 3 - , PSTR(" C"), stepper.motor_current_setting[E_AXIS + 2] // C (mapping to E2 must be defined by DIGIPOT_CHANNELS) - #endif - ); - #endif - SERIAL_EOL(); - #endif - } - -#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM - -#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC - - /** - * M908: Control digital trimpot directly (M908 P S) - */ - void GcodeSuite::M908() { - TERN_(HAS_MOTOR_CURRENT_SPI, stepper.set_digipot_value_spi(parser.intval('P'), parser.intval('S'))); - TERN_(HAS_MOTOR_CURRENT_DAC, stepper_dac.set_current_value(parser.byteval('P', -1), parser.ushortval('S', 0))); - } - - #if HAS_MOTOR_CURRENT_DAC - - void GcodeSuite::M909() { stepper_dac.print_values(); } - void GcodeSuite::M910() { stepper_dac.commit_eeprom(); } - - #endif // HAS_MOTOR_CURRENT_DAC - -#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC - -#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC diff --git a/src/gcode/feature/filwidth/M404-M407.cpp b/src/gcode/feature/filwidth/M404-M407.cpp deleted file mode 100644 index ff174ec..0000000 --- a/src/gcode/feature/filwidth/M404-M407.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(FILAMENT_WIDTH_SENSOR) - -#include "../../../feature/filwidth.h" -#include "../../../module/planner.h" -#include "../../../MarlinCore.h" -#include "../../gcode.h" - -/** - * M404: Display or set (in current units) the nominal filament width (3mm, 1.75mm ) W<3.0> - */ -void GcodeSuite::M404() { - if (parser.seenval('W')) { - filwidth.nominal_mm = parser.value_linear_units(); - planner.volumetric_area_nominal = CIRCLE_AREA(filwidth.nominal_mm * 0.5); - } - else - SERIAL_ECHOLNPGM("Filament dia (nominal mm):", filwidth.nominal_mm); -} - -/** - * M405: Turn on filament sensor for control - */ -void GcodeSuite::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.seenval('D')) - filwidth.set_delay_cm(parser.value_byte()); - - filwidth.enable(true); -} - -/** - * M406: Turn off filament sensor for control - */ -void GcodeSuite::M406() { - filwidth.enable(false); - planner.calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value -} - -/** - * M407: Get measured filament diameter on serial output - */ -void GcodeSuite::M407() { - SERIAL_ECHOLNPGM("Filament dia (measured mm):", filwidth.measured_mm); -} - -#endif // FILAMENT_WIDTH_SENSOR diff --git a/src/gcode/feature/fwretract/G10_G11.cpp b/src/gcode/feature/fwretract/G10_G11.cpp deleted file mode 100644 index 1889f83..0000000 --- a/src/gcode/feature/fwretract/G10_G11.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(FWRETRACT) - -#include "../../../feature/fwretract.h" -#include "../../gcode.h" -#include "../../../module/motion.h" - -/** - * G10 - Retract filament according to settings of M207 - * TODO: Handle 'G10 P' for tool settings and 'G10 L' for workspace settings - */ -void GcodeSuite::G10() { fwretract.retract(true E_OPTARG(parser.boolval('S'))); } - -/** - * G11 - Recover filament according to settings of M208 - */ -void GcodeSuite::G11() { fwretract.retract(false); } - -#endif // FWRETRACT diff --git a/src/gcode/feature/fwretract/M207-M209.cpp b/src/gcode/feature/fwretract/M207-M209.cpp deleted file mode 100644 index 173c289..0000000 --- a/src/gcode/feature/fwretract/M207-M209.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(FWRETRACT) - -#include "../../../feature/fwretract.h" -#include "../../gcode.h" - -/** - * 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_zraise - */ -void GcodeSuite::M207() { fwretract.M207(); } - -void GcodeSuite::M207_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_RETRACT_S_F_Z)); - fwretract.M207_report(); -} - -/** - * M208: Set firmware un-retraction values - * - * S[+units] retract_recover_extra (in addition to M207 S*) - * W[+units] swap_retract_recover_extra (multi-extruder) - * F[units/min] retract_recover_feedrate_mm_s - * R[units/min] swap_retract_recover_feedrate_mm_s - */ -void GcodeSuite::M208() { fwretract.M208(); } - -void GcodeSuite::M208_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_RECOVER_S_F)); - fwretract.M208_report(); -} - -#if ENABLED(FWRETRACT_AUTORETRACT) - - /** - * M209: Enable automatic retract (M209 S1) - * - * For slicers that don't support G10/11, reversed - * extruder-only moves can be classified as retraction. - */ - void GcodeSuite::M209() { fwretract.M209(); } - - void GcodeSuite::M209_report(const bool forReplay/*=true*/) { - report_heading_etc(forReplay, F(STR_AUTO_RETRACT_S)); - fwretract.M209_report(); - } - -#endif - -#endif // FWRETRACT diff --git a/src/gcode/feature/i2c/M260_M261.cpp b/src/gcode/feature/i2c/M260_M261.cpp deleted file mode 100644 index cf9bb7e..0000000 --- a/src/gcode/feature/i2c/M260_M261.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../../../inc/MarlinConfig.h" - -#if ENABLED(EXPERIMENTAL_I2CBUS) - -#include "../../gcode.h" - -#include "../../../feature/twibus.h" - -/** - * M260: Send data to a I2C slave device - * - * This is a PoC, the formatting and arguments for the GCODE will - * change to be more compatible, the current proposal is: - * - * M260 A ; Sets the I2C slave address the data will be sent to - * - * M260 B - * M260 B - * M260 B - * - * M260 S1 ; Send the buffered data and reset the buffer - * M260 R1 ; Reset the buffer without sending data - */ -void GcodeSuite::M260() { - // Set the target address - if (parser.seenval('A')) i2c.address(parser.value_byte()); - - // Add a new byte to the buffer - if (parser.seenval('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 S