mirror of https://github.com/Desuuuu/klipper.git
Integrate support for DGUS T5UID1 touchscreens
This commit is contained in:
parent
118ef908a5
commit
cb09ec8b9e
12
README.md
12
README.md
|
@ -14,3 +14,15 @@ To begin using Klipper start by
|
|||
|
||||
Klipper is Free Software. See the [license](COPYING) or read the
|
||||
[documentation](https://www.klipper3d.org/Overview.html).
|
||||
|
||||
## Modifications
|
||||
|
||||
The scope of modifications is limited to adding support for DGUS
|
||||
touchscreens. This feature is only available for AVR/LPC176X
|
||||
micro-controllers and it needs to be configured before compilation.
|
||||
|
||||
The touchscreen firmware compatible with this fork is available in
|
||||
[this repository](https://github.com/Desuuuu/DGUS-reloaded-Klipper).
|
||||
|
||||
Available configuration options are documented in the
|
||||
[sample-t5uid1.cfg](/config/sample-t5uid1.cfg) file.
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# This file provides example configuration for DGUS T5UID1 touchscreens.
|
||||
|
||||
[t5uid1]
|
||||
firmware: dgus_reloaded
|
||||
# This controls how Klipper interacts with the touchscreen. The only possible
|
||||
# value is "dgus_reloaded" at the moment. This parameter must be provided.
|
||||
#update_interval: 2
|
||||
# How often to send data updates to the touchscreen.
|
||||
#volume: 75
|
||||
# The volume for the touchscreen speaker (as a value from 0 to 100).
|
||||
#brightness: 100
|
||||
# The brightness for the touchscreen (as a value from 0 to 100).
|
||||
#machine_name: Generic 3D Printer
|
||||
# The machine name shown on the information page.
|
||||
#boot_sound:
|
||||
# The index of the sound to play when booting. Defaults to being provided by
|
||||
# the selected firmware.
|
||||
#notification_sound:
|
||||
# The index of the sound to play when certain events happened. Defaults to
|
||||
# being provided by the selected firmware.
|
||||
#z_min:
|
||||
# This can be used to provide a lower limit to Z moves. Movements will still
|
||||
# be limited by your [stepper_z] configuration values.
|
||||
#z_max:
|
||||
# This can be used to provide an upper limit to Z moves. Movements will still
|
||||
# be limited by your [stepper_z] configuration values.
|
|
@ -0,0 +1,9 @@
|
|||
# Package definition for the extras/t5uid1 directory
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
from . import t5uid1
|
||||
|
||||
def load_config(config):
|
||||
return t5uid1.load_config(config)
|
|
@ -0,0 +1,110 @@
|
|||
# Package definition for the extras/t5uid1/dugs_reloaded directory
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
controls = {
|
||||
# print_status
|
||||
'pause': 1, # popup_window
|
||||
'resume': 2, # popup_window
|
||||
|
||||
# leveling_automatic
|
||||
'disable': 5, # return_key_code
|
||||
|
||||
# settings_menu2
|
||||
'extra2': 4, # return_key_code
|
||||
|
||||
# wait
|
||||
'abort': 1, # popup_window
|
||||
'continue': 2 # return_key_code
|
||||
}
|
||||
|
||||
constants = {
|
||||
'temp_pla': {
|
||||
'hotend': 200,
|
||||
'bed': 60
|
||||
},
|
||||
'temp_abs': {
|
||||
'hotend': 240,
|
||||
'bed': 80
|
||||
},
|
||||
'temp_petg': {
|
||||
'hotend': 240,
|
||||
'bed': 60
|
||||
},
|
||||
|
||||
'popup_confirmed': 1,
|
||||
|
||||
'adjust_increment': 0,
|
||||
'adjust_decrement': 1,
|
||||
|
||||
'preset_pla': 1,
|
||||
'preset_abs': 2,
|
||||
'preset_petg': 3,
|
||||
|
||||
'extruder_current': -1,
|
||||
'extruder_e0': 0,
|
||||
'extruder_e1': 1,
|
||||
|
||||
'heater_all': -2,
|
||||
'heater_bed': -1,
|
||||
'heater_h0': 0,
|
||||
'heater_h1': 1,
|
||||
|
||||
'stepper_enable': 1,
|
||||
'stepper_disable': 2,
|
||||
|
||||
'step_size_10': 0,
|
||||
'step_size_1': 1,
|
||||
'step_size_0.1': 2,
|
||||
'step_size_0.01': 3,
|
||||
|
||||
'filament_retract': 0,
|
||||
'filament_extrude': 1,
|
||||
|
||||
'axis_xyz': 0,
|
||||
'axis_xy': 1,
|
||||
'axis_z': 2,
|
||||
|
||||
'move_x+': 0,
|
||||
'move_x-': 1,
|
||||
'move_y+': 2,
|
||||
'move_y-': 3,
|
||||
'move_z+': 4,
|
||||
'move_z-': 5,
|
||||
|
||||
'extra_button1': 0,
|
||||
'extra_button2': 1,
|
||||
|
||||
'disabled': 0,
|
||||
'enabled': 1,
|
||||
|
||||
'status_icon_pause': 1 << 0,
|
||||
'status_icon_resume': 1 << 1,
|
||||
|
||||
'step_icon_10': 1 << 0,
|
||||
'step_icon_1': 1 << 1,
|
||||
'step_icon_0.1': 1 << 2,
|
||||
'step_icon_0.01': 1 << 3,
|
||||
|
||||
'extruder_icon_e0': 1 << 0,
|
||||
'extruder_icon_e1': 1 << 1,
|
||||
|
||||
'heater_icon_bed': 1 << 0,
|
||||
'heater_icon_h0': 1 << 1,
|
||||
'heater_icon_h1': 1 << 2,
|
||||
|
||||
'wait_icon_abort': 1 << 0,
|
||||
'wait_icon_continue': 1 << 1
|
||||
}
|
||||
|
||||
configuration = {
|
||||
'config_files': ['routines.cfg',
|
||||
'pages.cfg',
|
||||
'vars_in.cfg',
|
||||
'vars_out.cfg'],
|
||||
'boot_sound': 1,
|
||||
'notification_sound': 3,
|
||||
'controls': controls,
|
||||
'constants': constants
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
[t5uid1_page boot]
|
||||
id: 0
|
||||
boot: true
|
||||
timeout: true
|
||||
|
||||
[t5uid1_page home]
|
||||
id: 1
|
||||
var_auto: temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target
|
||||
|
||||
[t5uid1_page print_status]
|
||||
id: 2
|
||||
var_auto:
|
||||
temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target,
|
||||
status_position_z, status_ellapsed, status_percent, status_icons
|
||||
|
||||
[t5uid1_page print_adjust]
|
||||
id: 3
|
||||
var_auto:
|
||||
temp_h0_target, temp_bed_target, fan_speed,
|
||||
adjust_feedrate, adjust_flowrate, level_offset
|
||||
|
||||
[t5uid1_page print_finished]
|
||||
id: 4
|
||||
var: status_ellapsed, status_percent
|
||||
var_auto:
|
||||
temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target,
|
||||
status_position_z
|
||||
|
||||
[t5uid1_page temp_menu]
|
||||
id: 5
|
||||
var_auto: temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target
|
||||
|
||||
[t5uid1_page temp_manual]
|
||||
id: 6
|
||||
var: temp_h0_max, temp_bed_max
|
||||
var_auto: temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target
|
||||
|
||||
[t5uid1_page fan]
|
||||
id: 7
|
||||
var_auto: fan_speed
|
||||
|
||||
[t5uid1_page move]
|
||||
id: 8
|
||||
var: move_step_icons
|
||||
var_auto: move_current_x, move_current_y, move_current_z
|
||||
|
||||
[t5uid1_page settings_menu]
|
||||
id: 9
|
||||
var_auto: stepper_status
|
||||
|
||||
[t5uid1_page leveling_menu]
|
||||
id: 10
|
||||
|
||||
[t5uid1_page leveling_offset]
|
||||
id: 11
|
||||
var: level_offset_step_icons
|
||||
var_auto: level_offset
|
||||
|
||||
[t5uid1_page leveling_manual]
|
||||
id: 12
|
||||
var_auto: temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target
|
||||
|
||||
[t5uid1_page leveling_automatic]
|
||||
id: 13
|
||||
var: level_auto_disable_icon, level_auto_grid
|
||||
var_auto:
|
||||
temp_h0_current, temp_h0_target, temp_bed_current, temp_bed_target
|
||||
|
||||
[t5uid1_page leveling_probing]
|
||||
id: 14
|
||||
var_auto: level_probing_icons
|
||||
|
||||
[t5uid1_page filament]
|
||||
id: 15
|
||||
var: filament_icons, filament_length
|
||||
var_auto: temp_h0_current, temp_h0_target
|
||||
|
||||
[t5uid1_page volume]
|
||||
id: 16
|
||||
var: volume
|
||||
|
||||
[t5uid1_page brightness]
|
||||
id: 17
|
||||
var: brightness
|
||||
|
||||
[t5uid1_page settings_menu2]
|
||||
id: 18
|
||||
var: bltouch
|
||||
|
||||
[t5uid1_page pid]
|
||||
id: 19
|
||||
var: pid_heater_icons, pid_temp
|
||||
var_auto: pid_kp, pid_ki, pid_kd
|
||||
|
||||
[t5uid1_page info]
|
||||
id: 20
|
||||
var: info_machine, info_build_volume, info_version
|
||||
|
||||
[t5uid1_page debug1]
|
||||
id: 240
|
||||
|
||||
[t5uid1_page debug2]
|
||||
id: 241
|
||||
|
||||
[t5uid1_page wait]
|
||||
id: 249
|
||||
var: line1, line2, line3, line4, wait_icons
|
||||
|
||||
[t5uid1_page kill]
|
||||
id: 250
|
||||
shutdown: true
|
||||
var: line1, line2, line3, line4
|
|
@ -0,0 +1,207 @@
|
|||
[t5uid1_routine message_timeout]
|
||||
trigger: manual
|
||||
delay: 30
|
||||
script: {% do set_message("") %}
|
||||
|
||||
[t5uid1_routine print_start]
|
||||
trigger: manual
|
||||
delay: 0
|
||||
script: {% do switch_page("print_status") %}
|
||||
|
||||
[t5uid1_routine print_end]
|
||||
trigger: manual
|
||||
delay: 0
|
||||
script:
|
||||
{% set sound = printer.t5uid1.notification_sound %}
|
||||
{% if sound >= 0 %}
|
||||
{% do play_sound(sound) %}
|
||||
{% endif %}
|
||||
{% do switch_page("print_finished") %}
|
||||
|
||||
[t5uid1_routine trigger_full_update]
|
||||
trigger: manual
|
||||
delay: 0
|
||||
script: {% do full_update() %}
|
||||
|
||||
[t5uid1_routine show_wait_screen]
|
||||
trigger: manual
|
||||
delay: 0
|
||||
script: {% do switch_page("wait") %}
|
||||
|
||||
[t5uid1_routine show_probing_screen]
|
||||
trigger: manual
|
||||
delay: 0
|
||||
script: {% do switch_page("leveling_probing") %}
|
||||
|
||||
[t5uid1_routine reset_bltouch]
|
||||
trigger: manual
|
||||
script:
|
||||
{% if printer.t5uid1.has_bltouch %}
|
||||
BLTOUCH_DEBUG COMMAND=reset
|
||||
BLTOUCH_DEBUG COMMAND=pin_up
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_routine __wait_return]
|
||||
trigger: enter
|
||||
page: wait
|
||||
interval: 1
|
||||
script:
|
||||
{% if not is_busy() %}
|
||||
{% set sound = get_variable("wait_return_sound", -1) %}
|
||||
{% if sound >= 0 and sound <= 255 %}
|
||||
{% do set_variable("wait_return_sound", -1) %}
|
||||
{% do play_sound(sound) %}
|
||||
{% endif %}
|
||||
{% set page = get_variable("wait_return", "")|default("home", true) %}
|
||||
{% do set_variable("wait_return", "") %}
|
||||
{% do switch_page(page) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_routine __probing_return]
|
||||
trigger: enter
|
||||
page: leveling_probing
|
||||
interval: 1
|
||||
script:
|
||||
{% if not is_busy() %}
|
||||
{% set sound = printer.t5uid1.notification_sound %}
|
||||
{% if sound >= 0 %}
|
||||
{% do play_sound(sound) %}
|
||||
{% endif %}
|
||||
{% do switch_page("leveling_automatic") %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_routine __boot]
|
||||
trigger: enter
|
||||
page: boot
|
||||
delay: 3
|
||||
script: {% do switch_page("home") %}
|
||||
|
||||
[t5uid1_routine __print_status_pause]
|
||||
trigger: enter
|
||||
page: print_status
|
||||
interval: 5
|
||||
script: {% do check_paused() %}
|
||||
|
||||
[t5uid1_routine __print_adjust_pause]
|
||||
trigger: enter
|
||||
page: print_adjust
|
||||
interval: 5
|
||||
script: {% do check_paused() %}
|
||||
|
||||
[t5uid1_routine __move]
|
||||
trigger: enter_pre
|
||||
page: move
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{ abort_page_switch() }
|
||||
{% else %}
|
||||
{% do set_variable("move_steps", printer.t5uid1.constants.step_size_10) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_routine __leveling_menu]
|
||||
trigger: enter_pre
|
||||
page: leveling_menu
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{ abort_page_switch() }
|
||||
{% elif printer.toolhead.homed_axes == "xyz" %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set x = (t5uid1.limits.x_min + t5uid1.limits.x_max) / 2 %}
|
||||
{% set y = (t5uid1.limits.y_min + t5uid1.limits.y_max) / 2 %}
|
||||
{% if printer.gcode.move_zpos < 10 %}
|
||||
G1 Z10 F600
|
||||
{% endif %}
|
||||
G1 X{x} Y{y} F4800
|
||||
{% else %}
|
||||
{ abort_page_switch() }
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "Homing...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", "leveling_menu") %}
|
||||
G28
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_routine __leveling_offset]
|
||||
trigger: enter_pre
|
||||
page: leveling_offset
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{ abort_page_switch() }
|
||||
{% elif printer.toolhead.homed_axes == "xyz" %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set x = (t5uid1.limits.x_min + t5uid1.limits.x_max) / 2 %}
|
||||
{% set y = (t5uid1.limits.y_min + t5uid1.limits.y_max) / 2 %}
|
||||
{% if printer.gcode.move_zpos < 5 %}
|
||||
G1 Z5 F600
|
||||
{% endif %}
|
||||
G1 X{x} Y{y} F4800
|
||||
G1 Z0 F300
|
||||
{% else %}
|
||||
{ abort_page_switch() }
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "Homing...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", "leveling_offset") %}
|
||||
G28
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_routine __leveling_manual]
|
||||
trigger: enter_pre
|
||||
page: leveling_manual
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{ abort_page_switch() }
|
||||
{% elif printer.toolhead.homed_axes != "xyz" %}
|
||||
{ abort_page_switch() }
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "Homing...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", "leveling_manual") %}
|
||||
G28
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% else %}
|
||||
BED_MESH_PROFILE SAVE=t5uid1_mesh_backup
|
||||
BED_MESH_CLEAR
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_routine __leveling_manual_leave]
|
||||
trigger: leave
|
||||
page: leveling_manual
|
||||
script:
|
||||
BED_MESH_PROFILE LOAD=t5uid1_mesh_backup
|
||||
BED_MESH_PROFILE REMOVE=t5uid1_mesh_backup
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_routine __filament]
|
||||
trigger: enter_pre
|
||||
page: filament
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% do set_variable("filament_extruder", t5uid1.constants.extruder_current) %}
|
||||
{% do set_variable("filament_length", 10) %}
|
||||
|
||||
[t5uid1_routine __pid]
|
||||
trigger: enter_pre
|
||||
page: pid
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% do set_variable("pid_heater", t5uid1.constants.heater_h0) %}
|
||||
{% do set_variable("pid_temp", t5uid1.constants.temp_pla.hotend) %}
|
||||
|
||||
[t5uid1_routine __info]
|
||||
trigger: enter_pre
|
||||
page: info
|
||||
script: {% do set_variable("debug_count", 0) %}
|
|
@ -0,0 +1,706 @@
|
|||
[t5uid1_var __switch_page]
|
||||
type: input
|
||||
address: 0x2000
|
||||
data_type: uint16
|
||||
script: {% do switch_page(page_name(data)) %}
|
||||
|
||||
[t5uid1_var __switch_page_idle]
|
||||
type: input
|
||||
address: 0x2002
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if not is_busy() %}
|
||||
{% do switch_page(page_name(data)) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var __switch_page_printing]
|
||||
type: input
|
||||
address: 0x2003
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if printer.t5uid1.is_printing %}
|
||||
{% do switch_page(page_name(data)) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var __status_abort]
|
||||
type: input
|
||||
address: 0x2007
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.popup_confirmed %}
|
||||
{% if t5uid1.is_printing %}
|
||||
RESPOND TYPE=command MSG=action:cancel
|
||||
{% endif %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __status_pause]
|
||||
type: input
|
||||
address: 0x2008
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.popup_confirmed %}
|
||||
{% if t5uid1.is_printing and not printer.pause_resume.is_paused %}
|
||||
RESPOND TYPE=command MSG=action:pause
|
||||
{% endif %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __status_resume]
|
||||
type: input
|
||||
address: 0x2009
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.popup_confirmed %}
|
||||
{% if t5uid1.is_printing and printer.pause_resume.is_paused %}
|
||||
RESPOND TYPE=command MSG=action:resume
|
||||
{% endif %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __adjust_set_feedrate]
|
||||
type: input
|
||||
address: 0x200a
|
||||
data_type: int16
|
||||
script:
|
||||
M220 S{data}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __adjust_set_flowrate]
|
||||
type: input
|
||||
address: 0x200b
|
||||
data_type: int16
|
||||
script:
|
||||
M221 S{data}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __adjust_set_offset]
|
||||
type: input
|
||||
address: 0x200e
|
||||
data_type: int16
|
||||
script:
|
||||
{% if "z" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set offset = data|float / 10 ** 2 %}
|
||||
SET_GCODE_OFFSET Z={offset}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __adjust_offset]
|
||||
type: input
|
||||
address: 0x200f
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if "z" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.adjust_increment %}
|
||||
SET_GCODE_OFFSET Z_ADJUST=0.01
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.adjust_decrement %}
|
||||
SET_GCODE_OFFSET Z_ADJUST=-0.01
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __temp_preset]
|
||||
type: input
|
||||
address: 0x2010
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.preset_pla %}
|
||||
SET_HEATER_TEMPERATURE HEATER={printer.toolhead.extruder} TARGET={t5uid1.constants.temp_pla.hotend}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={t5uid1.constants.temp_pla.bed}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.preset_abs %}
|
||||
SET_HEATER_TEMPERATURE HEATER={printer.toolhead.extruder} TARGET={t5uid1.constants.temp_abs.hotend}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={t5uid1.constants.temp_abs.bed}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.preset_petg %}
|
||||
SET_HEATER_TEMPERATURE HEATER={printer.toolhead.extruder} TARGET={t5uid1.constants.temp_petg.hotend}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={t5uid1.constants.temp_petg.bed}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __temp_set_target_bed]
|
||||
type: input
|
||||
address: 0x2011
|
||||
data_type: int16
|
||||
script:
|
||||
{% set max_temp = heater_max_temp("heater_bed", 10)|round|int %}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={[data, max_temp]|min}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __temp_set_target_h0]
|
||||
type: input
|
||||
address: 0x2012
|
||||
data_type: int16
|
||||
script:
|
||||
{% set max_temp = heater_max_temp("extruder", 15)|round|int %}
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder TARGET={[data, max_temp]|min}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __temp_set_target_h1]
|
||||
type: input
|
||||
address: 0x2013
|
||||
data_type: int16
|
||||
script:
|
||||
{% if 'extruder1' in printer %}
|
||||
{% set max_temp = heater_max_temp("extruder1", 15)|round|int %}
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder1 TARGET={[data, max_temp]|min}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __temp_cool]
|
||||
type: input
|
||||
address: 0x2014
|
||||
data_type: int16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.heater_all %}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0
|
||||
{% if 'extruder1' in printer %}
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder1 TARGET=0
|
||||
{% endif %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.heater_bed %}
|
||||
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=0
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.heater_h0 %}
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder TARGET=0
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.heater_h1 %}
|
||||
{% if 'extruder1' in printer %}
|
||||
SET_HEATER_TEMPERATURE HEATER=extruder1 TARGET=0
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __stepper_control]
|
||||
type: input
|
||||
address: 0x2015
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.stepper_enable %}
|
||||
{% set steppers = ['stepper_x', 'stepper_y', 'stepper_z', 'extruder'] %}
|
||||
{% if 'extruder1' in printer %}
|
||||
{% do steppers.append('extruder1') %}
|
||||
{% endif %}
|
||||
{% for stepper in steppers %}
|
||||
SET_STEPPER_ENABLE STEPPER={stepper} ENABLE=1
|
||||
{% endfor %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.stepper_disable %}
|
||||
M18
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __level_offset_set]
|
||||
type: input
|
||||
address: 0x2016
|
||||
data_type: int16
|
||||
script:
|
||||
{% if "z" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set offset = data|float / 10 ** 2 %}
|
||||
SET_GCODE_OFFSET Z={offset}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __level_offset_step]
|
||||
type: input
|
||||
address: 0x2017
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if "z" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set offset_steps = get_variable("offset_steps",
|
||||
t5uid1.constants['step_size_0.1']) %}
|
||||
{% if offset_steps == t5uid1.constants['step_size_0.1'] %}
|
||||
{% set step = "0.1" %}
|
||||
{% elif offset_steps == t5uid1.constants['step_size_0.01'] %}
|
||||
{% set step = "0.01" %}
|
||||
{% endif %}
|
||||
{% if data == t5uid1.constants.adjust_increment %}
|
||||
SET_GCODE_OFFSET Z_ADJUST={step}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% elif data == t5uid1.constants.adjust_decrement %}
|
||||
SET_GCODE_OFFSET Z_ADJUST=-{step}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __level_offset_set_step]
|
||||
type: input
|
||||
address: 0x2018
|
||||
data_type: uint16
|
||||
script:
|
||||
{% do set_variable("offset_steps", data) %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __level_manual_point]
|
||||
type: input
|
||||
address: 0x2019
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if printer.toolhead.homed_axes != "xyz" %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% elif is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% set inset = 30 %}
|
||||
{% set hop = 5 %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == 1 %}
|
||||
{% set x = (t5uid1.limits.x_max - t5uid1.limits.x_min) / 2 %}
|
||||
{% set y = (t5uid1.limits.y_max - t5uid1.limits.y_min) / 2 %}
|
||||
{% elif data == 2 %}
|
||||
{% set x = t5uid1.limits.x_min + inset %}
|
||||
{% set y = t5uid1.limits.y_min + inset %}
|
||||
{% elif data == 3 %}
|
||||
{% set x = t5uid1.limits.x_max - inset %}
|
||||
{% set y = t5uid1.limits.y_min + inset %}
|
||||
{% elif data == 4 %}
|
||||
{% set x = t5uid1.limits.x_max - inset %}
|
||||
{% set y = t5uid1.limits.y_max - inset %}
|
||||
{% elif data == 5 %}
|
||||
{% set x = t5uid1.limits.x_min + inset %}
|
||||
{% set y = t5uid1.limits.y_max - inset %}
|
||||
{% endif %}
|
||||
SAVE_GCODE_STATE NAME=state_level_manual_point
|
||||
G90
|
||||
{% if printer.gcode.move_zpos < hop %}
|
||||
G1 Z{hop} F600
|
||||
{% endif %}
|
||||
G1 X{x} Y{y} F4800
|
||||
G1 Z0 F300
|
||||
RESTORE_GCODE_STATE NAME=state_level_manual_point
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __level_auto_probe]
|
||||
type: input
|
||||
address: 0x201a
|
||||
data_type: none
|
||||
script:
|
||||
{% if printer.toolhead.homed_axes != "xyz" %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% elif is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
BED_MESH_CALIBRATE
|
||||
G28 Z
|
||||
{% do start_routine("show_probing_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __level_auto_disable]
|
||||
type: input
|
||||
address: 0x201b
|
||||
data_type: none
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
BED_MESH_CLEAR
|
||||
BED_MESH_PROFILE REMOVE=default
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __filament_select]
|
||||
type: input
|
||||
address: 0x201c
|
||||
data_type: int16
|
||||
script:
|
||||
{% do set_variable("filament_extruder", data) %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __filament_set_length]
|
||||
type: input
|
||||
address: 0x201d
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set extruder = get_variable("filament_extruder",
|
||||
t5uid1.constants.extruder_current) %}
|
||||
{% if extruder == t5uid1.constants.extruder_current %}
|
||||
{% set len = limit_extrude(printer.toolhead.extruder, data) %}
|
||||
{% elif extruder == t5uid1.constants.extruder_e0 %}
|
||||
{% set len = limit_extrude("extruder", data) %}
|
||||
{% elif extruder == t5uid1.constants.extruder_e1 %}
|
||||
{% set len = limit_extrude("extruder1", data) %}
|
||||
{% endif %}
|
||||
{% do set_variable("filament_length", len|round|int) %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __filament_move]
|
||||
type: input
|
||||
address: 0x201e
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set extruder = get_variable("filament_extruder",
|
||||
t5uid1.constants.extruder_current) %}
|
||||
{% if extruder == t5uid1.constants.extruder_current %}
|
||||
{% set ext_name = printer.toolhead.extruder %}
|
||||
{% elif extruder == t5uid1.constants.extruder_e0 %}
|
||||
{% set ext_name = "extruder" %}
|
||||
{% elif extruder == t5uid1.constants.extruder_e1 %}
|
||||
{% set ext_name = "extruder1" %}
|
||||
{% endif %}
|
||||
{% if ext_name not in printer %}
|
||||
{% do set_message("Invalid extruder") %}
|
||||
{% elif printer[ext_name].temperature < heater_min_extrude_temp(ext_name) %}
|
||||
{% do set_message("Temperature too low") %}
|
||||
{% else %}
|
||||
SAVE_GCODE_STATE NAME=state_filament_move
|
||||
ACTIVATE_EXTRUDER EXTRUDER={ext_name}
|
||||
M83
|
||||
{% set length = get_variable("filament_length", 10) %}
|
||||
{% if data == t5uid1.constants.filament_retract %}
|
||||
G1 E-{length}
|
||||
{% elif data == t5uid1.constants.filament_extrude %}
|
||||
G1 E{length}
|
||||
{% endif %}
|
||||
RESTORE_GCODE_STATE NAME=state_filament_move
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __home]
|
||||
type: input
|
||||
address: 0x201f
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "Homing...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", t5uid1.page) %}
|
||||
{% if data == t5uid1.constants.axis_xyz %}
|
||||
G28 X Y Z
|
||||
{% elif data == t5uid1.constants.axis_xy %}
|
||||
G28 X Y
|
||||
{% elif data == t5uid1.constants.axis_z %}
|
||||
G28 Z
|
||||
{% endif %}
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __move_x]
|
||||
type: input
|
||||
address: 0x2020
|
||||
data_type: int16
|
||||
script:
|
||||
{% if "x" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pos = data|float / 10 ** 1 %}
|
||||
{% if pos < t5uid1.limits.x_min %}
|
||||
{% set pos = t5uid1.limits.x_min %}
|
||||
{% elif pos > t5uid1.limits.x_max %}
|
||||
{% set pos = t5uid1.limits.x_max %}
|
||||
{% endif %}
|
||||
SAVE_GCODE_STATE NAME=state_move_x
|
||||
G90
|
||||
G1 X{pos} F4800
|
||||
RESTORE_GCODE_STATE NAME=state_move_x
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __move_y]
|
||||
type: input
|
||||
address: 0x2021
|
||||
data_type: int16
|
||||
script:
|
||||
{% if "y" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pos = data|float / 10 ** 1 %}
|
||||
{% if pos < t5uid1.limits.y_min %}
|
||||
{% set pos = t5uid1.limits.y_min %}
|
||||
{% elif pos > t5uid1.limits.y_max %}
|
||||
{% set pos = t5uid1.limits.y_max %}
|
||||
{% endif %}
|
||||
SAVE_GCODE_STATE NAME=state_move_y
|
||||
G90
|
||||
G1 Y{pos} F4800
|
||||
RESTORE_GCODE_STATE NAME=state_move_y
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __move_z]
|
||||
type: input
|
||||
address: 0x2022
|
||||
data_type: int16
|
||||
script:
|
||||
{% if "z" not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pos = data|float / 10 ** 1 %}
|
||||
{% if pos < t5uid1.limits.z_min %}
|
||||
{% set pos = t5uid1.limits.z_min %}
|
||||
{% elif pos > t5uid1.limits.z_max %}
|
||||
{% set pos = t5uid1.limits.z_max %}
|
||||
{% endif %}
|
||||
SAVE_GCODE_STATE NAME=state_move_z
|
||||
G90
|
||||
G1 Z{pos} F900
|
||||
RESTORE_GCODE_STATE NAME=state_move_z
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __move_step]
|
||||
type: input
|
||||
address: 0x2023
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set move_steps = get_variable("move_steps",
|
||||
t5uid1.constants.step_size_10) %}
|
||||
{% if move_steps == t5uid1.constants.step_size_10 %}
|
||||
{% set step = 10.0 %}
|
||||
{% elif move_steps == t5uid1.constants.step_size_1 %}
|
||||
{% set step = 1.0 %}
|
||||
{% elif move_steps == t5uid1.constants['step_size_0.1'] %}
|
||||
{% set step = 0.1 %}
|
||||
{% endif %}
|
||||
{% if data == t5uid1.constants['move_x+'] %}
|
||||
{% set axis = "x" %}
|
||||
{% set pos = printer.gcode.move_xpos + step %}
|
||||
{% set speed = 4800 %}
|
||||
{% elif data == t5uid1.constants['move_x-'] %}
|
||||
{% set axis = "x" %}
|
||||
{% set pos = printer.gcode.move_xpos - step %}
|
||||
{% set speed = 4800 %}
|
||||
{% elif data == t5uid1.constants['move_y+'] %}
|
||||
{% set axis = "y" %}
|
||||
{% set pos = printer.gcode.move_ypos + step %}
|
||||
{% set speed = 4800 %}
|
||||
{% elif data == t5uid1.constants['move_y-'] %}
|
||||
{% set axis = "y" %}
|
||||
{% set pos = printer.gcode.move_ypos - step %}
|
||||
{% set speed = 4800 %}
|
||||
{% elif data == t5uid1.constants['move_z+'] %}
|
||||
{% set axis = "z" %}
|
||||
{% set pos = printer.gcode.move_zpos + step %}
|
||||
{% set speed = 900 %}
|
||||
{% elif data == t5uid1.constants['move_z-'] %}
|
||||
{% set axis = "z" %}
|
||||
{% set pos = printer.gcode.move_zpos - step %}
|
||||
{% set speed = 900 %}
|
||||
{% endif %}
|
||||
{% if axis not in printer.toolhead.homed_axes %}
|
||||
{% do set_message("Homing required") %}
|
||||
{% else %}
|
||||
{% if pos < t5uid1.limits[axis ~ "_min"] %}
|
||||
{% set pos = t5uid1.limits[axis ~ "_min"] %}
|
||||
{% elif pos > t5uid1.limits[axis ~ "_max"] %}
|
||||
{% set pos = t5uid1.limits[axis ~ "_max"] %}
|
||||
{% endif %}
|
||||
SAVE_GCODE_STATE NAME=state_move_step
|
||||
G90
|
||||
G1 {axis|upper}{pos} F{speed}
|
||||
RESTORE_GCODE_STATE NAME=state_move_step
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __move_set_step]
|
||||
type: input
|
||||
address: 0x2024
|
||||
data_type: uint16
|
||||
script:
|
||||
{% do set_variable("move_steps", data) %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __settings2_extra]
|
||||
type: input
|
||||
address: 0x2028
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.extra_button1 %}
|
||||
{% if t5uid1.has_bltouch %}
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% do start_routine("reset_bltouch") %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% do switch_page("info") %}
|
||||
{% endif %}
|
||||
{% elif data == t5uid1.constants.extra_button2 %}
|
||||
{% if t5uid1.has_bltouch %}
|
||||
{% do switch_page("info") %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var __pid_select]
|
||||
type: input
|
||||
address: 0x2029
|
||||
data_type: int16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if data == t5uid1.constants.heater_bed %}
|
||||
{% do set_variable("pid_temp", t5uid1.constants.temp_pla.bed) %}
|
||||
{% do set_variable("pid_heater", data) %}
|
||||
{% elif data == t5uid1.constants.heater_h0 %}
|
||||
{% do set_variable("pid_temp", t5uid1.constants.temp_pla.hotend) %}
|
||||
{% do set_variable("pid_heater", data) %}
|
||||
{% elif data == t5uid1.constants.heater_h1 %}
|
||||
{% do set_variable("pid_temp", t5uid1.constants.temp_pla.hotend) %}
|
||||
{% do set_variable("pid_heater", data) %}
|
||||
{% endif %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __pid_set_temp]
|
||||
type: input
|
||||
address: 0x202a
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
{% set min_temp = heater_min_temp("heater_bed")|round|int %}
|
||||
{% set max_temp = heater_max_temp("heater_bed", 10)|round|int %}
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
{% set min_temp = heater_min_temp("extruder")|round|int %}
|
||||
{% set max_temp = heater_max_temp("extruder", 15)|round|int %}
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{% set min_temp = heater_min_temp("extruder1")|round|int %}
|
||||
{% set max_temp = heater_max_temp("extruder1", 15)|round|int %}
|
||||
{% endif %}
|
||||
{% do set_variable("pid_temp", [([data, max_temp]|min), min_temp]|max) %}
|
||||
{% do start_routine("trigger_full_update") %}
|
||||
|
||||
[t5uid1_var __pid_run]
|
||||
type: input
|
||||
address: 0x202b
|
||||
data_type: none
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% set pid_temp = get_variable("pid_temp",
|
||||
t5uid1.constants.temp_pla.hotend) %}
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "PID autotuning...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", "pid") %}
|
||||
{% do set_variable("wait_return_sound", t5uid1.notification_sound) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
PID_CALIBRATE HEATER=heater_bed TARGET={pid_temp}
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
PID_CALIBRATE HEATER=extruder TARGET={pid_temp}
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{% if 'extruder1' in printer %}
|
||||
PID_CALIBRATE HEATER=extruder1 TARGET={pid_temp}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __save_config]
|
||||
type: input
|
||||
address: 0x2030
|
||||
data_type: none
|
||||
script:
|
||||
{% if is_busy() %}
|
||||
{% do set_message("Busy") %}
|
||||
{% else %}
|
||||
{% do set_variable("line1", "") %}
|
||||
{% do set_variable("line2", "Saving configuration...") %}
|
||||
{% do set_variable("line3", "") %}
|
||||
{% do set_variable("line4", "") %}
|
||||
{% do set_variable("wait_return", "boot") %}
|
||||
SAVE_CONFIG
|
||||
{% do start_routine("show_wait_screen") %}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __fan_speed]
|
||||
type: input
|
||||
address: 0x4000
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if data >= 0 and data <= 100 %}
|
||||
M106 S{(data|float / 100 * 255)|round|int}
|
||||
{% endif %}
|
||||
run_as_gcode: true
|
||||
|
||||
[t5uid1_var __volume]
|
||||
type: input
|
||||
address: 0x4022
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if data >= 0 and data <= 100 %}
|
||||
{% do set_volume(data) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var __brightness]
|
||||
type: input
|
||||
address: 0x4023
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if data >= 0 and data <= 100 %}
|
||||
{% do set_brightness(data) %}
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var __debug]
|
||||
type: input
|
||||
address: 0x5001
|
||||
data_type: none
|
||||
script:
|
||||
{% set counter = get_variable("debug_count", 0)|int + 1 %}
|
||||
{% do set_variable("debug_count", counter) %}
|
||||
{% if counter >= 10 %}
|
||||
{% do switch_page("debug1") %}
|
||||
{% endif %}
|
|
@ -0,0 +1,461 @@
|
|||
[t5uid1_var line1]
|
||||
type: output
|
||||
address: 0x1100
|
||||
data_type: str
|
||||
data_len: 32
|
||||
script: { "{:^32s}".format(get_variable("line1", "")|trim) }
|
||||
|
||||
[t5uid1_var line2]
|
||||
type: output
|
||||
address: 0x1120
|
||||
data_type: str
|
||||
data_len: 32
|
||||
script: { "{:^32s}".format(get_variable("line2", "")|trim) }
|
||||
|
||||
[t5uid1_var line3]
|
||||
type: output
|
||||
address: 0x1140
|
||||
data_type: str
|
||||
data_len: 32
|
||||
script: { "{:^32s}".format(get_variable("line3", "")|trim) }
|
||||
|
||||
[t5uid1_var line4]
|
||||
type: output
|
||||
address: 0x1160
|
||||
data_type: str
|
||||
data_len: 32
|
||||
script: { "{:^32s}".format(get_variable("line4", "")|trim) }
|
||||
|
||||
[t5uid1_var message]
|
||||
type: output
|
||||
address: 0x3000
|
||||
data_type: str
|
||||
data_len: 32
|
||||
script: { "{:>32s}".format(get_variable("message", "")|trim) }
|
||||
|
||||
[t5uid1_var status_position_z]
|
||||
type: output
|
||||
address: 0x30e6
|
||||
data_type: int16
|
||||
script: { (printer.gcode.move_zpos * 10 ** 1)|round|int }
|
||||
|
||||
[t5uid1_var status_ellapsed]
|
||||
type: output
|
||||
address: 0x30e7
|
||||
data_type: str
|
||||
data_len: 15
|
||||
script: { get_duration(printer.t5uid1.print_duration) }
|
||||
|
||||
[t5uid1_var status_percent]
|
||||
type: output
|
||||
address: 0x30f6
|
||||
data_type: uint16
|
||||
script: { printer.t5uid1.print_progress }
|
||||
|
||||
[t5uid1_var status_icons]
|
||||
type: output
|
||||
address: 0x30f7
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if not t5uid1.is_printing %}
|
||||
{% do disable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.pause) %}
|
||||
{% do disable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.resume) %}
|
||||
{ "0" }
|
||||
{% elif printer.pause_resume.is_paused %}
|
||||
{% do enable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.resume) %}
|
||||
{% do disable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.pause) %}
|
||||
{ t5uid1.constants.status_icon_resume }
|
||||
{% else %}
|
||||
{% do enable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.pause) %}
|
||||
{% do disable_control(t5uid1.pages.print_status,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.resume) %}
|
||||
{ t5uid1.constants.status_icon_pause }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var adjust_feedrate]
|
||||
type: output
|
||||
address: 0x30f8
|
||||
data_type: int16
|
||||
script: { (printer.gcode.speed_factor * 100)|round|int }
|
||||
|
||||
[t5uid1_var adjust_flowrate]
|
||||
type: output
|
||||
address: 0x30f9
|
||||
data_type: int16
|
||||
script: { (printer.gcode.extrude_factor * 100)|round|int }
|
||||
|
||||
[t5uid1_var temp_bed_current]
|
||||
type: output
|
||||
address: 0x30fc
|
||||
data_type: int16
|
||||
script: { printer.heater_bed.temperature|round|int }
|
||||
|
||||
[t5uid1_var temp_bed_target]
|
||||
type: output
|
||||
address: 0x30fd
|
||||
data_type: int16
|
||||
script: { printer.heater_bed.target|round|int }
|
||||
|
||||
[t5uid1_var temp_bed_max]
|
||||
type: output
|
||||
address: 0x30fe
|
||||
data_type: uint16
|
||||
script: { heater_max_temp("heater_bed", 10)|round|int }
|
||||
|
||||
[t5uid1_var temp_h0_current]
|
||||
type: output
|
||||
address: 0x30ff
|
||||
data_type: int16
|
||||
script: { printer.extruder.temperature|round|int }
|
||||
|
||||
[t5uid1_var temp_h0_target]
|
||||
type: output
|
||||
address: 0x3100
|
||||
data_type: int16
|
||||
script: { printer.extruder.target|round|int }
|
||||
|
||||
[t5uid1_var temp_h0_max]
|
||||
type: output
|
||||
address: 0x3101
|
||||
data_type: uint16
|
||||
script: { heater_max_temp("extruder", 15)|round|int }
|
||||
|
||||
[t5uid1_var temp_h1_current]
|
||||
type: output
|
||||
address: 0x3102
|
||||
data_type: int16
|
||||
script:
|
||||
{% if 'extruder1' in printer %}
|
||||
{ printer.extruder1.temperature|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var temp_h1_target]
|
||||
type: output
|
||||
address: 0x3103
|
||||
data_type: int16
|
||||
script:
|
||||
{% if 'extruder1' in printer %}
|
||||
{ printer.extruder1.target|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var temp_h1_max]
|
||||
type: output
|
||||
address: 0x3104
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if 'extruder1' in printer %}
|
||||
{ heater_max_temp("extruder1", 15)|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var stepper_status]
|
||||
type: output
|
||||
address: 0x3105
|
||||
data_type: uint16
|
||||
script:
|
||||
{% if all_steppers_enabled() %}
|
||||
{ printer.t5uid1.constants.enabled }
|
||||
{% else %}
|
||||
{ printer.t5uid1.constants.disabled }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var level_offset]
|
||||
type: output
|
||||
address: 0x3106
|
||||
data_type: int16
|
||||
script: { (printer.gcode.base_zpos * 10 ** 1)|round|int }
|
||||
|
||||
[t5uid1_var level_offset_step_icons]
|
||||
type: output
|
||||
address: 0x3107
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set offset_steps = get_variable("offset_steps",
|
||||
t5uid1.constants['step_size_0.1']) %}
|
||||
{% if offset_steps == t5uid1.constants['step_size_0.1'] %}
|
||||
{ t5uid1.constants['step_icon_0.1'] }
|
||||
{% elif offset_steps == t5uid1.constants['step_size_0.01'] %}
|
||||
{ t5uid1.constants['step_icon_0.01'] }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var level_auto_disable_icon]
|
||||
type: output
|
||||
address: 0x3108
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if printer.bed_mesh.profile_name != "" %}
|
||||
{% do enable_control(t5uid1.pages.leveling_automatic,
|
||||
t5uid1.control_types.return_key_code,
|
||||
t5uid1.controls.disable) %}
|
||||
{ t5uid1.constants.enabled }
|
||||
{% else %}
|
||||
{% do disable_control(t5uid1.pages.leveling_automatic,
|
||||
t5uid1.control_types.return_key_code,
|
||||
t5uid1.controls.disable) %}
|
||||
{ t5uid1.constants.disabled }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var level_auto_grid]
|
||||
type: output
|
||||
address: 0x3109
|
||||
data_type: array[int16]
|
||||
array_len: 25
|
||||
script:
|
||||
{% set grid = printer.bed_mesh.probed_matrix %}
|
||||
{% if not grid or grid|length < 5 %}
|
||||
{% set grid = [] %}
|
||||
{% for i in range(5) %}
|
||||
{% do grid.append([0, 0, 0, 0, 0]) %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% for line in grid %}
|
||||
{% for val in line %}
|
||||
{ (val * 10 ** 3)|round|int },
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
[t5uid1_var level_probing_icons]
|
||||
type: output
|
||||
address: 0x3122
|
||||
data_type: uint32
|
||||
script: { probed_matrix() }
|
||||
|
||||
[t5uid1_var filament_icons]
|
||||
type: output
|
||||
address: 0x3124
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set extruder = get_variable("filament_extruder",
|
||||
t5uid1.constants.extruder_current) %}
|
||||
{% if extruder == t5uid1.constants.extruder_current %}
|
||||
{% if printer.toolhead.extruder == "extruder" %}
|
||||
{ t5uid1.constants.extruder_icon_e0 }
|
||||
{% elif printer.toolhead.extruder == "extruder1" %}
|
||||
{ t5uid1.constants.extruder_icon_e1 }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
{% elif extruder == t5uid1.constants.extruder_e0 %}
|
||||
{ t5uid1.constants.extruder_icon_e0 }
|
||||
{% elif extruder == t5uid1.constants.extruder_e1 %}
|
||||
{ t5uid1.constants.extruder_icon_e1 }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var filament_length]
|
||||
type: output
|
||||
address: 0x3125
|
||||
data_type: uint16
|
||||
script: { get_variable("filament_length", 10) }
|
||||
|
||||
[t5uid1_var move_current_x]
|
||||
type: output
|
||||
address: 0x3126
|
||||
data_type: int16
|
||||
script: { (printer.gcode.move_xpos * 10 ** 1)|round|int }
|
||||
|
||||
[t5uid1_var move_current_y]
|
||||
type: output
|
||||
address: 0x3127
|
||||
data_type: int16
|
||||
script: { (printer.gcode.move_ypos * 10 ** 1)|round|int }
|
||||
|
||||
[t5uid1_var move_current_z]
|
||||
type: output
|
||||
address: 0x3128
|
||||
data_type: int16
|
||||
script: { (printer.gcode.move_zpos * 10 ** 1)|round|int }
|
||||
|
||||
[t5uid1_var move_step_icons]
|
||||
type: output
|
||||
address: 0x3129
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set move_steps = get_variable("move_steps",
|
||||
t5uid1.constants.step_size_10) %}
|
||||
{% if move_steps == t5uid1.constants.step_size_10 %}
|
||||
{ t5uid1.constants.step_icon_10 }
|
||||
{% elif move_steps == t5uid1.constants.step_size_1 %}
|
||||
{ t5uid1.constants.step_icon_1 }
|
||||
{% elif move_steps == t5uid1.constants['step_size_0.1'] %}
|
||||
{ t5uid1.constants['step_icon_0.1'] }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var bltouch]
|
||||
type: output
|
||||
address: 0x312a
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% if t5uid1.has_bltouch %}
|
||||
{% do enable_control(t5uid1.pages.settings_menu2,
|
||||
t5uid1.control_types.return_key_code,
|
||||
t5uid1.controls.extra2) %}
|
||||
{ t5uid1.constants.enabled }
|
||||
{% else %}
|
||||
{% do disable_control(t5uid1.pages.settings_menu2,
|
||||
t5uid1.control_types.return_key_code,
|
||||
t5uid1.controls.extra2) %}
|
||||
{ t5uid1.constants.disabled }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var pid_heater_icons]
|
||||
type: output
|
||||
address: 0x312b
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
{ t5uid1.constants.heater_icon_bed }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
{ t5uid1.constants.heater_icon_h0 }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{ t5uid1.constants.heater_icon_h1 }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var pid_temp]
|
||||
type: output
|
||||
address: 0x312c
|
||||
data_type: uint16
|
||||
script: { get_variable("pid_temp", printer.t5uid1.constants.temp_pla.hotend) }
|
||||
|
||||
[t5uid1_var pid_kp]
|
||||
type: output
|
||||
address: 0x312d
|
||||
data_type: int32
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
{ (pid_param("heater_bed", "p") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
{ (pid_param("extruder", "p") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{ (pid_param("extruder1", "p") * 10 ** 2)|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var pid_ki]
|
||||
type: output
|
||||
address: 0x312f
|
||||
data_type: int32
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
{ (pid_param("heater_bed", "i") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
{ (pid_param("extruder", "i") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{ (pid_param("extruder1", "i") * 10 ** 2)|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var pid_kd]
|
||||
type: output
|
||||
address: 0x3131
|
||||
data_type: int32
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% set pid_heater = get_variable("pid_heater",
|
||||
t5uid1.constants.heater_h0) %}
|
||||
{% if pid_heater == t5uid1.constants.heater_bed %}
|
||||
{ (pid_param("heater_bed", "d") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h0 %}
|
||||
{ (pid_param("extruder", "d") * 10 ** 2)|round|int }
|
||||
{% elif pid_heater == t5uid1.constants.heater_h1 %}
|
||||
{ (pid_param("extruder1", "d") * 10 ** 2)|round|int }
|
||||
{% else %}
|
||||
{ "0" }
|
||||
{% endif %}
|
||||
|
||||
[t5uid1_var info_machine]
|
||||
type: output
|
||||
address: 0x3133
|
||||
data_type: str
|
||||
data_len: 24
|
||||
script: { printer.t5uid1.machine_name }
|
||||
|
||||
[t5uid1_var info_build_volume]
|
||||
type: output
|
||||
address: 0x314b
|
||||
data_type: str
|
||||
data_len: 24
|
||||
script:
|
||||
{% set limits = printer.t5uid1.limits %}
|
||||
{ "{:d}x{:d}x{:d}".format((limits.x_max - limits.x_min)|round(0, 'floor')|int,
|
||||
(limits.y_max - limits.y_min)|round(0, 'floor')|int,
|
||||
(limits.z_max - limits.z_min)|round(0, 'floor')|int) }
|
||||
|
||||
[t5uid1_var info_version]
|
||||
type: output
|
||||
address: 0x3163
|
||||
data_type: str
|
||||
data_len: 16
|
||||
script: { printer.t5uid1.version }
|
||||
|
||||
[t5uid1_var wait_icons]
|
||||
type: output
|
||||
address: 0x31bd
|
||||
data_type: uint16
|
||||
script:
|
||||
{% set t5uid1 = printer.t5uid1 %}
|
||||
{% do disable_control(t5uid1.pages.wait,
|
||||
t5uid1.control_types.popup_window,
|
||||
t5uid1.controls.abort) %}
|
||||
{% do disable_control(t5uid1.pages.wait,
|
||||
t5uid1.control_types.return_key_code,
|
||||
t5uid1.controls.continue) %}
|
||||
{ "0" }
|
||||
|
||||
[t5uid1_var fan_speed]
|
||||
type: output
|
||||
address: 0x4000
|
||||
data_type: uint16
|
||||
script: { (printer.fan.speed * 100)|round|int }
|
||||
|
||||
[t5uid1_var volume]
|
||||
type: output
|
||||
address: 0x4022
|
||||
data_type: uint16
|
||||
script: { printer.t5uid1.volume }
|
||||
|
||||
[t5uid1_var brightness]
|
||||
type: output
|
||||
address: 0x4023
|
||||
data_type: uint16
|
||||
script: { printer.t5uid1.brightness }
|
|
@ -0,0 +1,38 @@
|
|||
# Page class
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
class T5UID1_Page:
|
||||
def __init__(self, var_names, config):
|
||||
self.printer = config.get_printer()
|
||||
name_parts = config.get_name().split()
|
||||
if len(name_parts) != 2:
|
||||
raise config.error("Section name '%s' is not valid"
|
||||
% (config.get_name(),))
|
||||
self.name = name_parts[1]
|
||||
|
||||
self.id = config.getint('id', minval=0, maxval=255)
|
||||
self.is_boot = config.getboolean('boot', False)
|
||||
self.is_timeout = config.getboolean('timeout', False)
|
||||
self.is_shutdown = config.getboolean('shutdown', False)
|
||||
self.var_auto = []
|
||||
self.var = []
|
||||
|
||||
for var in config.get('var_auto', '').split(','):
|
||||
var = var.strip()
|
||||
if len(var) > 0 and var not in self.var_auto:
|
||||
if var not in var_names:
|
||||
raise config.error("Invalid var '%s' in section '%s'"
|
||||
% (var, config.get_name()))
|
||||
self.var_auto.append(var)
|
||||
|
||||
for var in config.get('var', '').split(','):
|
||||
var = var.strip()
|
||||
if (len(var) > 0
|
||||
and var not in self.var_auto and var not in self.var):
|
||||
if var not in var_names:
|
||||
raise config.error("Invalid var '%s' in section '%s'"
|
||||
% (var, config.get_name()))
|
||||
self.var.append(var)
|
|
@ -0,0 +1,102 @@
|
|||
# Routine class
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
TRIGGERS = [
|
||||
"enter_pre",
|
||||
"enter",
|
||||
"leave",
|
||||
"manual"
|
||||
]
|
||||
|
||||
class T5UID1_Routine:
|
||||
def __init__(self, gcode_macro, context, page_names, config):
|
||||
self.printer = config.get_printer()
|
||||
|
||||
self.gcode = self.printer.lookup_object('gcode')
|
||||
self.reactor = self.printer.get_reactor()
|
||||
|
||||
name_parts = config.get_name().split()
|
||||
if len(name_parts) != 2:
|
||||
raise config.error("Section name '%s' is not valid"
|
||||
% (config.get_name(),))
|
||||
self.name = name_parts[1]
|
||||
|
||||
self.trigger = config.get('trigger')
|
||||
if self.trigger not in TRIGGERS:
|
||||
raise config.error("Invalid trigger '%s' in section '%s'"
|
||||
% (self.trigger, config.get_name()))
|
||||
|
||||
if self.trigger != "manual":
|
||||
self.page = config.get('page')
|
||||
if self.page not in page_names:
|
||||
raise config.error("Invalid page '%s' in section '%s'"
|
||||
% (self.page, config.get_name()))
|
||||
else:
|
||||
self.page = None
|
||||
|
||||
if self.trigger != "enter_pre":
|
||||
self.delay = config.getint('delay', None, minval=0, maxval=60)
|
||||
else:
|
||||
self.delay = None
|
||||
|
||||
if self.trigger in ["enter", "manual"]:
|
||||
self.interval = config.getint('interval', 0, minval=0, maxval=60)
|
||||
else:
|
||||
self.interval = 0
|
||||
|
||||
self._template = gcode_macro.load_template(config, 'script')
|
||||
self._context = context
|
||||
self.run_as_gcode = config.getboolean('run_as_gcode', False)
|
||||
|
||||
self._should_stop = False
|
||||
self._timer = self.reactor.register_timer(self._timer_run)
|
||||
|
||||
def _timer_run(self, eventtime):
|
||||
if self._should_stop:
|
||||
return self.reactor.NEVER
|
||||
self.run(is_timer=True)
|
||||
if self._should_stop or self.interval <= 0:
|
||||
return self.reactor.NEVER
|
||||
return eventtime + self.interval
|
||||
|
||||
def run(self, repeat=True, is_timer=False):
|
||||
if not is_timer:
|
||||
self._should_stop = False
|
||||
if self.delay is not None:
|
||||
if self.delay > 0:
|
||||
self.reactor.update_timer(self._timer,
|
||||
self.reactor.monotonic()
|
||||
+ self.delay)
|
||||
else:
|
||||
self.reactor.update_timer(self._timer, self.reactor.NOW)
|
||||
return
|
||||
|
||||
swrap = self._template.create_status_wrapper()
|
||||
context = { 'printer': swrap,
|
||||
'is_timer': is_timer }
|
||||
context.update(self._context)
|
||||
|
||||
result = self._template.render(context).strip()
|
||||
if self.run_as_gcode and len(result) > 0:
|
||||
self.gcode.run_script_from_command(result)
|
||||
|
||||
if not is_timer and self.interval > 0:
|
||||
if repeat:
|
||||
next_run = self.reactor.monotonic() + self.interval
|
||||
else:
|
||||
next_run = self.reactor.NEVER
|
||||
self.reactor.update_timer(self._timer, next_run)
|
||||
return
|
||||
|
||||
if self.trigger == "enter_pre":
|
||||
if len(result) == 0:
|
||||
return True
|
||||
commands = [ c.strip() for c in result.split('\n') ]
|
||||
return not "DGUS_ABORT_PAGE_SWITCH" in commands
|
||||
|
||||
def stop(self):
|
||||
self._should_stop = True
|
||||
self.reactor.update_timer(self._timer, self.reactor.NEVER)
|
|
@ -0,0 +1,891 @@
|
|||
# Support for DGUS T5UID1 touchscreens
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import os, logging, struct, textwrap
|
||||
import jinja2
|
||||
import mcu
|
||||
from . import var, page, routine, dgus_reloaded
|
||||
from .. import gcode_macro, heaters
|
||||
|
||||
T5UID1_firmware_cfg = {
|
||||
'dgus_reloaded': dgus_reloaded.configuration
|
||||
}
|
||||
|
||||
DEFAULT_VOLUME = 75
|
||||
DEFAULT_BRIGHTNESS = 100
|
||||
|
||||
T5UID1_CMD_WRITEVAR = 0x82
|
||||
T5UID1_CMD_READVAR = 0x83
|
||||
|
||||
T5UID1_ADDR_VERSION = 0x0f
|
||||
T5UID1_ADDR_BRIGHTNESS = 0x82
|
||||
T5UID1_ADDR_PAGE = 0x84
|
||||
T5UID1_ADDR_SOUND = 0xa0
|
||||
T5UID1_ADDR_VOLUME = 0xa1
|
||||
T5UID1_ADDR_CONTROL = 0xb0
|
||||
|
||||
TIMEOUT_SECS = 15
|
||||
CMD_DELAY = 0.02
|
||||
|
||||
CONTROL_TYPES = {
|
||||
'variable_data_input': 0x00,
|
||||
'popup_window': 0x01,
|
||||
'incremental_adjust': 0x02,
|
||||
'slider_adjust': 0x03,
|
||||
'rtc_settings': 0x04,
|
||||
'return_key_code': 0x05,
|
||||
'text_input': 0x06,
|
||||
'firmware_settings': 0x07
|
||||
}
|
||||
|
||||
def map_value_range(x, in_min, in_max, out_min, out_max):
|
||||
return int(round((x - in_min)
|
||||
* (out_max - out_min)
|
||||
/ (in_max - in_min)
|
||||
+ out_min))
|
||||
|
||||
def get_duration(seconds):
|
||||
if type(seconds) is not int:
|
||||
seconds = int(seconds)
|
||||
if seconds < 0:
|
||||
seconds = 0
|
||||
minutes = seconds / 60
|
||||
hours = minutes / 60
|
||||
days = hours / 24
|
||||
days %= 365
|
||||
hours %= 24
|
||||
minutes %= 60
|
||||
seconds %= 60
|
||||
result = str(seconds) + "s"
|
||||
if minutes:
|
||||
result = str(minutes) + "m " + result
|
||||
if hours:
|
||||
result = str(hours) + "h " + result
|
||||
if days:
|
||||
result = str(days) + "d " + result
|
||||
return result
|
||||
|
||||
def bitwise_and(lhs, rhs):
|
||||
return lhs & rhs
|
||||
|
||||
def bitwise_or(lhs, rhs):
|
||||
return lhs | rhs
|
||||
|
||||
class T5UID1GCodeMacro:
|
||||
def __init__(self, config):
|
||||
self.printer = config.get_printer()
|
||||
self.env = jinja2.Environment('{%', '%}', '{', '}',
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
extensions=['jinja2.ext.do'])
|
||||
def load_template(self, config, option, default=None):
|
||||
name = "%s:%s" % (config.get_name(), option)
|
||||
if default is None:
|
||||
script = config.get(option)
|
||||
else:
|
||||
script = config.get(option, default)
|
||||
return gcode_macro.TemplateWrapper(self.printer, self.env, name, script)
|
||||
|
||||
class T5UID1:
|
||||
def __init__(self, config):
|
||||
self.printer = config.get_printer()
|
||||
self.name = config.get_name()
|
||||
|
||||
self.reactor = self.printer.get_reactor()
|
||||
|
||||
self.gcode = self.printer.lookup_object('gcode')
|
||||
self.configfile = self.printer.lookup_object('configfile')
|
||||
|
||||
self.stepper_enable = self.heaters = self.bed_mesh = None
|
||||
self.toolhead = self.probe = self.pause_resume = None
|
||||
self.extruders = {}
|
||||
|
||||
self.mcu = mcu.get_printer_mcu(self.printer,
|
||||
config.get('t5uid1_mcu', 'mcu'))
|
||||
self.oid = self.mcu.create_oid()
|
||||
|
||||
self._version = self.printer.get_start_args().get('software_version')
|
||||
|
||||
self._gcode_macro = T5UID1GCodeMacro(config)
|
||||
|
||||
firmware_cfg = config.getchoice('firmware', T5UID1_firmware_cfg)
|
||||
self._firmware = config.get('firmware')
|
||||
|
||||
self._machine_name = config.get('machine_name', 'Generic 3D printer')
|
||||
self._baud = config.getint('baud', 115200, minval=1200, maxval=921600)
|
||||
self._update_interval = config.getint('update_interval', 2,
|
||||
minval=1, maxval=10)
|
||||
self._volume = config.getint('volume', DEFAULT_VOLUME,
|
||||
minval=0, maxval=100)
|
||||
self._brightness = config.getint('brightness', DEFAULT_BRIGHTNESS,
|
||||
minval=0, maxval=100)
|
||||
self._boot_sound = config.getint('boot_sound',
|
||||
firmware_cfg['boot_sound'],
|
||||
minval=-1, maxval=255)
|
||||
self._notification_sound = config.getint('notification_sound',
|
||||
firmware_cfg['notification_sound'], minval=-1, maxval=255)
|
||||
|
||||
self._z_min = config.getfloat('z_min', None)
|
||||
self._z_max = config.getfloat('z_max', None)
|
||||
|
||||
self._last_cmd_time = 0
|
||||
self._gui_version = 0
|
||||
self._os_version = 0
|
||||
self._current_page = ""
|
||||
self._variable_data = {}
|
||||
self._status_data = {}
|
||||
self._vars = {}
|
||||
self._pages = {}
|
||||
self._routines = {}
|
||||
self._is_printing = False
|
||||
self._print_progress = 0
|
||||
self._print_start_time = -1
|
||||
self._print_pause_time = -1
|
||||
self._print_end_time = -1
|
||||
self._boot_page = self._timeout_page = self._shutdown_page = None
|
||||
self._t5uid1_ping_cmd = self._t5uid1_write_cmd = None
|
||||
self._is_connected = False
|
||||
|
||||
global_context = {
|
||||
'get_variable': self.get_variable,
|
||||
'set_variable': self.set_variable,
|
||||
'enable_control': self.enable_control,
|
||||
'disable_control': self.disable_control,
|
||||
'start_routine': self.start_routine,
|
||||
'stop_routine': self.stop_routine,
|
||||
'set_message': self.set_message,
|
||||
'bitwise_and': bitwise_and,
|
||||
'bitwise_or': bitwise_or
|
||||
}
|
||||
|
||||
context_input = dict(global_context)
|
||||
context_input.update({
|
||||
'page_name': self.page_name,
|
||||
'switch_page': self.switch_page,
|
||||
'play_sound': self.play_sound,
|
||||
'set_volume': self.set_volume,
|
||||
'set_brightness': self.set_brightness,
|
||||
'limit_extrude': self.limit_extrude,
|
||||
'heater_min_temp': self.heater_min_temp,
|
||||
'heater_max_temp': self.heater_max_temp,
|
||||
'heater_min_extrude_temp': self.heater_min_extrude_temp,
|
||||
'is_busy': self.is_busy
|
||||
})
|
||||
|
||||
context_output = dict(global_context)
|
||||
context_output.update({
|
||||
'all_steppers_enabled': self.all_steppers_enabled,
|
||||
'heater_min_temp': self.heater_min_temp,
|
||||
'heater_max_temp': self.heater_max_temp,
|
||||
'probed_matrix': self.probed_matrix,
|
||||
'pid_param': self.pid_param,
|
||||
'get_duration': get_duration
|
||||
})
|
||||
|
||||
context_routine = dict(global_context)
|
||||
context_routine.update({
|
||||
'page_name': self.page_name,
|
||||
'switch_page': self.switch_page,
|
||||
'play_sound': self.play_sound,
|
||||
'set_volume': self.set_volume,
|
||||
'set_brightness': self.set_brightness,
|
||||
'abort_page_switch': self.abort_page_switch,
|
||||
'full_update': self.full_update,
|
||||
'is_busy': self.is_busy,
|
||||
'check_paused': self.check_paused
|
||||
})
|
||||
|
||||
self._status_data.update({
|
||||
'controls': firmware_cfg['controls'],
|
||||
'constants': firmware_cfg['constants']
|
||||
})
|
||||
|
||||
self._load_config(config,
|
||||
firmware_cfg['config_files'],
|
||||
context_input,
|
||||
context_output,
|
||||
context_routine)
|
||||
|
||||
if self._boot_page is None:
|
||||
raise self.printer.config_error("No boot page found")
|
||||
if self._timeout_page is None:
|
||||
self._timeout_page = self._boot_page
|
||||
if self._shutdown_page is None:
|
||||
self._shutdown_page = self._boot_page
|
||||
|
||||
self.mcu.register_config_callback(self._build_config)
|
||||
|
||||
self._update_timer = self.reactor.register_timer(self._send_update)
|
||||
self._ping_timer = self.reactor.register_timer(self._do_ping)
|
||||
|
||||
self.gcode.register_command(
|
||||
'DGUS_ABORT_PAGE_SWITCH', self.cmd_DGUS_ABORT_PAGE_SWITCH)
|
||||
self.gcode.register_command(
|
||||
'DGUS_PLAY_SOUND', self.cmd_DGUS_PLAY_SOUND)
|
||||
self.gcode.register_command(
|
||||
'DGUS_PRINT_START', self.cmd_DGUS_PRINT_START)
|
||||
self.gcode.register_command(
|
||||
'DGUS_PRINT_END', self.cmd_DGUS_PRINT_END)
|
||||
self.gcode.register_command('M73', self.cmd_M73)
|
||||
self.gcode.register_command('M117', self.cmd_M117)
|
||||
self.gcode.register_command('M300', self.cmd_M300)
|
||||
|
||||
self.printer.register_event_handler("klippy:ready",
|
||||
self._handle_ready)
|
||||
self.printer.register_event_handler("klippy:shutdown",
|
||||
self._handle_shutdown)
|
||||
self.printer.register_event_handler("klippy:disconnect",
|
||||
self._handle_disconnect)
|
||||
|
||||
def _load_config(self, config, fnames, ctx_in, ctx_out, ctx_routine):
|
||||
if type(fnames) is not list:
|
||||
fnames = [fnames]
|
||||
v_list = config.get_prefix_sections('t5uid1_var ')
|
||||
v_main_names = { c.get_name(): 1 for c in v_list }
|
||||
p_list = config.get_prefix_sections('t5uid1_page ')
|
||||
p_main_names = { c.get_name(): 1 for c in p_list }
|
||||
r_list = config.get_prefix_sections('t5uid1_routine ')
|
||||
r_main_names = { c.get_name(): 1 for c in r_list }
|
||||
for fname in fnames:
|
||||
filepath = os.path.join(os.path.dirname(__file__),
|
||||
self._firmware,
|
||||
fname)
|
||||
try:
|
||||
dconfig = self.configfile.read_config(filepath)
|
||||
except Exception:
|
||||
raise self.printer.config_error("Cannot load config '%s'"
|
||||
% (filepath,))
|
||||
v_list += [c for c in dconfig.get_prefix_sections('t5uid1_var ')
|
||||
if c.get_name() not in v_main_names]
|
||||
p_list += [c for c in dconfig.get_prefix_sections('t5uid1_page ')
|
||||
if c.get_name() not in p_main_names]
|
||||
r_list += [c for c in dconfig.get_prefix_sections('t5uid1_routine ')
|
||||
if c.get_name() not in r_main_names]
|
||||
for c in v_list:
|
||||
v = var.T5UID1_Var(self._gcode_macro,
|
||||
ctx_in,
|
||||
ctx_out,
|
||||
c)
|
||||
if v.name in self._vars:
|
||||
raise self.printer.config_error("t5uid1_var '%s' already"
|
||||
" exists" % (v.name,))
|
||||
self._vars[v.name] = v
|
||||
for c in p_list:
|
||||
p = page.T5UID1_Page(self._vars.keys(), c)
|
||||
if p.name in self._pages:
|
||||
raise self.printer.config_error("t5uid1_page '%s' already"
|
||||
" exists" % (p.name,))
|
||||
self._pages[p.name] = p
|
||||
if p.is_boot:
|
||||
if self._boot_page is None:
|
||||
self._boot_page = p.name
|
||||
else:
|
||||
raise self.printer.config_error("Multiple boot pages"
|
||||
" found")
|
||||
if p.is_timeout:
|
||||
if self._timeout_page is None:
|
||||
self._timeout_page = p.name
|
||||
else:
|
||||
raise self.printer.config_error("Multiple timeout pages"
|
||||
" found")
|
||||
if p.is_shutdown:
|
||||
if self._shutdown_page is None:
|
||||
self._shutdown_page = p.name
|
||||
else:
|
||||
raise self.printer.config_error("Multiple shutdown pages"
|
||||
" found")
|
||||
for c in r_list:
|
||||
r = routine.T5UID1_Routine(self._gcode_macro,
|
||||
ctx_routine,
|
||||
self._pages.keys(),
|
||||
c)
|
||||
if r.name in self._routines:
|
||||
raise self.printer.config_error("t5uid1_routine '%s' already"
|
||||
" exists" % (r.name,))
|
||||
self._routines[r.name] = r
|
||||
|
||||
def _build_config(self):
|
||||
timeout_command, timeout_data = self.switch_page(self._timeout_page,
|
||||
send=False)
|
||||
timeout_data = "".join(["%02x" % (x,) for x in timeout_data])
|
||||
|
||||
self.mcu.add_config_cmd(
|
||||
"config_t5uid1 oid=%d baud=%d timeout=%d"
|
||||
" timeout_command=%d timeout_data=%s"
|
||||
% (self.oid, self._baud, TIMEOUT_SECS,
|
||||
timeout_command, timeout_data))
|
||||
|
||||
curtime = self.reactor.monotonic()
|
||||
self._last_cmd_time = self.mcu.estimated_print_time(curtime)
|
||||
|
||||
cmd_queue = self.mcu.alloc_command_queue()
|
||||
self._t5uid1_ping_cmd = self.mcu.lookup_command(
|
||||
"t5uid1_ping oid=%c", cq=cmd_queue)
|
||||
self._t5uid1_write_cmd = self.mcu.lookup_command(
|
||||
"t5uid1_write oid=%c command=%c data=%*s", cq=cmd_queue)
|
||||
|
||||
self.mcu.register_response(self._handle_t5uid1_received,
|
||||
"t5uid1_received")
|
||||
|
||||
def _handle_ready(self):
|
||||
has_bltouch = False
|
||||
try:
|
||||
self.printer.lookup_object('bltouch')
|
||||
has_bltouch = True
|
||||
except Exception:
|
||||
pass
|
||||
self._status_data.update({
|
||||
'limits': self.limits(),
|
||||
'has_bltouch': has_bltouch
|
||||
})
|
||||
self._is_connected = True
|
||||
self.reactor.register_timer(self._on_ready, self.reactor.NOW)
|
||||
|
||||
def _on_ready(self, eventtime):
|
||||
if not self._is_connected:
|
||||
return self.reactor.NEVER
|
||||
self._last_cmd_time = self.mcu.estimated_print_time(eventtime)
|
||||
self.t5uid1_command_read(T5UID1_ADDR_VERSION, 1)
|
||||
self.set_brightness(self._brightness)
|
||||
self.switch_page(self._boot_page)
|
||||
if self._boot_sound >= 0:
|
||||
self.play_sound(self._boot_sound, volume=self._volume)
|
||||
else:
|
||||
self.set_volume(self._volume)
|
||||
return self.reactor.NEVER
|
||||
|
||||
def _handle_shutdown(self):
|
||||
msg = getattr(self.mcu, "_shutdown_msg", "").strip()
|
||||
parts = textwrap.wrap(msg, 32)
|
||||
while len(parts) < 4:
|
||||
parts.append("")
|
||||
self.set_variable("line1", parts[0].strip())
|
||||
self.set_variable("line2", parts[1].strip())
|
||||
self.set_variable("line3", parts[2].strip())
|
||||
self.set_variable("line4", parts[3].strip())
|
||||
self.switch_page(self._shutdown_page)
|
||||
if self._notification_sound >= 0:
|
||||
self.play_sound(self._notification_sound)
|
||||
|
||||
def _handle_disconnect(self):
|
||||
self._is_connected = False
|
||||
self._current_page = ""
|
||||
self.reactor.update_timer(self._update_timer, self.reactor.NEVER)
|
||||
self.reactor.update_timer(self._ping_timer, self.reactor.NEVER)
|
||||
|
||||
def _handle_t5uid1_received(self, params):
|
||||
if not self._is_connected:
|
||||
return
|
||||
logging.debug("t5uid1_received %s", params)
|
||||
if params['command'] != T5UID1_CMD_READVAR:
|
||||
return
|
||||
data = bytearray(params['data'])
|
||||
if len(data) < 3:
|
||||
logging.warning("Received invalid T5UID1 message")
|
||||
return
|
||||
address = struct.unpack(">H", data[:2])[0]
|
||||
data_len = data[2] << 1
|
||||
if len(data) < data_len + 3:
|
||||
logging.warning("Received invalid T5UID1 message")
|
||||
return
|
||||
data = data[3:data_len + 3]
|
||||
self.reactor.register_async_callback(
|
||||
(lambda e, s=self, a=address, d=data: s.handle_received(a, d)))
|
||||
|
||||
def handle_received(self, address, data):
|
||||
if not self._is_connected:
|
||||
return
|
||||
if address == T5UID1_ADDR_VERSION and len(data) == 2:
|
||||
self._gui_version = data[0]
|
||||
self._os_version = data[1]
|
||||
return
|
||||
handled = False
|
||||
for name in self._vars:
|
||||
if (self._vars[name].address != address
|
||||
or self._vars[name].type != "input"):
|
||||
continue
|
||||
handled = True
|
||||
try:
|
||||
self._vars[name].data_received(data)
|
||||
except ValueError as e:
|
||||
logging.exception("Exception in '%s' receive handler: %s"
|
||||
% (name, str(e)))
|
||||
except Exception as e:
|
||||
logging.exception("Unhandled exception in '%s' receive"
|
||||
" handler: %s" % (name, str(e)))
|
||||
if not handled:
|
||||
logging.info("Received unhandled T5UID1 message for address %s"
|
||||
% (hex(address),))
|
||||
|
||||
def send_var(self, name):
|
||||
if name not in self._vars:
|
||||
raise Exception("T5UID1_Var '%s' not found" % (name,))
|
||||
return self.t5uid1_command_write(self._vars[name].address,
|
||||
self._vars[name].prepare_data())
|
||||
|
||||
def page_name(self, page_id):
|
||||
if type(page_id) is not int:
|
||||
page_id = int(page_id)
|
||||
for name in self._pages:
|
||||
if self._pages[name].id == page_id:
|
||||
return name
|
||||
raise Exception("T5UID1_Page %d not found" % (page_id,))
|
||||
|
||||
def send_page_vars(self, page=None, complete=False):
|
||||
if page is None:
|
||||
page = self._current_page
|
||||
if page not in self._pages:
|
||||
raise Exception("T5UID1_Page '%s' not found" % (page,))
|
||||
if complete:
|
||||
for var_name in self._pages[page].var:
|
||||
self.send_var(var_name)
|
||||
for var_name in self._pages[page].var_auto:
|
||||
self.send_var(var_name)
|
||||
|
||||
def full_update(self):
|
||||
self.send_page_vars(complete=True)
|
||||
self.reactor.update_timer(self._update_timer,
|
||||
self.reactor.monotonic()
|
||||
+ self._update_interval)
|
||||
|
||||
def start_routine(self, routine):
|
||||
if routine not in self._routines:
|
||||
raise Exception("T5UID1_Routine '%s' not found" % (routine,))
|
||||
if self._routines[routine].trigger != "manual":
|
||||
raise Exception("T5UID1_Routine '%s' cannot be started manually"
|
||||
% (routine,))
|
||||
self._routines[routine].run()
|
||||
|
||||
def stop_routine(self, routine):
|
||||
if routine not in self._routines:
|
||||
raise Exception("T5UID1_Routine '%s' not found" % (routine,))
|
||||
self._routines[routine].stop()
|
||||
|
||||
def _start_page_routines(self, page, trigger):
|
||||
if page not in self._pages:
|
||||
raise Exception("T5UID1_Page '%s' not found" % (page,))
|
||||
results = []
|
||||
for routine in self._routines:
|
||||
if (self._routines[routine].page != page
|
||||
or self._routines[routine].trigger != trigger):
|
||||
continue
|
||||
result = self._routines[routine].run()
|
||||
if result is not None:
|
||||
results.append(result)
|
||||
return all(results)
|
||||
|
||||
def _stop_page_routines(self, page):
|
||||
if page not in self._pages:
|
||||
raise Exception("T5UID1_Page '%s' not found" % (page,))
|
||||
for routine in self._routines:
|
||||
if self._routines[routine].page != page:
|
||||
continue
|
||||
self._routines[routine].stop()
|
||||
|
||||
class sentinel: pass
|
||||
|
||||
def get_variable(self, name, default=sentinel):
|
||||
if name not in self._variable_data:
|
||||
if default is not self.sentinel:
|
||||
return default
|
||||
raise Exception("Variable '%s' not found" % (name,))
|
||||
return self._variable_data[name]
|
||||
|
||||
def set_variable(self, name, value):
|
||||
self._variable_data[name] = value
|
||||
|
||||
def check_paused(self):
|
||||
if not self._is_printing:
|
||||
return
|
||||
if self.pause_resume is None:
|
||||
try:
|
||||
self.pause_resume = self.printer.lookup_object('pause_resume')
|
||||
except Exception:
|
||||
return
|
||||
curtime = self.reactor.monotonic()
|
||||
if self._print_pause_time < 0 and self.pause_resume.is_paused:
|
||||
self._print_pause_time = curtime
|
||||
elif self._print_pause_time >= 0 and not self.pause_resume.is_paused:
|
||||
pause_duration = curtime - self._print_pause_time
|
||||
if pause_duration > 0:
|
||||
self._print_start_time += pause_duration
|
||||
self._print_pause_time = -1
|
||||
|
||||
def get_status(self, eventtime):
|
||||
pages = { p: self._pages[p].id for p in self._pages }
|
||||
res = dict(self._status_data)
|
||||
if not self._is_printing:
|
||||
print_duration = self._print_end_time - self._print_start_time
|
||||
elif self._print_pause_time >= 0:
|
||||
print_duration = self._print_pause_time - self._print_start_time
|
||||
else:
|
||||
print_duration = eventtime - self._print_start_time
|
||||
res.update({
|
||||
'version': self._version,
|
||||
'machine_name': self._machine_name,
|
||||
'gui_version': self._gui_version,
|
||||
'os_version': self._os_version,
|
||||
'notification_sound': self._notification_sound,
|
||||
'page': self._current_page,
|
||||
'volume': self._volume,
|
||||
'brightness': self._brightness,
|
||||
'pages': pages,
|
||||
'control_types': CONTROL_TYPES,
|
||||
'is_printing': self._is_printing,
|
||||
'print_progress': self._print_progress,
|
||||
'print_duration': max(0, print_duration)
|
||||
})
|
||||
return res
|
||||
|
||||
def _send_update(self, eventtime):
|
||||
if not self._is_connected or not self._current_page:
|
||||
return self.reactor.NEVER
|
||||
try:
|
||||
self.send_page_vars(self._current_page, complete=False)
|
||||
except Exception as e:
|
||||
logging.exception("Unhandled exception in update timer: %s"
|
||||
% (name, str(e)))
|
||||
return eventtime + self._update_interval
|
||||
|
||||
def _do_ping(self, eventtime):
|
||||
if not self._is_connected or self._t5uid1_ping_cmd is None:
|
||||
return self.reactor.NEVER
|
||||
print_time = self.mcu.estimated_print_time(eventtime)
|
||||
print_time = max(self._last_cmd_time + CMD_DELAY, print_time)
|
||||
clock = self.mcu.print_time_to_clock(print_time)
|
||||
self._t5uid1_ping_cmd.send([self.oid], minclock=clock)
|
||||
self._last_cmd_time = print_time
|
||||
return eventtime + TIMEOUT_SECS - 2
|
||||
|
||||
def _t5uid1_write(self, command, data, schedule_ping=True):
|
||||
if not self._is_connected or self._t5uid1_write_cmd is None:
|
||||
return
|
||||
curtime = self.reactor.monotonic()
|
||||
print_time = self.mcu.estimated_print_time(curtime)
|
||||
print_time = max(self._last_cmd_time + CMD_DELAY, print_time)
|
||||
clock = self.mcu.print_time_to_clock(print_time)
|
||||
self._t5uid1_write_cmd.send([self.oid, command, list(data)],
|
||||
minclock=clock)
|
||||
self._last_cmd_time = print_time
|
||||
if schedule_ping:
|
||||
self.reactor.update_timer(self._ping_timer,
|
||||
curtime + TIMEOUT_SECS - 2)
|
||||
|
||||
def t5uid1_command_write(self, address, data, send=True):
|
||||
if address < 0 or address > 0xffff:
|
||||
raise ValueError("invalid address")
|
||||
if type(data) is not bytearray:
|
||||
raise ValueError("invalid data")
|
||||
if len(data) < 1 or len(data) > 64 or len(data) % 2 != 0:
|
||||
raise ValueError("invalid data length")
|
||||
command = T5UID1_CMD_WRITEVAR
|
||||
command_data = bytearray([ (address >> 8), (address & 0xff) ])
|
||||
command_data.extend(data)
|
||||
if not send:
|
||||
return (command, command_data)
|
||||
self._t5uid1_write(command, command_data)
|
||||
|
||||
def t5uid1_command_read(self, address, wlen, send=True):
|
||||
if address < 0 or address > 0xffff:
|
||||
raise ValueError("invalid address")
|
||||
if wlen < 1 or wlen > 0x7d:
|
||||
raise ValueError("invalid wlen")
|
||||
command = T5UID1_CMD_READVAR
|
||||
command_data = bytearray([ (address >> 8), (address & 0xff), wlen ])
|
||||
if not send:
|
||||
return (command, command_data)
|
||||
self._t5uid1_write(command, command_data)
|
||||
|
||||
def switch_page(self, name, send=True):
|
||||
if name not in self._pages:
|
||||
raise ValueError("invalid page")
|
||||
if not send:
|
||||
return self.t5uid1_command_write(T5UID1_ADDR_PAGE,
|
||||
bytearray([
|
||||
0x5a, 0x01,
|
||||
0x00, self._pages[name].id
|
||||
]),
|
||||
send)
|
||||
if name == self._current_page:
|
||||
return
|
||||
if not self._start_page_routines(name, "enter_pre"):
|
||||
return
|
||||
self.send_page_vars(name, complete=True)
|
||||
self.t5uid1_command_write(T5UID1_ADDR_PAGE,
|
||||
bytearray([
|
||||
0x5a, 0x01,
|
||||
0x00, self._pages[name].id
|
||||
]),
|
||||
send)
|
||||
if self._current_page:
|
||||
self._stop_page_routines(self._current_page)
|
||||
self._start_page_routines(self._current_page, "leave")
|
||||
self._current_page = name
|
||||
self._start_page_routines(name, "enter")
|
||||
self.reactor.update_timer(self._update_timer,
|
||||
self.reactor.monotonic()
|
||||
+ self._update_interval)
|
||||
|
||||
def abort_page_switch(self):
|
||||
return "DGUS_ABORT_PAGE_SWITCH"
|
||||
|
||||
def play_sound(self, start, slen=1, volume=-1, send=True):
|
||||
if start < 0 or start > 255:
|
||||
raise ValueError("invalid start")
|
||||
if slen < 1 or slen > 255:
|
||||
raise ValueError("invalid slen")
|
||||
if volume > 100:
|
||||
raise ValueError("invalid volume")
|
||||
if volume < 0:
|
||||
volume = self._volume
|
||||
val = map_value_range(volume, 0, 100, 0, 255)
|
||||
return self.t5uid1_command_write(T5UID1_ADDR_SOUND,
|
||||
bytearray([start, slen, val, 0]),
|
||||
send)
|
||||
|
||||
def enable_control(self, page, ctype, control, send=True):
|
||||
if page < 0 or page > 255:
|
||||
raise ValueError("invalid page")
|
||||
if ctype < 0 or ctype > 255:
|
||||
raise ValueError("invalid ctype")
|
||||
if control < 0 or control > 255:
|
||||
raise ValueError("invalid control")
|
||||
return self.t5uid1_command_write(T5UID1_ADDR_CONTROL,
|
||||
bytearray([
|
||||
0x5a, 0xa5, 0, page,
|
||||
control, ctype, 0, 0x01
|
||||
]),
|
||||
send)
|
||||
|
||||
def disable_control(self, page, ctype, control, send=True):
|
||||
if page < 0 or page > 255:
|
||||
raise ValueError("invalid page")
|
||||
if ctype < 0 or ctype > 255:
|
||||
raise ValueError("invalid ctype")
|
||||
if control < 0 or control > 255:
|
||||
raise ValueError("invalid control")
|
||||
return self.t5uid1_command_write(T5UID1_ADDR_CONTROL,
|
||||
bytearray([
|
||||
0x5a, 0xa5, 0, page,
|
||||
control, ctype, 0, 0
|
||||
]),
|
||||
send)
|
||||
|
||||
def set_brightness(self, brightness, send=True):
|
||||
if brightness < 0 or brightness > 100:
|
||||
raise ValueError("invalid brightness")
|
||||
val = map_value_range(brightness, 0, 100, 5, 100)
|
||||
result = self.t5uid1_command_write(T5UID1_ADDR_BRIGHTNESS,
|
||||
bytearray([val, val]),
|
||||
send)
|
||||
if not send:
|
||||
return result
|
||||
if self._brightness != brightness:
|
||||
self._brightness = brightness
|
||||
self.configfile.set(self.name, 'brightness', brightness)
|
||||
|
||||
def set_volume(self, volume, send=True):
|
||||
if volume < 0 or volume > 100:
|
||||
raise ValueError("invalid volume")
|
||||
val = map_value_range(volume, 0, 100, 0, 255)
|
||||
result = self.t5uid1_command_write(T5UID1_ADDR_VOLUME,
|
||||
bytearray([val, 0]),
|
||||
send)
|
||||
if not send:
|
||||
return result
|
||||
if self._volume != volume:
|
||||
self._volume = volume
|
||||
self.configfile.set(self.name, 'volume', volume)
|
||||
|
||||
def all_steppers_enabled(self):
|
||||
if self.stepper_enable is None:
|
||||
self.stepper_enable = self.printer.lookup_object('stepper_enable')
|
||||
res = True
|
||||
for name in ['stepper_x', 'stepper_y', 'stepper_z']:
|
||||
res &= self.stepper_enable.lookup_enable(name).is_motor_enabled()
|
||||
return res
|
||||
|
||||
def heater_min_temp(self, heater):
|
||||
if self.heaters is None:
|
||||
self.heaters = self.printer.lookup_object('heaters')
|
||||
try:
|
||||
return self.heaters.lookup_heater(heater).min_temp
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
def heater_max_temp(self, heater, margin=0):
|
||||
if self.heaters is None:
|
||||
self.heaters = self.printer.lookup_object('heaters')
|
||||
try:
|
||||
return max(0, self.heaters.lookup_heater(heater).max_temp - margin)
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
def heater_min_extrude_temp(self, heater):
|
||||
if self.heaters is None:
|
||||
self.heaters = self.printer.lookup_object('heaters')
|
||||
return self.heaters.lookup_heater(heater).min_extrude_temp
|
||||
|
||||
def probed_matrix(self):
|
||||
if self.bed_mesh is None:
|
||||
self.bed_mesh = self.printer.lookup_object('bed_mesh')
|
||||
count = len(self.bed_mesh.bmc.probe_helper.results)
|
||||
points_map = [ 0, 1, 2, 3, 4,
|
||||
9, 8, 7, 6, 5,
|
||||
10, 11, 12, 13, 14,
|
||||
19, 18, 17, 16, 15,
|
||||
20, 21, 22, 23, 24]
|
||||
res = 0
|
||||
for i in range(25):
|
||||
if count > points_map[i]:
|
||||
if i < 16:
|
||||
res |= 1 << (i + 16)
|
||||
else:
|
||||
res |= 1 << (i - 16)
|
||||
return res
|
||||
|
||||
def pid_param(self, heater, param):
|
||||
if param not in ['p', 'i', 'd']:
|
||||
raise ValueError("Invalid param")
|
||||
if self.heaters is None:
|
||||
self.heaters = self.printer.lookup_object('heaters')
|
||||
try:
|
||||
return getattr(self.heaters.lookup_heater(heater).control,
|
||||
'K' + param) * heaters.PID_PARAM_BASE
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
def limit_extrude(self, extruder, val):
|
||||
try:
|
||||
if extruder in self.extruders:
|
||||
res = self.extruders[extruder].max_e_dist
|
||||
else:
|
||||
e = self.printer.lookup_object(extruder)
|
||||
res = e.max_e_dist
|
||||
self.extruders[extruder] = e
|
||||
return min(res, val)
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
def limits(self):
|
||||
if self.toolhead is None:
|
||||
self.toolhead = self.printer.lookup_object('toolhead')
|
||||
kin = self.toolhead.get_kinematics()
|
||||
x_min, x_max = kin.rails[0].get_range()
|
||||
y_min, y_max = kin.rails[1].get_range()
|
||||
z_min, z_max = kin.rails[2].get_range()
|
||||
if (self._z_min is not None
|
||||
and self._z_min > z_min
|
||||
and self._z_min < z_max):
|
||||
z_min = self._z_min
|
||||
if (self._z_max is not None
|
||||
and self._z_max < z_max
|
||||
and self._z_max > z_min):
|
||||
z_max = self._z_max
|
||||
return {
|
||||
'x_min': x_min,
|
||||
'x_max': x_max,
|
||||
'y_min': y_min,
|
||||
'y_max': y_max,
|
||||
'z_min': z_min,
|
||||
'z_max': z_max
|
||||
}
|
||||
|
||||
def set_message(self, message):
|
||||
self.set_variable('message', message)
|
||||
if 'message' in self._vars:
|
||||
self.send_var('message')
|
||||
if len(message) > 0 and 'message_timeout' in self._routines:
|
||||
self.start_routine('message_timeout')
|
||||
|
||||
def is_busy(self):
|
||||
if self.toolhead is None:
|
||||
self.toolhead = self.printer.lookup_object('toolhead')
|
||||
if self.probe is None:
|
||||
self.probe = self.printer.lookup_object('probe')
|
||||
eventtime = self.reactor.monotonic()
|
||||
print_time, est_print_time, lookahead_empty = self.toolhead.check_busy(
|
||||
eventtime)
|
||||
idle_time = est_print_time - print_time
|
||||
return (not lookahead_empty
|
||||
or idle_time < 1.0
|
||||
or self.gcode.get_mutex().test()
|
||||
or self.probe.multi_probe_pending)
|
||||
|
||||
def cmd_DGUS_ABORT_PAGE_SWITCH(self, gcmd):
|
||||
pass
|
||||
|
||||
def cmd_DGUS_PLAY_SOUND(self, gcmd):
|
||||
if self._notification_sound >= 0:
|
||||
start = gcmd.get_int('START', self._notification_sound,
|
||||
minval=0, maxval=255)
|
||||
else:
|
||||
start = gcmd.get_int('START', minval=0, maxval=255)
|
||||
slen = gcmd.get_int('LEN', 1, minval=0, maxval=255)
|
||||
volume = gcmd.get_int('VOLUME', -1, minval=0, maxval=100)
|
||||
try:
|
||||
self.play_sound(start, slen, volume)
|
||||
except Exception as e:
|
||||
raise gcmd.error(str(e))
|
||||
gcmd.respond_info("Playing sound %d (len=%d, volume=%d)"
|
||||
% (start, slen, volume))
|
||||
|
||||
def cmd_DGUS_PRINT_START(self, gcmd):
|
||||
self._print_progress = 0
|
||||
self._print_start_time = self.reactor.monotonic()
|
||||
self._print_pause_time = -1
|
||||
self._print_end_time = -1
|
||||
self._is_printing = True
|
||||
self.check_paused()
|
||||
if 'print_start' in self._routines:
|
||||
self.start_routine('print_start')
|
||||
|
||||
def cmd_DGUS_PRINT_END(self, gcmd):
|
||||
if not self._is_printing:
|
||||
return
|
||||
self._print_progress = 100
|
||||
curtime = self.reactor.monotonic()
|
||||
if self._print_pause_time >= 0:
|
||||
pause_duration = curtime - self._print_pause_time
|
||||
if pause_duration > 0:
|
||||
self._print_start_time += pause_duration
|
||||
self._print_pause_time = -1
|
||||
self._print_end_time = curtime
|
||||
self._is_printing = False
|
||||
if 'print_end' in self._routines:
|
||||
self.start_routine('print_end')
|
||||
|
||||
def cmd_M73(self, gcmd):
|
||||
progress = gcmd.get_int('P', 0)
|
||||
self._print_progress = min(100, max(0, progress))
|
||||
|
||||
def cmd_M117(self, gcmd):
|
||||
msg = gcmd.get_commandline()
|
||||
umsg = msg.upper()
|
||||
if not umsg.startswith('M117'):
|
||||
start = umsg.find('M117')
|
||||
end = msg.rfind('*')
|
||||
msg = msg[start:end]
|
||||
if len(msg) > 5:
|
||||
self.set_message(msg[5:])
|
||||
else:
|
||||
self.set_message("")
|
||||
|
||||
def cmd_M300(self, gcmd):
|
||||
if self._notification_sound >= 0:
|
||||
start = gcmd.get_int('S', self._notification_sound)
|
||||
else:
|
||||
start = gcmd.get_int('S', minval=0, maxval=255)
|
||||
slen = gcmd.get_int('P', 1, minval=1, maxval=255)
|
||||
volume = gcmd.get_int('V', -1, minval=0, maxval=100)
|
||||
if start < 0 or start > 255:
|
||||
start = self._notification_sound
|
||||
try:
|
||||
self.play_sound(start, slen, volume)
|
||||
except Exception as e:
|
||||
raise gcmd.error(str(e))
|
||||
|
||||
def load_config(config):
|
||||
return T5UID1(config)
|
|
@ -0,0 +1,154 @@
|
|||
# Variable class
|
||||
#
|
||||
# Copyright (C) 2020 Desuuuu <contact@desuuuu.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import struct
|
||||
|
||||
TYPES_LEN = {
|
||||
'int16': 2,
|
||||
'uint16': 2,
|
||||
'int32': 4,
|
||||
'uint32': 4,
|
||||
'float': 4
|
||||
}
|
||||
|
||||
TYPES_FMT = {
|
||||
'int16': '>h',
|
||||
'uint16': '>H',
|
||||
'int32': '>i',
|
||||
'uint32': '>I',
|
||||
'float': '>f'
|
||||
}
|
||||
|
||||
class T5UID1_Var:
|
||||
def __init__(self, gcode_macro, input_context, output_context, config):
|
||||
self.printer = config.get_printer()
|
||||
|
||||
self.gcode = self.printer.lookup_object('gcode')
|
||||
|
||||
name_parts = config.get_name().split()
|
||||
if len(name_parts) != 2:
|
||||
raise config.error("Section name '%s' is not valid"
|
||||
% (config.get_name(),))
|
||||
self.name = name_parts[1]
|
||||
|
||||
self.type = config.get('type')
|
||||
if self.type not in ["input", "output"]:
|
||||
raise config.error("Invalid type '%s' in section '%s'"
|
||||
% (self.type, config.get_name()))
|
||||
|
||||
address = config.get('address')
|
||||
try:
|
||||
self.address = int(address, 16)
|
||||
if self.address < 0x1000 or self.address > 0xffff:
|
||||
raise
|
||||
except:
|
||||
raise config.error("Invalid address '%s' in section '%s'"
|
||||
% (address, config.get_name()))
|
||||
|
||||
data_types = TYPES_LEN.keys()
|
||||
data_types.append('str')
|
||||
if self.type == "input":
|
||||
data_types.append('none')
|
||||
|
||||
self.data_type = config.get('data_type')
|
||||
if (self.data_type.startswith('array[')
|
||||
and self.data_type.endswith(']')
|
||||
and self.type == "output"
|
||||
and self.data_type != "str"):
|
||||
self.data_type = self.data_type[6:-1]
|
||||
self.array_len = config.getint('array_len', minval=2, maxval=32)
|
||||
else:
|
||||
self.array_len = 1
|
||||
if self.data_type not in data_types:
|
||||
raise config.error("Invalid data_type '%s' in section '%s'"
|
||||
% (self.data_type, config.get_name()))
|
||||
|
||||
if self.data_type == "none":
|
||||
self.data_len = 0
|
||||
elif self.data_type == "str":
|
||||
self.data_len = config.getint('data_len', minval=1, maxval=32)
|
||||
else:
|
||||
self.data_len = TYPES_LEN[self.data_type]
|
||||
|
||||
if self.type == "input":
|
||||
self._template = gcode_macro.load_template(config, 'script')
|
||||
self._context = input_context
|
||||
self.run_as_gcode = config.getboolean('run_as_gcode', False)
|
||||
elif self.type == "output":
|
||||
self._template = gcode_macro.load_template(config, 'script')
|
||||
self._context = output_context
|
||||
self.run_as_gcode = False
|
||||
|
||||
def data_received(self, data):
|
||||
if self.type != "input":
|
||||
raise Exception("not an input")
|
||||
|
||||
swrap = self._template.create_status_wrapper()
|
||||
context = { 'printer': swrap }
|
||||
context.update(self._context)
|
||||
|
||||
if self.data_type != "none" and self.data_len != 0:
|
||||
received_len = len(data)
|
||||
if self.data_type == "str":
|
||||
buf = bytearray()
|
||||
for i in range(received_len):
|
||||
if i >= self.data_len:
|
||||
break
|
||||
if data[i] == 0x00:
|
||||
break
|
||||
if (i + 1 < received_len
|
||||
and data[i] == 0xff and data[i + 1] == 0xff):
|
||||
break
|
||||
buf.append(data[i])
|
||||
data = str(buf.decode('ascii'))
|
||||
elif received_len != self.data_len:
|
||||
raise ValueError("Expected %d bytes, got %d"
|
||||
% (self.data_len, received_len))
|
||||
else:
|
||||
data = struct.unpack(TYPES_FMT[self.data_type], data)[0]
|
||||
context.update({ 'data': data })
|
||||
|
||||
result = self._template.render(context).strip()
|
||||
if self.run_as_gcode and len(result) > 0:
|
||||
self.gcode.run_script_from_command(result)
|
||||
|
||||
def prepare_data(self):
|
||||
if self.type != "output":
|
||||
raise Exception("not an output")
|
||||
|
||||
swrap = self._template.create_status_wrapper()
|
||||
context = { 'printer': swrap }
|
||||
context.update(self._context)
|
||||
result = self._template.render(context)
|
||||
|
||||
if self.data_type == "str":
|
||||
result = bytearray(result.replace('\n', ''))
|
||||
target_len = self.data_len
|
||||
if target_len % 2 != 0:
|
||||
target_len += 1
|
||||
extra_bytes = len(result) - target_len
|
||||
if extra_bytes > 0:
|
||||
result = result[:target_len]
|
||||
elif extra_bytes < 0:
|
||||
result.extend([0] * abs(extra_bytes))
|
||||
else:
|
||||
parts = result.strip().split(',')
|
||||
result = bytearray()
|
||||
count = 0
|
||||
for part in parts:
|
||||
part = part.strip()
|
||||
if len(part) == 0:
|
||||
continue
|
||||
if self.data_type == "float":
|
||||
part = float(part)
|
||||
else:
|
||||
part = int(part)
|
||||
result.extend(struct.pack(TYPES_FMT[self.data_type], part))
|
||||
count += 1
|
||||
if count != self.array_len:
|
||||
raise ValueError("Expected %d values, got %d"
|
||||
% (self.array_len, count))
|
||||
|
||||
return result
|
|
@ -102,6 +102,34 @@ config AVR_STACK_SIZE
|
|||
config AVR_WATCHDOG
|
||||
bool
|
||||
default y
|
||||
config T5UID1_SERIAL
|
||||
depends on MACH_atmega2560
|
||||
bool "Enable DGUS T5UID1 screen"
|
||||
default n
|
||||
choice
|
||||
depends on T5UID1_SERIAL
|
||||
prompt "Screen Serial Port" if LOW_LEVEL_OPTIONS
|
||||
default T5UID1_SERIAL_UART2
|
||||
help
|
||||
Select the serial device to use for the touchscreen.
|
||||
config T5UID1_SERIAL_UART0
|
||||
bool "UART0"
|
||||
config T5UID1_SERIAL_UART1
|
||||
bool "UART1"
|
||||
config T5UID1_SERIAL_UART2
|
||||
bool "UART2"
|
||||
config T5UID1_SERIAL_UART3
|
||||
bool "UART3"
|
||||
endchoice
|
||||
|
||||
config T5UID1_SERIAL_PORT
|
||||
depends on T5UID1_SERIAL
|
||||
int
|
||||
default 3 if T5UID1_SERIAL_UART3
|
||||
default 1 if T5UID1_SERIAL_UART1
|
||||
default 0 if T5UID1_SERIAL_UART0
|
||||
default 2
|
||||
|
||||
config USBSERIAL
|
||||
bool "Use USB for communication (instead of serial)"
|
||||
depends on MACH_at90usb1286 || MACH_at90usb646 || MACH_atmega32u4
|
||||
|
|
|
@ -17,6 +17,8 @@ src-$(CONFIG_HAVE_GPIO_HARD_PWM) += avr/hard_pwm.c
|
|||
src-$(CONFIG_AVR_WATCHDOG) += avr/watchdog.c
|
||||
src-$(CONFIG_USBSERIAL) += avr/usbserial.c generic/usb_cdc.c
|
||||
src-$(CONFIG_SERIAL) += avr/serial.c generic/serial_irq.c
|
||||
src-$(CONFIG_T5UID1_SERIAL) += avr/serial_t5uid1.c
|
||||
src-$(CONFIG_T5UID1_SERIAL) += generic/t5uid1_irq.c
|
||||
|
||||
# Suppress broken "misspelled signal handler" warnings on gcc 4.8.1
|
||||
CFLAGS_klipper.elf := $(CFLAGS_klipper.elf) $(if $(filter 4.8.1, $(shell $(CC) -dumpversion)), -w)
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
// AVR serial port code.
|
||||
//
|
||||
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <avr/interrupt.h> // USART_RX_vect
|
||||
#include "autoconf.h" // CONFIG_T5UID1_SERIAL_PORT
|
||||
#include "board/t5uid1_irq.h" // t5uid1_rx_byte
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "sched.h" // DECL_INIT
|
||||
|
||||
#if CONFIG_T5UID1_SERIAL_PORT == CONFIG_SERIAL_PORT
|
||||
#error "The serial port selected for the T5UID1 screen is already used"
|
||||
#endif
|
||||
|
||||
// Reserve serial pins
|
||||
#if CONFIG_T5UID1_SERIAL_PORT == 0
|
||||
#if CONFIG_MACH_atmega1280 || CONFIG_MACH_atmega2560
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "PE0,PE1");
|
||||
#else
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "PD0,PD1");
|
||||
#endif
|
||||
#elif CONFIG_T5UID1_SERIAL_PORT == 1
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "PD2,PD3");
|
||||
#elif CONFIG_T5UID1_SERIAL_PORT == 2
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "PH0,PH1");
|
||||
#else
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "PJ0,PJ1");
|
||||
#endif
|
||||
|
||||
// Helper macros for defining serial port aliases
|
||||
#define AVR_SERIAL_REG1(prefix, id, suffix) prefix ## id ## suffix
|
||||
#define AVR_SERIAL_REG(prefix, id, suffix) AVR_SERIAL_REG1(prefix, id, suffix)
|
||||
|
||||
// Serial port register aliases
|
||||
#define UCSRxA AVR_SERIAL_REG(UCSR, CONFIG_T5UID1_SERIAL_PORT, A)
|
||||
#define UCSRxB AVR_SERIAL_REG(UCSR, CONFIG_T5UID1_SERIAL_PORT, B)
|
||||
#define UCSRxC AVR_SERIAL_REG(UCSR, CONFIG_T5UID1_SERIAL_PORT, C)
|
||||
#define UBRRx AVR_SERIAL_REG(UBRR, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define UDRx AVR_SERIAL_REG(UDR, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define UCSZx1 AVR_SERIAL_REG(UCSZ, CONFIG_T5UID1_SERIAL_PORT, 1)
|
||||
#define UCSZx0 AVR_SERIAL_REG(UCSZ, CONFIG_T5UID1_SERIAL_PORT, 0)
|
||||
#define U2Xx AVR_SERIAL_REG(U2X, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define RXENx AVR_SERIAL_REG(RXEN, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define TXENx AVR_SERIAL_REG(TXEN, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define RXCIEx AVR_SERIAL_REG(RXCIE, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
#define UDRIEx AVR_SERIAL_REG(UDRIE, CONFIG_T5UID1_SERIAL_PORT,)
|
||||
|
||||
#if defined(USART_RX_vect)
|
||||
// The atmega168 / atmega328 doesn't have an ID in the irq names
|
||||
#define USARTx_RX_vect USART_RX_vect
|
||||
#define USARTx_UDRE_vect USART_UDRE_vect
|
||||
#else
|
||||
#define USARTx_RX_vect \
|
||||
AVR_SERIAL_REG(USART, CONFIG_T5UID1_SERIAL_PORT, _RX_vect)
|
||||
#define USARTx_UDRE_vect \
|
||||
AVR_SERIAL_REG(USART, CONFIG_T5UID1_SERIAL_PORT, _UDRE_vect)
|
||||
#endif
|
||||
|
||||
void
|
||||
t5uid1_init(uint32_t baud)
|
||||
{
|
||||
UCSRxA = CONFIG_SERIAL_BAUD_U2X ? (1<<U2Xx) : 0;
|
||||
uint32_t cm = CONFIG_SERIAL_BAUD_U2X ? 8 : 16;
|
||||
UBRRx = DIV_ROUND_CLOSEST(CONFIG_CLOCK_FREQ, cm * baud) - 1UL;
|
||||
UCSRxC = (1<<UCSZx1) | (1<<UCSZx0);
|
||||
UCSRxB = (1<<RXENx) | (1<<TXENx) | (1<<RXCIEx) | (1<<UDRIEx);
|
||||
}
|
||||
|
||||
// Rx interrupt - data available to be read.
|
||||
ISR(USARTx_RX_vect)
|
||||
{
|
||||
t5uid1_rx_byte(UDRx);
|
||||
}
|
||||
|
||||
// Tx interrupt - data can be written to serial.
|
||||
ISR(USARTx_UDRE_vect)
|
||||
{
|
||||
uint8_t data;
|
||||
int ret = t5uid1_get_tx_byte(&data);
|
||||
if (ret)
|
||||
UCSRxB &= ~(1<<UDRIEx);
|
||||
else
|
||||
UDRx = data;
|
||||
}
|
||||
|
||||
// Enable tx interrupts
|
||||
void
|
||||
t5uid1_enable_tx_irq(void)
|
||||
{
|
||||
UCSRxB |= 1<<UDRIEx;
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
// Generic interrupt based serial uart helper code
|
||||
//
|
||||
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <string.h> // memmove
|
||||
#include "basecmd.h" // oid_alloc
|
||||
#include "board/io.h" // readb
|
||||
#include "board/irq.h" // irq_save
|
||||
#include "board/misc.h" // timer_read_time
|
||||
#include "command.h" // DECL_CONSTANT
|
||||
#include "sched.h" // sched_wake_task
|
||||
#include "t5uid1_irq.h" // t5uid1_enable_tx_irq
|
||||
|
||||
#define T5UID1_HEADER1 0x5A
|
||||
#define T5UID1_HEADER2 0xA5
|
||||
#define T5UID1_HEADER_LEN 3
|
||||
|
||||
#define RX_BUFFER_SIZE 192
|
||||
#define TIMER_MS 500
|
||||
|
||||
struct t5uid1 {
|
||||
struct timer timer;
|
||||
uint32_t baud;
|
||||
uint16_t ticks;
|
||||
uint16_t timeout;
|
||||
uint8_t timeout_command;
|
||||
uint8_t timeout_data_len;
|
||||
uint8_t timeout_data[];
|
||||
};
|
||||
|
||||
static uint8_t receive_buf[RX_BUFFER_SIZE], receive_pos;
|
||||
static uint8_t transmit_buf[96], transmit_pos, transmit_max;
|
||||
|
||||
static struct task_wake t5uid1_wake;
|
||||
|
||||
void
|
||||
t5uid1_send_command(uint_fast8_t command, uint8_t *data, uint_fast8_t data_len)
|
||||
{
|
||||
if (data_len < 1)
|
||||
return;
|
||||
|
||||
// Verify space for message
|
||||
uint_fast8_t tpos = readb(&transmit_pos), tmax = readb(&transmit_max);
|
||||
if (tpos >= tmax) {
|
||||
tpos = tmax = 0;
|
||||
writeb(&transmit_max, 0);
|
||||
writeb(&transmit_pos, 0);
|
||||
}
|
||||
uint_fast8_t msglen = T5UID1_HEADER_LEN + 1 + data_len;
|
||||
if (tmax + msglen > sizeof(transmit_buf)) {
|
||||
if (tmax + msglen - tpos > sizeof(transmit_buf))
|
||||
// Not enough space for message
|
||||
return;
|
||||
// Disable TX irq and move buffer
|
||||
writeb(&transmit_max, 0);
|
||||
tpos = readb(&transmit_pos);
|
||||
tmax -= tpos;
|
||||
memmove(&transmit_buf[0], &transmit_buf[tpos], tmax);
|
||||
writeb(&transmit_pos, 0);
|
||||
writeb(&transmit_max, tmax);
|
||||
t5uid1_enable_tx_irq();
|
||||
}
|
||||
|
||||
// Generate message
|
||||
transmit_buf[tmax] = T5UID1_HEADER1;
|
||||
transmit_buf[tmax + 1] = T5UID1_HEADER2;
|
||||
transmit_buf[tmax + 2] = data_len + 1;
|
||||
transmit_buf[tmax + 3] = command;
|
||||
memcpy(&transmit_buf[tmax + 4], data, data_len);
|
||||
|
||||
// Start message transmit
|
||||
writeb(&transmit_max, tmax + msglen);
|
||||
t5uid1_enable_tx_irq();
|
||||
}
|
||||
|
||||
static uint_fast8_t
|
||||
t5uid1_timeout_event(struct timer *timer)
|
||||
{
|
||||
struct t5uid1 *t = container_of(timer, struct t5uid1, timer);
|
||||
if (++t->ticks >= t->timeout) {
|
||||
if (t->timeout) {
|
||||
t5uid1_send_command(t->timeout_command,
|
||||
t->timeout_data, t->timeout_data_len);
|
||||
}
|
||||
t->ticks = UINT16_MAX;
|
||||
return SF_DONE;
|
||||
}
|
||||
t->timer.waketime += timer_from_us(TIMER_MS * 1000);
|
||||
return SF_RESCHEDULE;
|
||||
}
|
||||
|
||||
void
|
||||
reset_timer(struct t5uid1 *t)
|
||||
{
|
||||
if (!t->timeout) {
|
||||
sched_del_timer(&t->timer);
|
||||
} else if (t->ticks == UINT16_MAX) {
|
||||
sched_del_timer(&t->timer);
|
||||
uint32_t now = timer_read_time();
|
||||
t->timer.waketime = now + timer_from_us(TIMER_MS * 1000);
|
||||
t->timer.func = t5uid1_timeout_event;
|
||||
if (!timer_is_before(t->timer.waketime, now)) {
|
||||
t->ticks = 0;
|
||||
sched_add_timer(&t->timer);
|
||||
}
|
||||
} else {
|
||||
t->ticks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
command_config_t5uid1(uint32_t *args)
|
||||
{
|
||||
uint8_t timeout_data_len = args[4];
|
||||
struct t5uid1 *t = oid_alloc(
|
||||
args[0], command_config_t5uid1, sizeof(*t) + timeout_data_len);
|
||||
t->baud = args[1];
|
||||
t->ticks = UINT16_MAX;
|
||||
t->timeout = args[2] * (1000 / TIMER_MS);
|
||||
t->timeout_command = args[3];
|
||||
t->timeout_data_len = timeout_data_len;
|
||||
uint8_t *timeout_data = (void*)(size_t)args[5];
|
||||
memcpy(t->timeout_data, timeout_data, timeout_data_len);
|
||||
t5uid1_init(t->baud);
|
||||
reset_timer(t);
|
||||
}
|
||||
DECL_COMMAND(command_config_t5uid1,
|
||||
"config_t5uid1 oid=%c baud=%u timeout=%hu"
|
||||
" timeout_command=%c timeout_data=%*s");
|
||||
|
||||
void
|
||||
command_t5uid1_ping(uint32_t *args)
|
||||
{
|
||||
struct t5uid1 *t = oid_lookup(args[0], command_config_t5uid1);
|
||||
reset_timer(t);
|
||||
}
|
||||
DECL_COMMAND_FLAGS(command_t5uid1_ping, HF_IN_SHUTDOWN,
|
||||
"t5uid1_ping oid=%c");
|
||||
|
||||
void
|
||||
command_t5uid1_write(uint32_t *args)
|
||||
{
|
||||
struct t5uid1 *t = oid_lookup(args[0], command_config_t5uid1);
|
||||
uint_fast8_t command = args[1];
|
||||
uint_fast8_t data_len = args[2];
|
||||
uint8_t *data = (void*)(size_t)args[3];
|
||||
t5uid1_send_command(command, data, data_len);
|
||||
reset_timer(t);
|
||||
}
|
||||
DECL_COMMAND_FLAGS(command_t5uid1_write, HF_IN_SHUTDOWN,
|
||||
"t5uid1_write oid=%c command=%c data=%*s");
|
||||
|
||||
// Rx interrupt - store read data
|
||||
void
|
||||
t5uid1_rx_byte(uint_fast8_t data)
|
||||
{
|
||||
if (receive_pos > T5UID1_HEADER_LEN)
|
||||
sched_wake_task(&t5uid1_wake);
|
||||
if (receive_pos >= sizeof(receive_buf))
|
||||
// Serial overflow - ignore it
|
||||
return;
|
||||
receive_buf[receive_pos++] = data;
|
||||
}
|
||||
|
||||
// Tx interrupt - get next byte to transmit
|
||||
int
|
||||
t5uid1_get_tx_byte(uint8_t *pdata)
|
||||
{
|
||||
if (transmit_pos >= transmit_max)
|
||||
return -1;
|
||||
*pdata = transmit_buf[transmit_pos++];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Remove from the receive buffer the given number of bytes
|
||||
static void
|
||||
t5uid1_pop_input(uint_fast8_t len)
|
||||
{
|
||||
uint_fast8_t copied = 0;
|
||||
for (;;) {
|
||||
uint_fast8_t rpos = readb(&receive_pos);
|
||||
uint_fast8_t needcopy = rpos - len;
|
||||
if (needcopy) {
|
||||
memmove(&receive_buf[copied], &receive_buf[copied + len]
|
||||
, needcopy - copied);
|
||||
copied = needcopy;
|
||||
sched_wake_task(&t5uid1_wake);
|
||||
}
|
||||
irqstatus_t flag = irq_save();
|
||||
if (rpos != readb(&receive_pos)) {
|
||||
// Raced with irq handler - retry
|
||||
irq_restore(flag);
|
||||
continue;
|
||||
}
|
||||
receive_pos = needcopy;
|
||||
irq_restore(flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the next command
|
||||
int_fast8_t
|
||||
t5uid1_find_command(uint8_t *buf, uint_fast8_t buf_len, uint_fast8_t *pop_count)
|
||||
{
|
||||
if (buf_len < T5UID1_HEADER_LEN)
|
||||
goto need_more_data;
|
||||
if (buf[0] != T5UID1_HEADER1 || buf[1] != T5UID1_HEADER2)
|
||||
goto error;
|
||||
uint_fast8_t cmdlen = buf[2];
|
||||
if (cmdlen < 2)
|
||||
goto error;
|
||||
if (buf_len - T5UID1_HEADER_LEN < cmdlen)
|
||||
goto need_more_data;
|
||||
*pop_count = T5UID1_HEADER_LEN + cmdlen;
|
||||
return 1;
|
||||
|
||||
need_more_data:
|
||||
*pop_count = 0;
|
||||
return 0;
|
||||
error:
|
||||
*pop_count = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process any incoming commands
|
||||
void
|
||||
t5uid1_task(void)
|
||||
{
|
||||
if (!sched_check_wake(&t5uid1_wake))
|
||||
return;
|
||||
uint_fast8_t rpos = readb(&receive_pos), pop_count;
|
||||
int_fast8_t ret = t5uid1_find_command(receive_buf, rpos, &pop_count);
|
||||
if (ret > 0) {
|
||||
uint_fast8_t command = receive_buf[T5UID1_HEADER_LEN];
|
||||
uint_fast8_t data_len = pop_count - T5UID1_HEADER_LEN - 1;
|
||||
uint8_t *data = &receive_buf[T5UID1_HEADER_LEN + 1];
|
||||
sendf("t5uid1_received command=%c data=%*s", command, data_len, data);
|
||||
}
|
||||
if (ret) {
|
||||
t5uid1_pop_input(pop_count);
|
||||
}
|
||||
}
|
||||
DECL_TASK(t5uid1_task);
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef __GENERIC_T5UID1_IRQ_H
|
||||
#define __GENERIC_T5UID1_IRQ_H
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
|
||||
void t5uid1_init(uint32_t baud);
|
||||
// callback provided by board specific code
|
||||
void t5uid1_enable_tx_irq(void);
|
||||
|
||||
// t5uid1_irq.c
|
||||
void t5uid1_rx_byte(uint_fast8_t data);
|
||||
int t5uid1_get_tx_byte(uint8_t *pdata);
|
||||
|
||||
#endif // t5uid1_irq.h
|
|
@ -68,4 +68,9 @@ config SERIAL
|
|||
bool
|
||||
default y
|
||||
|
||||
config T5UID1_SERIAL
|
||||
depends on USBSERIAL
|
||||
bool "Use UART0 for DGUS T5UID1 screen"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
|
|
@ -22,6 +22,8 @@ src-$(CONFIG_HAVE_GPIO_SPI) += lpc176x/spi.c
|
|||
src-$(CONFIG_USBSERIAL) += lpc176x/usbserial.c lpc176x/chipid.c
|
||||
src-$(CONFIG_USBSERIAL) += generic/usb_cdc.c
|
||||
src-$(CONFIG_SERIAL) += lpc176x/serial.c generic/serial_irq.c
|
||||
src-$(CONFIG_T5UID1_SERIAL) += lpc176x/serial_t5uid1.c
|
||||
src-$(CONFIG_T5UID1_SERIAL) += generic/t5uid1_irq.c
|
||||
|
||||
# Build the additional bin output file
|
||||
target-y += $(OUT)klipper.bin
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
// lpc176x serial port
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include "board/armcm_boot.h" // armcm_enable_irq
|
||||
#include "board/irq.h" // irq_save
|
||||
#include "board/t5uid1_irq.h" // t5uid1_rx_byte
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "internal.h" // gpio_peripheral
|
||||
#include "sched.h" // DECL_INIT
|
||||
|
||||
// Write tx bytes to the serial port
|
||||
static void
|
||||
kick_tx(void)
|
||||
{
|
||||
for (;;) {
|
||||
if (!(LPC_UART0->LSR & (1<<5))) {
|
||||
// Output fifo full - enable tx irq
|
||||
LPC_UART0->IER = 0x03;
|
||||
break;
|
||||
}
|
||||
uint8_t data;
|
||||
int ret = t5uid1_get_tx_byte(&data);
|
||||
if (ret) {
|
||||
// No more data to send - disable tx irq
|
||||
LPC_UART0->IER = 0x01;
|
||||
break;
|
||||
}
|
||||
LPC_UART0->THR = data;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UART0_IRQHandler(void)
|
||||
{
|
||||
uint32_t iir = LPC_UART0->IIR, status = iir & 0x0f;
|
||||
if (status == 0x04)
|
||||
t5uid1_rx_byte(LPC_UART0->RBR);
|
||||
else if (status == 0x02)
|
||||
kick_tx();
|
||||
}
|
||||
|
||||
void
|
||||
t5uid1_enable_tx_irq(void)
|
||||
{
|
||||
if (LPC_UART0->LSR & (1<<5)) {
|
||||
irqstatus_t flag = irq_save();
|
||||
kick_tx();
|
||||
irq_restore(flag);
|
||||
}
|
||||
}
|
||||
|
||||
DECL_CONSTANT_STR("RESERVE_PINS_t5uid1", "P0.3,P0.2");
|
||||
|
||||
void
|
||||
t5uid1_init(uint32_t baud)
|
||||
{
|
||||
// Setup baud
|
||||
LPC_UART0->LCR = (1<<7); // set DLAB bit
|
||||
enable_pclock(PCLK_UART0);
|
||||
uint32_t pclk = SystemCoreClock;
|
||||
uint32_t div = pclk / (baud * 16);
|
||||
LPC_UART0->DLL = div & 0xff;
|
||||
LPC_UART0->DLM = (div >> 8) & 0xff;
|
||||
LPC_UART0->FDR = 0x10;
|
||||
LPC_UART0->LCR = 3; // 8N1 ; clear DLAB bit
|
||||
|
||||
// Enable fifo
|
||||
LPC_UART0->FCR = 0x01;
|
||||
|
||||
// Setup pins
|
||||
gpio_peripheral(GPIO(0, 3), 1, 0);
|
||||
gpio_peripheral(GPIO(0, 2), 1, 0);
|
||||
|
||||
// Enable receive irq
|
||||
armcm_enable_irq(UART0_IRQHandler, UART0_IRQn, 0);
|
||||
LPC_UART0->IER = 0x01;
|
||||
}
|
Loading…
Reference in New Issue