From bd290a69b9f89ceb527f1b6ca8189feb37c590c7 Mon Sep 17 00:00:00 2001 From: Scott Mohekey Date: Mon, 24 Jun 2024 14:03:25 +1200 Subject: [PATCH] Adds support for Discovery machines as well as advanced status and led light strip. (#108) * Added support for Discovery GR machines. * A few small fixes. --- .vscode/launch.json | 99 +++--- CMakeLists.txt | 1 + CMakePresets.json | 236 +++++++++++++-- Configuration.h | 96 +++++- external/eigen | 2 +- samd51p20a_flash.ld | 7 +- src/marlin/MarlinCore.cpp | 10 +- src/marlin/gcode/calibrate/G28.cpp | 14 +- src/marlin/gcode/config/M2000.cpp | 1 - src/marlin/gcode/config/M43.cpp | 7 +- src/marlin/gcode/control/M2001.cpp | 2 +- src/marlin/gcode/control/M3-M5.cpp | 5 +- src/marlin/gcode/gcode.cpp | 65 ++-- src/marlin/gcode/gcode.h | 78 +++-- src/marlin/gcode/host/M115.cpp | 1 + src/marlin/gcode/motion/G0_G1.cpp | 31 +- src/marlin/gcode/motion/G2_G3.cpp | 6 +- src/marlin/gcode/probe/G37.cpp | 8 +- src/marlin/gcode/probe/G38.cpp | 6 +- src/marlin/gcode/queue.cpp | 1 - src/marlin/inc/Conditionals_post.h | 3 +- src/marlin/module/motion.cpp | 68 +++-- src/marlin/module/motion.h | 46 +-- src/marlin/module/planner.cpp | 14 +- src/marlin/module/planner.h | 10 + src/marlin/module/stepper.cpp | 32 +- src/marlin/module/stepper.h | 2 + src/marlin/pins/pinsDebug_list.h | 6 + src/marlin/pins/samd/pins_boardinator.h | 18 +- src/swordfish/Controller.cpp | 214 ++++++------- src/swordfish/Controller.h | 38 ++- src/swordfish/Exception.h | 9 +- src/swordfish/core/Schema.h | 6 +- src/swordfish/debug.h | 2 +- src/swordfish/modules/CMakeLists.txt | 1 + src/swordfish/modules/estop/EStopModule.cpp | 22 +- src/swordfish/modules/estop/EStopModule.h | 2 + .../modules/gcode/CommandException.cpp | 4 +- .../modules/gcode/CommandException.h | 12 +- src/swordfish/modules/motion/MotionModule.cpp | 44 +-- src/swordfish/modules/motion/MotionModule.h | 2 + src/swordfish/modules/status/CmakeLists.txt | 9 + src/swordfish/modules/status/Color.cpp | 207 +++++++++++++ src/swordfish/modules/status/Color.h | 43 +++ src/swordfish/modules/status/StatusModule.cpp | 193 ++++++++++++ src/swordfish/modules/status/StatusModule.h | 104 +++++++ src/swordfish/modules/status/WS2812Driver.cpp | 284 ++++++++++++++++++ src/swordfish/modules/status/WS2812Driver.h | 47 +++ .../modules/tools/DriverParameterDefinition.h | 10 +- src/swordfish/modules/tools/ToolsModule.cpp | 6 +- src/swordfish/types.h | 17 +- 51 files changed, 1740 insertions(+), 411 deletions(-) create mode 100644 src/swordfish/modules/status/CmakeLists.txt create mode 100644 src/swordfish/modules/status/Color.cpp create mode 100644 src/swordfish/modules/status/Color.h create mode 100644 src/swordfish/modules/status/StatusModule.cpp create mode 100644 src/swordfish/modules/status/StatusModule.h create mode 100644 src/swordfish/modules/status/WS2812Driver.cpp create mode 100644 src/swordfish/modules/status/WS2812Driver.h diff --git a/.vscode/launch.json b/.vscode/launch.json index 0f125e129b..ac0a645940 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,37 +1,66 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "cwd": "${workspaceRoot}", - "executable": "${workspaceRoot}/build/Swordfish.elf", - "name": "Debug Swordfish", - "request": "launch", - "type": "cortex-debug", - "servertype": "jlink", - "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", - "armToolchainPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin", - "device": "ATSAMD51P20A", - "interface": "swd", - "serialNumber": "", // add J-Link serial number if having multiple attached the same time. - "runToEntryPoint": "main", - "svdFile": "${workspaceRoot}/ATSAMD51P20A.svd", - "preRestartCommands": [ - "monitor reset" - ], - "rttConfig": { - "enabled": true, - "address": "auto", - // "clearSearch": false // OpenOCD users may have to un-comment this - "decoders": [ - { - "port": 0, - "type": "console" - } - ] - } - } - ] + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "cwd": "${workspaceRoot}", + "executable": "${workspaceRoot}/build/Swordfish.elf", + "name": "Launch Swordfish", + "request": "launch", + "type": "cortex-debug", + "servertype": "jlink", + "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", + "armToolchainPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin", + "device": "ATSAMD51P20A", + "interface": "swd", + "serialNumber": "", // add J-Link serial number if having multiple attached the same time. + "runToEntryPoint": "main", + "svdFile": "${workspaceRoot}/ATSAMD51P20A.svd", + "preRestartCommands": [ + "monitor reset" + ], + "rttConfig": { + "enabled": true, + "address": "auto", + // "clearSearch": false // OpenOCD users may have to un-comment this + "decoders": [ + { + "port": 0, + "type": "console" + } + ] + } + }, + { + "cwd": "${workspaceRoot}", + "executable": "${workspaceRoot}/build/Swordfish.elf", + "name": "Attach Swordfish", + "request": "attach", + "type": "cortex-debug", + "servertype": "jlink", + "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", + "armToolchainPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/10 2021.10/bin", + "device": "ATSAMD51P20A", + "interface": "swd", + "serialNumber": "", // add J-Link serial number if having multiple attached the same time. + "runToEntryPoint": "main", + "svdFile": "${workspaceRoot}/ATSAMD51P20A.svd", + "preRestartCommands": [ + "monitor reset" + ], + "rttConfig": { + "enabled": true, + "address": "auto", + // "clearSearch": false // OpenOCD users may have to un-comment this + "decoders": [ + { + "port": 0, + "type": "console" + } + ] + } + } + ] } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b5624c5710..19e09f5b46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ target_compile_definitions(${PROJECT_NAME}.elf ARDUINOSTL_M_H MACHINE_TYPE=${SWORDFISH_MACHINE_TYPE} MACHINE_NAME=${SWORDFISH_MACHINE_NAME} + INVERT_ENDSTOPS=${SWORDFISH_INVERT_ENDSTOPS} ) target_include_directories(${PROJECT_NAME}.elf diff --git a/CMakePresets.json b/CMakePresets.json index 6971c8bf44..e1d5e6628c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -27,39 +27,133 @@ } }, { - "name": "Debug P1", + "name": "Debug Proteus P1", "inherits": "Debug", - "displayName": "Debug P1", + "displayName": "Debug Proteus P1", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "1", - "SWORDFISH_MACHINE_NAME": "Proteus P1" + "SWORDFISH_MACHINE_NAME": "Proteus P1", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Debug P2", + "name": "Debug Proteus P2", "inherits": "Debug", - "displayName": "Debug P2", + "displayName": "Debug Proteus P2", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "2", - "SWORDFISH_MACHINE_NAME": "Proteus P2" + "SWORDFISH_MACHINE_NAME": "Proteus P2", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Debug P3", + "name": "Debug Proteus P3", "inherits": "Debug", - "displayName": "Debug P3", + "displayName": "Debug Proteus P3", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "3", - "SWORDFISH_MACHINE_NAME": "Proteus P3" + "SWORDFISH_MACHINE_NAME": "Proteus P3", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Debug P4", + "name": "Debug Proteus P4", "inherits": "Debug", - "displayName": "Debug P4", + "displayName": "Debug Proteus P4", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "4", - "SWORDFISH_MACHINE_NAME": "Proteus P4" + "SWORDFISH_MACHINE_NAME": "Proteus P4", + "SWORDFISH_INVERT_ENDSTOPS": true + } + }, + { + "name": "Debug Discovery GR 0303", + "inherits": "Debug", + "displayName": "Debug Discovery GR 0303", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "5", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0303", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Discovery GR 0603", + "inherits": "Debug", + "displayName": "Debug Discovery GR 0603", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "6", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0603", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Discovery GR 0606", + "inherits": "Debug", + "displayName": "Debug Discovery GR 0606", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "7", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0606", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Discovery GR 1206", + "inherits": "Debug", + "displayName": "Debug Discovery GR 1206", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "8", + "SWORDFISH_MACHINE_NAME": "Discovery GR 1206", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Discovery GR 1212", + "inherits": "Debug", + "displayName": "Debug Discovery GR 1212", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "9", + "SWORDFISH_MACHINE_NAME": "Discovery GR 1212", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Venture GR 1313", + "inherits": "Debug", + "displayName": "Debug Venture GR 1313", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "10", + "SWORDFISH_MACHINE_NAME": "Venture GR 1313", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Venture GR 1325", + "inherits": "Debug", + "displayName": "Debug Venture GR 1325", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "11", + "SWORDFISH_MACHINE_NAME": "Venture GR 1325", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Venture GR 1336", + "inherits": "Debug", + "displayName": "Debug Venture GR 1336", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "12", + "SWORDFISH_MACHINE_NAME": "Venture GR 1336", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Debug Venture GR 1836", + "inherits": "Debug", + "displayName": "Debug Venture GR 1836", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "13", + "SWORDFISH_MACHINE_NAME": "Venture GR 1836", + "SWORDFISH_INVERT_ENDSTOPS": false } }, { @@ -73,39 +167,133 @@ } }, { - "name": "Release P1", + "name": "Release Proteus P1", "inherits": "Release", - "displayName": "Release P1", + "displayName": "Release Proteus P1", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "1", - "SWORDFISH_MACHINE_NAME": "Proteus P1" + "SWORDFISH_MACHINE_NAME": "Proteus P1", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Release P2", + "name": "Release Proteus P2", "inherits": "Release", - "displayName": "Release P2", + "displayName": "Release Proteus P2", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "2", - "SWORDFISH_MACHINE_NAME": "Proteus P2" + "SWORDFISH_MACHINE_NAME": "Proteus P2", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Release P3", + "name": "Release Proteus P3", "inherits": "Release", - "displayName": "Release P3", + "displayName": "Release Proteus P3", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "3", - "SWORDFISH_MACHINE_NAME": "Proteus P3" + "SWORDFISH_MACHINE_NAME": "Proteus P3", + "SWORDFISH_INVERT_ENDSTOPS": true } }, { - "name": "Release P4", + "name": "Release Proteus P4", "inherits": "Release", - "displayName": "Release P4", + "displayName": "Release Proteus P4", "cacheVariables": { "SWORDFISH_MACHINE_TYPE": "4", - "SWORDFISH_MACHINE_NAME": "Proteus P4" + "SWORDFISH_MACHINE_NAME": "Proteus P4", + "SWORDFISH_INVERT_ENDSTOPS": true + } + }, + { + "name": "Release Discovery GR 0303", + "inherits": "Release", + "displayName": "Release Discovery GR 0303", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "5", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0303", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Discovery GR 0603", + "inherits": "Release", + "displayName": "Release Discovery GR 0603", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "6", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0603", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Discovery GR 0606", + "inherits": "Release", + "displayName": "Release Discovery GR 0606", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "7", + "SWORDFISH_MACHINE_NAME": "Discovery GR 0606", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Discovery GR 1206", + "inherits": "Release", + "displayName": "Release Discovery GR 1206", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "8", + "SWORDFISH_MACHINE_NAME": "Discovery GR 1206", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Discovery GR 1212", + "inherits": "Release", + "displayName": "Release Discovery GR 1212", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "9", + "SWORDFISH_MACHINE_NAME": "Discovery GR 1212", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Venture GR 1313", + "inherits": "Release", + "displayName": "Release Venture GR 1313", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "10", + "SWORDFISH_MACHINE_NAME": "Venture GR 1313", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Venture GR 1325", + "inherits": "Release", + "displayName": "Release Venture GR 1325", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "11", + "SWORDFISH_MACHINE_NAME": "Venture GR 1325", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Venture GR 1336", + "inherits": "Release", + "displayName": "Release Venture GR 1336", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "12", + "SWORDFISH_MACHINE_NAME": "Venture GR 1336", + "SWORDFISH_INVERT_ENDSTOPS": false + } + }, + { + "name": "Release Venture GR 1836", + "inherits": "Release", + "displayName": "Release Venture GR 1836", + "cacheVariables": { + "SWORDFISH_MACHINE_TYPE": "13", + "SWORDFISH_MACHINE_NAME": "Venture GR 1836", + "SWORDFISH_INVERT_ENDSTOPS": false } } ] diff --git a/Configuration.h b/Configuration.h index 7e4d26ed23..f74d1ef6f0 100644 --- a/Configuration.h +++ b/Configuration.h @@ -685,12 +685,13 @@ #endif // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup). -#define X_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. -#define Y_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. -#define Z_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. -#define X_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. -#define Y_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. -#define Z_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop. +#define X_MIN_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define Y_MIN_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define Z_MIN_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define X_MAX_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define Y_MAX_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define Z_MAX_ENDSTOP_INVERTING INVERT_ENDSTOPS +#define A_MAX_ENDSTOP_INVERTING INVERT_ENDSTOPS #define Z_MIN_PROBE_ENDSTOP_INVERTING true // Set to true to invert the logic of the probe. #define TOOL_PROBE_ENDSTOP_INVERTING true #define WORK_PROBE_ENDSTOP_INVERTING true @@ -777,11 +778,17 @@ * Override with M92 * X, Y, Z, E0 [, E1 [, E2...]] */ +#if MACHINE_TYPE == 10 || MACHINE_TYPE == 11 || MACHINE_TYPE == 12 || MACHINE_TYPE == 13 +#define DEFAULT_AXIS_STEPS_PER_UNIT \ + { \ + 320, 320, 320, 400 \ + } +#else #define DEFAULT_AXIS_STEPS_PER_UNIT \ { \ 400, 400, 400, 400 \ } - +#endif /** * Default Max Feed Rate (mm/s) * Override with M203 @@ -1165,28 +1172,33 @@ #define X_ENABLE_ON 1 #define Y_ENABLE_ON 1 #define Z_ENABLE_ON 1 -#define E_ENABLE_ON 0 // For all extruders +#define A_ENABLE_ON 1 // Disable axis steppers immediately when they're not being stepped. // WARNING: When motors turn off there is a chance of losing position accuracy! #define DISABLE_X false #define DISABLE_Y false #define DISABLE_Z false +#define DISABLE_A false // Turn off the display blinking that warns about possible accuracy reduction // #define DISABLE_REDUCED_ACCURACY_WARNING // @section extruder -#define DISABLE_E false // Disable the extruder when not stepping #define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled // @section machine // Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. #define INVERT_X_DIR false +#if MACHINE_TYPE == 5 || MACHINE_TYPE == 6 || MACHINE_TYPE == 7 || MACHINE_TYPE == 8 || MACHINE_TYPE == 9 +#define INVERT_Y_DIR false +#else #define INVERT_Y_DIR true +#endif #define INVERT_Z_DIR true +#define INVERT_A_DIR false // @section extruder @@ -1202,7 +1214,7 @@ // @section homing -#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. +//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety. // #define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety. // #define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off. @@ -1213,9 +1225,6 @@ // Direction of endstops when homing; 1=MAX, -1=MIN // :[-1,1] -#define X_HOME_DIR -1 -#define Y_HOME_DIR 1 -#define Z_HOME_DIR 1 // @section machine @@ -1223,28 +1232,85 @@ #if MACHINE_TYPE == 1 # define X_BED_SIZE 735 # define Y_BED_SIZE 730 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 #elif MACHINE_TYPE == 2 # define X_BED_SIZE 1355 # define Y_BED_SIZE 730 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 #elif MACHINE_TYPE == 3 # define X_BED_SIZE 1355 # define Y_BED_SIZE 1330 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 #elif MACHINE_TYPE == 4 # define X_BED_SIZE 1355 # define Y_BED_SIZE 2530 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 5 +# define X_BED_SIZE 320 +# define Y_BED_SIZE 320 +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 6 +# define X_BED_SIZE 620 +# define Y_BED_SIZE 320 +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 7 +# define X_BED_SIZE 620 +# define Y_BED_SIZE 620 +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 8 +# define X_BED_SIZE 1220 +# define Y_BED_SIZE 620 +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 9 +# define X_BED_SIZE 1220 +# define Y_BED_SIZE 1220 +#define X_HOME_DIR -1 +#define Y_HOME_DIR -1 +#define Z_HOME_DIR 1 +#elif MACHINE_TYPE == 10 +#define X_BED_SIZE 1300 +#define Y_BED_SIZE 1300 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 #else -# define X_BED_SIZE 1355 -# define Y_BED_SIZE 1330 +# define X_BED_SIZE 1540 +# define Y_BED_SIZE 1500 +#define X_HOME_DIR -1 +#define Y_HOME_DIR 1 +#define Z_HOME_DIR 1 #endif // Travel limits (mm) after homing, corresponding to endstop positions. #define X_MIN_POS 0 #define Y_MIN_POS 0 +#if MACHINE_TYPE == 1 || MACHINE_TYPE == 2 || MACHINE_TYPE == 3 || MACHINE_TYPE == 4 #define Z_MIN_POS -155 +#elif MACHINE_TYPE == 5 || MACHINE_TYPE == 6 || MACHINE_TYPE == 7 || MACHINE_TYPE == 8 || MACHINE_TYPE == 9 || MACHINE_TYPE == 10 +#define Z_MIN_POS -200 +#endif #define X_MAX_POS X_BED_SIZE #define Y_MAX_POS Y_BED_SIZE #define Z_MAX_POS 0 +#define A_MIN_POS 0 + /** * Software Endstops * diff --git a/external/eigen b/external/eigen index a629a26353..15de225a15 160000 --- a/external/eigen +++ b/external/eigen @@ -1 +1 @@ -Subproject commit a629a263530cdc4aa6958b209d4ad761d8e9ecab +Subproject commit 15de225a1529ec961df10b27b6805842c63ed626 diff --git a/samd51p20a_flash.ld b/samd51p20a_flash.ld index 884c8a38b3..4797fe7499 100644 --- a/samd51p20a_flash.ld +++ b/samd51p20a_flash.ld @@ -95,18 +95,19 @@ SECTIONS KEEP(*(.eh_frame*)) } > FLASH - .ARM.extab : + .ARM.extab : ALIGN(8) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > FLASH - .ARM.exidx : + .ARM.exidx : ALIGN(8) { __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; } > FLASH - + + /* To copy multiple ROM to RAM sections, * uncomment .copy.table section and, * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ diff --git a/src/marlin/MarlinCore.cpp b/src/marlin/MarlinCore.cpp index 722f02a5e8..957291cd04 100644 --- a/src/marlin/MarlinCore.cpp +++ b/src/marlin/MarlinCore.cpp @@ -34,6 +34,7 @@ using namespace swordfish; using namespace swordfish::motion; +using namespace swordfish::status; #if ENABLED(MARLIN_DEV_MODE) # warning "WARNING! Disable MARLIN_DEV_MODE for the final build!" @@ -241,7 +242,8 @@ bool wait_for_user; // = false; void wait_for_user_response(millis_t ms /*=0*/, const bool no_sleep /*=false*/) { UNUSED(no_sleep); - KEEPALIVE_STATE(PAUSED_FOR_USER); + TemporaryState state(MachineState::AwaitingInput); + wait_for_user = true; if (ms) ms += millis(); // expire time @@ -746,11 +748,13 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep /*=false*/)) { SERIAL_ECHOLNPAIR("idle() call depth: ", int(idle_depth)); #endif - Controller::getInstance().idle(); - // Core Marlin activities manage_inactivity(TERN_(ADVANCED_PAUSE_FEATURE, no_stepper_sleep)); + Controller::getInstance().idle(); + + //gcode.set_busy_state(NOT_BUSY); + // Manage Heaters (and Watchdog) thermalManager.manage_heater(); diff --git a/src/marlin/gcode/calibrate/G28.cpp b/src/marlin/gcode/calibrate/G28.cpp index e2c1188859..8161bc8625 100644 --- a/src/marlin/gcode/calibrate/G28.cpp +++ b/src/marlin/gcode/calibrate/G28.cpp @@ -37,6 +37,7 @@ using namespace swordfish; using namespace swordfish::tools; using namespace swordfish::motion; +using namespace swordfish::status; #if ENABLED(QUICK_HOME) @@ -182,7 +183,6 @@ void GcodeSuite::G28() { auto& toolsModule = ToolsModule::getInstance(); auto& motionModule = MotionModule::getInstance(); - KEEPALIVE_STATE(HOMING); DEBUG_SECTION(log_G28, "G28", DEBUGGING(LEVELING)); if (DEBUGGING(LEVELING)) log_machine_info(); @@ -200,6 +200,8 @@ void GcodeSuite::G28() { planner.synchronize(); // Wait for planner moves to finish! + TemporaryState temp(MachineState::Homing); + // Disable the leveling matrix before homing #if HAS_LEVELING const bool leveling_restore_state = parser.boolval('L', TERN(RESTORE_LEVELING_AFTER_G28, planner.leveling_active, ENABLED(ENABLE_LEVELING_AFTER_G28))); @@ -232,7 +234,7 @@ void GcodeSuite::G28() { if (homing) { homeaxis(Z_AXIS); } else { - do_blocking_move_to_z(home_dir(Z_AXIS) > 0 ? Z_MAX_POS : Z_MIN_POS); + do_blocking_move_to_z(MachineState::Homing, home_dir(Z_AXIS) > 0 ? Z_MAX_POS : Z_MIN_POS); } } @@ -246,7 +248,7 @@ void GcodeSuite::G28() { // Raise Z before homing any other axes and z is not already high enough (never lower z) if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height); - do_z_clearance(z_homing_height, axis_is_trusted(Z_AXIS), DISABLED(UNKNOWN_Z_NO_RAISE)); + do_z_clearance(MachineState::Homing, z_homing_height, axis_is_trusted(Z_AXIS), DISABLED(UNKNOWN_Z_NO_RAISE)); } #if ENABLED(QUICK_HOME) @@ -291,7 +293,7 @@ void GcodeSuite::G28() { if (homing) { homeaxis(X_AXIS); } else { - do_blocking_move_to_x(home_dir(X_AXIS) > 0 ? X_MAX_POS : X_MIN_POS); + do_blocking_move_to_x(MachineState::Homing, home_dir(X_AXIS) > 0 ? X_MAX_POS : X_MIN_POS); } #endif @@ -302,7 +304,7 @@ void GcodeSuite::G28() { if (homing) { homeaxis(Y_AXIS); } else { - do_blocking_move_to_y(home_dir(Y_AXIS) > 0 ? Y_MAX_POS : Y_MIN_POS); + do_blocking_move_to_y(MachineState::Homing, home_dir(Y_AXIS) > 0 ? Y_MAX_POS : Y_MIN_POS); } } @@ -340,7 +342,7 @@ void GcodeSuite::G28() { if (toolsModule.isAutomatic()) { // move to X min - do_blocking_move_to_x(motionModule.getLimits().getMin().x()); + do_blocking_move_to_x(MachineState::Homing, motionModule.getLimits().getMin().x()); } report_current_position(); diff --git a/src/marlin/gcode/config/M2000.cpp b/src/marlin/gcode/config/M2000.cpp index 1c9d8b1f47..0b22b03eee 100644 --- a/src/marlin/gcode/config/M2000.cpp +++ b/src/marlin/gcode/config/M2000.cpp @@ -21,7 +21,6 @@ using namespace swordfish; using namespace swordfish::core; using namespace swordfish::data; -using namespace swordfish::gcode; using namespace swordfish::io; using namespace swordfish::motion; using namespace swordfish::tools; diff --git a/src/marlin/gcode/config/M43.cpp b/src/marlin/gcode/config/M43.cpp index 3f765c0bbc..a01f8fed22 100644 --- a/src/marlin/gcode/config/M43.cpp +++ b/src/marlin/gcode/config/M43.cpp @@ -29,6 +29,10 @@ #include "../../pins/pinsDebug.h" #include "../../module/endstops.h" +#include + +using namespace swordfish::status; + #if HAS_Z_SERVO_PROBE #include "../../module/probe.h" #include "../../module/servo.h" @@ -338,7 +342,8 @@ void GcodeSuite::M43() { } #if HAS_RESUME_CONTINUE - KEEPALIVE_STATE(PAUSED_FOR_USER); + TemporaryState state(MachineState::AwaitingInput); + wait_for_user = true; TERN_(HOST_PROMPT_SUPPORT, host_prompt(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR)); TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called"))); diff --git a/src/marlin/gcode/control/M2001.cpp b/src/marlin/gcode/control/M2001.cpp index f7e421254f..df74cb1a9c 100644 --- a/src/marlin/gcode/control/M2001.cpp +++ b/src/marlin/gcode/control/M2001.cpp @@ -4,7 +4,7 @@ #include #include -using namespace swordfish::gcode; +using namespace swordfish; enum class Function : uint8_t { None = 0x00, diff --git a/src/marlin/gcode/control/M3-M5.cpp b/src/marlin/gcode/control/M3-M5.cpp index 53472ae38a..0df6532a1a 100644 --- a/src/marlin/gcode/control/M3-M5.cpp +++ b/src/marlin/gcode/control/M3-M5.cpp @@ -29,6 +29,7 @@ using namespace swordfish::core; using namespace swordfish::tools; +using namespace swordfish::status; /** * Laser: @@ -68,7 +69,7 @@ using namespace swordfish::tools; * PWM duty cycle goes from 0 (off) to 255 (always on). */ void GcodeSuite::M3_M4(const bool is_M4) { - KEEPALIVE_STATE(SPINDLE_RAMPING); + TemporaryState state(MachineState::SpindleRamp); auto& toolsModule = ToolsModule::getInstance(); auto& driver = toolsModule.getCurrentDriver(); @@ -91,7 +92,7 @@ void GcodeSuite::M3_M4(const bool is_M4) { * M5 - Cutter OFF (when moves are complete) */ void GcodeSuite::M5() { - KEEPALIVE_STATE(SPINDLE_RAMPING); + TemporaryState state(MachineState::SpindleRamp); auto& toolsModule = ToolsModule::getInstance(); auto& driver = toolsModule.getCurrentDriver(); diff --git a/src/marlin/gcode/gcode.cpp b/src/marlin/gcode/gcode.cpp index a41fb2d4a3..a6b0bba2cf 100644 --- a/src/marlin/gcode/gcode.cpp +++ b/src/marlin/gcode/gcode.cpp @@ -81,6 +81,7 @@ using namespace swordfish::core; using namespace swordfish::estop; using namespace swordfish::io; using namespace swordfish::motion; +using namespace swordfish::status; using namespace swordfish::tools; // Inactivity shutdown @@ -91,13 +92,14 @@ millis_t GcodeSuite::previous_move_ms = 0, // Relative motion mode for each logical axis static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES; uint8_t GcodeSuite::axis_relative = ((ar_init.x ? _BV(REL_X) : 0) | (ar_init.y ? _BV(REL_Y) : 0) | (ar_init.z ? _BV(REL_Z) : 0) | (ar_init.e ? _BV(REL_E) : 0)); +bool GcodeSuite::aborted_ = false; #if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) bool GcodeSuite::autoreport_paused; // = false #endif #if ENABLED(HOST_KEEPALIVE_FEATURE) -GcodeSuite::MarlinBusyState GcodeSuite::busy_state = NOT_BUSY; +//MarlinBusyState GcodeSuite::busy_state = NOT_BUSY; float GcodeSuite::host_keepalive_interval = DEFAULT_KEEPALIVE_INTERVAL; #endif @@ -285,15 +287,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok /*=false*/) { #endif #if HAS_ESTOP - /*if (estop_engaged()) { - SERIAL_ECHO_MSG(STR_ESTOP_ENGAGED); - - if (!no_ok) { - queue.ok_to_send(); - } - - return; - }*/ + GcodeSuite::aborted_ = false; if (!EStopModule::getInstance().checkOrClear()) { SERIAL_ECHO_MSG(STR_ESTOP_ENGAGED); @@ -306,7 +300,9 @@ void GcodeSuite::process_parsed_command(const bool no_ok /*=false*/) { } #endif - KEEPALIVE_STATE(IN_HANDLER); + //KEEPALIVE_STATE(IN_HANDLER); + + //auto _ = keepalive_state(IN_HANDLER); auto& out = Console::out(); @@ -1076,29 +1072,44 @@ void GcodeSuite::process_subcommands_now(char* gcode) { } const char* GcodeSuite::get_state() { - if (!EStopModule::getInstance().checkOrClear()) { - return "estop"; - } + auto state = StatusModule::getInstance().peek_state(); - switch (busy_state) { - case NOT_BUSY: + switch (state) { + case MachineState::Idle: { return "idle"; - case IN_HANDLER: + } + + case MachineState::EmergencyStop: { + return "estop"; + } + + case MachineState::FeedMove: { return "busy"; - case IN_PROCESS: + } + + case MachineState::RapidMove: { return "busy"; - case HOMING: + } + + case MachineState::Homing: { return "homing"; - case PROBING: - return "probing"; - case PAUSED_FOR_USER: - return "paused"; - case PAUSED_FOR_INPUT: + } + + case MachineState::AwaitingInput: { return "waiting"; - case SPINDLE_RAMPING: + } + + case MachineState::SpindleRamp: { return "spindle:ramping"; - default: + } + + case MachineState::Probing: { + return "probing"; + } + + default: { return "idle"; + } } } @@ -1131,7 +1142,7 @@ void GcodeSuite::report_state() { SERIAL_PRINTF(",\"ovR\":%ld", rapidrate_percentage); SERIAL_PRINTF(",\"ovF\":%ld", feedrate_percentage); SERIAL_PRINTF(",\"ovS\":%ld", (uint32_t) driver.getPowerOverride()); - SERIAL_PRINTF(",\"spindle\":{\"freq\":%d,\"rpm\":%d,\"dir\":%d}", driver.getOutputFrequency(), driver.getCurrentPower(), driver.getCurrentDirection()); + SERIAL_PRINTF(",\"spindle\":{\"freq\":%d,\"rpm\":%d,\"dir\":%d}", driver.getOutputFrequency(), 0/*driver.getCurrentPower()*/, driver.getCurrentDirection()); SERIAL_PRINTF(",\"tool\":%ld", toolManager.getCurrentToolIndex() + 1); SERIAL_PRINTF(",\"ntool\":%ld", toolManager.getNextToolIndex() + 1); SERIAL_ECHO("}\n"); diff --git a/src/marlin/gcode/gcode.h b/src/marlin/gcode/gcode.h index 25c6a6f2b1..d34b1f5504 100644 --- a/src/marlin/gcode/gcode.h +++ b/src/marlin/gcode/gcode.h @@ -331,6 +331,7 @@ typedef struct { class GcodeSuite { public: + static bool aborted_; static uint8_t axis_relative; static inline bool axis_is_relative(const AxisEnum a) { @@ -413,6 +414,16 @@ class GcodeSuite { process_subcommands_now_P(keep_leveling ? G28_STR : TERN(G28_L0_ENSURES_LEVELING_OFF, "G28L0", G28_STR)); } + static inline void abort_current() { + aborted_ = true; + } + + static inline void throwIfAborted() { + if (aborted_) { + throw swordfish::CommandException("command aborted"); + } + } + #if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE) static bool autoreport_paused; static inline bool set_autoreport_paused(const bool p) { @@ -428,40 +439,28 @@ class GcodeSuite { #endif #if ENABLED(HOST_KEEPALIVE_FEATURE) - /** - * States for managing Marlin and host communication - * Marlin sends messages if blocked or busy - */ - enum MarlinBusyState : char { - NOT_BUSY, // Not in a handler - IN_HANDLER, // Processing a GCode - IN_PROCESS, // Known to be blocking command input (as in G29) - HOMING, - PROBING, - PAUSED_FOR_USER, // Blocking pending any input - PAUSED_FOR_INPUT, // Blocking pending text input (concept) - SPINDLE_RAMPING - }; - - static MarlinBusyState busy_state; +private: + //static MarlinBusyState busy_state; + +public: static float host_keepalive_interval; static void host_keepalive(); - template - class keepaliverestorer { + /*template + class KeepaliveRestorer { T& ref_; T val_; public: - keepaliverestorer(T& perm) : + KeepaliveRestorer(T& perm) : ref_(perm), val_(perm) { } - keepaliverestorer(T& perm, T temp_val) : + KeepaliveRestorer(T& perm, T temp_val) : ref_(perm), val_(perm) { perm = temp_val; } - ~keepaliverestorer() { + ~KeepaliveRestorer() { restore(); } inline void restore() { @@ -469,15 +468,42 @@ class GcodeSuite { host_keepalive(); } - }; + };*/ + + /*class TemporaryState { + private: + MarlinBusyState old_state_; + + public: + TemporaryState(MarlinBusyState temporary_state) { + old_state_ = GcodeSuite::busy_state; + + GcodeSuite::set_busy_state(temporary_state); + } + + ~TemporaryState() { + restore(); + } -# define REMEMBER_KEEPALIVE(N, X, V...) GcodeSuite::keepaliverestorer<__typeof__(X)> restorer_##N(X, ##V) + inline void restore() { + GcodeSuite::set_busy_state(old_state_); + } + };*/ -# define KEEPALIVE_STATE(N) REMEMBER_KEEPALIVE(_KA_, gcode.busy_state, gcode.N) +//# define REMEMBER_KEEPALIVE(N, X, V...) GcodeSuite::KeepaliveRestorer<__typeof__(X)> restorer_##N(X, ##V) + +//# define KEEPALIVE_STATE(N) REMEMBER_KEEPALIVE(_KA_, gcode.busy_state, gcode.N) + + /*[[nodiscard]] + static TemporaryState keepalive_state(MarlinBusyState busy_state) { + return TemporaryState { busy_state }; + }*/ #else -# define KEEPALIVE_STATE(N) NOOP +//# define KEEPALIVE_STATE(N) NOOP #endif + + static void dwell(millis_t time); private: @@ -646,7 +672,7 @@ class GcodeSuite { static void M81(); static void M82(); - static void M83(); + //static void M83(); static void M85(); static void M86(); static void M92(); diff --git a/src/marlin/gcode/host/M115.cpp b/src/marlin/gcode/host/M115.cpp index c3b406ba34..2337847aee 100644 --- a/src/marlin/gcode/host/M115.cpp +++ b/src/marlin/gcode/host/M115.cpp @@ -64,6 +64,7 @@ void GcodeSuite::M115() { SERIAL_PRINTF(",\"date\":\"%s\"", __DATE__); SERIAL_PRINTF(",\"time\":\"%s\"", __TIME__); SERIAL_PRINTF(",\"url\":\"%s\"", SOURCE_CODE_URL); + SERIAL_PRINTF(",\"machine\":\"%s\"", MACHINE_NAME); SERIAL_ECHO(",\"smartM6\":true"); SERIAL_PRINTF(",\"hasATC\":%s", toolsModule.isAutomatic() ? "true" : "false"); SERIAL_ECHO("}"); diff --git a/src/marlin/gcode/motion/G0_G1.cpp b/src/marlin/gcode/motion/G0_G1.cpp index 80d9c2c0d7..8a7a9cb685 100644 --- a/src/marlin/gcode/motion/G0_G1.cpp +++ b/src/marlin/gcode/motion/G0_G1.cpp @@ -20,15 +20,17 @@ * */ -#include +#include using namespace swordfish; +using namespace swordfish::status; #include "../gcode.h" #include "../../module/motion.h" #include "../../module/planner.h" #include "../../MarlinCore.h" +#include #if ENABLED(VARIABLE_G0_FEEDRATE) feedRate_t rapidrate_mm_s = MMM_TO_MMS(G0_FEEDRATE); @@ -42,8 +44,7 @@ using namespace swordfish; * G0, G1: Coordinated movement of X Y Z E axes */ void GcodeSuite::G0_G1(const bool fast_move/* = false*/) { - - if (IsRunning() + if (IsRunning() #if ENABLED(NO_MOTION_BEFORE_HOMING) && !homing_needed_error( (parser.seen('X') ? _BV(X_AXIS) : 0) @@ -53,13 +54,15 @@ void GcodeSuite::G0_G1(const bool fast_move/* = false*/) { ) { feedRate_t old_feedrate; - #if ENABLED(VARIABLE_G0_FEEDRATE) - if (fast_move) { - old_feedrate = feedrate_mm_s; // Back up the (old) motion mode feedrate - feedrate_mm_s = rapidrate_mm_s * 0.01f * rapidrate_percentage; // Get G0 feedrate from last usage - } - #endif - + MachineState machine_state = MachineState::FeedMove; + + if (fast_move) { + machine_state = MachineState::RapidMove; + + old_feedrate = feedrate_mm_s; // Back up the (old) motion mode feedrate + feedrate_mm_s = rapidrate_mm_s * 0.01f * rapidrate_percentage; // Get G0 feedrate from last usage + } + get_destination_from_command(); // Get X Y Z E F (and set cutter power) if (fast_move) { @@ -70,12 +73,12 @@ void GcodeSuite::G0_G1(const bool fast_move/* = false*/) { feedrate_mm_s = MMM_TO_MMS(G0_FEEDRATE); // Get the fixed G0 feedrate #endif } - + debug()("accel_mm_s2: ", fast_move ? planner.settings.travel_acceleration : planner.settings.acceleration); debug()("feedrate_mm_s: ", feedrate_mm_s); - - prepare_line_to_destination(fast_move ? planner.settings.travel_acceleration : planner.settings.acceleration); - + + prepare_line_to_destination(machine_state, fast_move ? planner.settings.travel_acceleration : planner.settings.acceleration); + // Restore the motion mode feedrate if (fast_move) { feedrate_mm_s = old_feedrate; diff --git a/src/marlin/gcode/motion/G2_G3.cpp b/src/marlin/gcode/motion/G2_G3.cpp index 3712014177..64753f0b2a 100644 --- a/src/marlin/gcode/motion/G2_G3.cpp +++ b/src/marlin/gcode/motion/G2_G3.cpp @@ -28,6 +28,7 @@ using namespace swordfish; using namespace swordfish::motion; +using namespace swordfish::status; # include "../gcode.h" # include "../../module/motion.h" @@ -264,12 +265,13 @@ void plan_arc( Eigen::Vector3f raw3f { raw.x, raw.y, raw.z }; limits.throwIfOutside(raw3f); + gcode.throwIfAborted(); # if HAS_LEVELING && !PLANNER_LEVELING planner.apply_leveling(raw); # endif - if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, 0 + if (!planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, MachineState::FeedMove, 0 # if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration @@ -290,7 +292,7 @@ void plan_arc( planner.apply_leveling(raw); # endif - planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, 0 + planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, MachineState::FeedMove, 0 # if ENABLED(SCARA_FEEDRATE_SCALING) , inv_duration diff --git a/src/marlin/gcode/probe/G37.cpp b/src/marlin/gcode/probe/G37.cpp index 7db348d609..0c03a89d1b 100644 --- a/src/marlin/gcode/probe/G37.cpp +++ b/src/marlin/gcode/probe/G37.cpp @@ -30,6 +30,7 @@ #include #include + #if HAS_TOOL_PROBE # include "../gcode.h" @@ -39,6 +40,7 @@ using namespace swordfish; using namespace swordfish::motion; +using namespace swordfish::status; # define TOOL_PROBE_X (X_MIN_POS + 35) # define TOOL_PROBE_Y (Y_MAX_POS - 10) @@ -51,7 +53,7 @@ inline bool do_single_probe(EndstopEnum endstop /*, const uint8_t move_value*/) endstops.enable(true); - prepare_line_to_destination(); + prepare_line_to_destination(MachineState::Probing); planner.synchronize(); bool triggered = endstops.trigger_state() & (1 << endstop); @@ -74,7 +76,7 @@ void backoff(xyz_float_t& retract_mm) { // Move away by the retract distance destination = current_position + retract_mm; - prepare_line_to_destination(); + prepare_line_to_destination(MachineState::Probing); planner.synchronize(); } @@ -133,8 +135,6 @@ bool run_probe(AxisEnum axis, EndstopEnum endstop, float distance, float retract * G37 Probe Tool Offset */ void GcodeSuite::G37() { - KEEPALIVE_STATE(PROBING); - if (homing_needed_error(_BV(X_AXIS) | _BV(Y_AXIS) | _BV(Z_AXIS))) { return; } diff --git a/src/marlin/gcode/probe/G38.cpp b/src/marlin/gcode/probe/G38.cpp index 41ff37ce16..8be7c45dba 100644 --- a/src/marlin/gcode/probe/G38.cpp +++ b/src/marlin/gcode/probe/G38.cpp @@ -29,6 +29,10 @@ # include "../../module/motion.h" # include "../../module/endstops.h" +#include + +using namespace swordfish::status; + extern bool run_probe(AxisEnum axis, EndstopEnum endstop, float distance, float retract); /** @@ -43,8 +47,6 @@ extern bool run_probe(AxisEnum axis, EndstopEnum endstop, float distance, float * G38.5 - Probe away from workpiece, stop on contact break */ void GcodeSuite::G38(const int8_t subcode) { - KEEPALIVE_STATE(PROBING); - remember_feedrate_scaling_off(); [[maybe_unused]] const bool error_on_fail = diff --git a/src/marlin/gcode/queue.cpp b/src/marlin/gcode/queue.cpp index 6317787227..0bbdd0d639 100644 --- a/src/marlin/gcode/queue.cpp +++ b/src/marlin/gcode/queue.cpp @@ -742,7 +742,6 @@ void GCodeQueue::get_available_commands() { * Get the next command in the queue, optionally log it to SD, then dispatch it */ void GCodeQueue::advance() { - // Process immediate commands if (process_injected_command_P() || process_injected_command()) return; diff --git a/src/marlin/inc/Conditionals_post.h b/src/marlin/inc/Conditionals_post.h index 88f001b564..d9e02c3778 100644 --- a/src/marlin/inc/Conditionals_post.h +++ b/src/marlin/inc/Conditionals_post.h @@ -1755,7 +1755,8 @@ #if _HAS_STOP(X,MAX) #define HAS_X_MAX 1 #endif -#if _HAS_STOP(Y,MIN) +//#if _HAS_STOP(Y,MIN) +#if PIN_EXISTS(Y_MIN) #define HAS_Y_MIN 1 #endif #if _HAS_STOP(Y,MAX) diff --git a/src/marlin/module/motion.cpp b/src/marlin/module/motion.cpp index f57644a67d..0e38916ff6 100644 --- a/src/marlin/module/motion.cpp +++ b/src/marlin/module/motion.cpp @@ -30,8 +30,9 @@ using namespace Eigen; -using namespace swordfish; +//using namespace swordfish; using namespace swordfish::motion; +using namespace swordfish::status; #include "motion.h" #include "endstops.h" @@ -317,8 +318,8 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { * Move the planner to the current position from wherever it last moved * (or from wherever it has been told it is located). */ -void line_to_current_position(const feedRate_t& fr_mm_s /*=feedrate_mm_s*/) { - planner.buffer_line(current_position, fr_mm_s, active_extruder); +void line_to_current_position(const MachineState machine_state, const feedRate_t& fr_mm_s /*=feedrate_mm_s*/) { + planner.buffer_line(current_position, fr_mm_s, active_extruder, machine_state); } #if EXTRUDERS @@ -359,7 +360,7 @@ void prepare_fast_move_to_destination(const feedRate_t& scaled_fr_mm_s /*=MMS_SC * - Move at normal speed regardless of feedrate percentage. * - Extrude the specified length regardless of flow percentage. */ -void _internal_move_to_destination(const feedRate_t& fr_mm_s /*=0.0f*/ +void _internal_move_to_destination(const MachineState machine_state, const feedRate_t& fr_mm_s /*=0.0f*/ #if IS_KINEMATIC , const bool is_fast /*=false*/ @@ -382,7 +383,7 @@ void _internal_move_to_destination(const feedRate_t& fr_mm_s /*=0.0f*/ prepare_fast_move_to_destination(); else #endif - prepare_line_to_destination(); + prepare_line_to_destination(machine_state); feedrate_mm_s = old_feedrate; feedrate_percentage = old_pct; @@ -394,7 +395,7 @@ void _internal_move_to_destination(const feedRate_t& fr_mm_s /*=0.0f*/ /** * Plan a move to (X, Y, Z) and set the current_position */ -void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t& fr_mm_s /*=0.0*/) { +void do_blocking_move_to(const MachineState machine_state, const float rx, const float ry, const float rz, const feedRate_t& fr_mm_s /*=0.0*/) { DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING)); if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", rx, ry, rz); @@ -475,16 +476,16 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f // If Z needs to raise, do it before moving XY if (current_position.z < rz) { current_position.z = rz; - line_to_current_position(z_feedrate); + line_to_current_position(machine_state, z_feedrate); } current_position.set(rx, ry); - line_to_current_position(xy_feedrate); + line_to_current_position(machine_state, xy_feedrate); // If Z needs to lower, do it after moving XY if (current_position.z > rz) { current_position.z = rz; - line_to_current_position(z_feedrate); + line_to_current_position(machine_state, z_feedrate); } #endif @@ -492,43 +493,43 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const f planner.synchronize(); } -void do_blocking_move_to(const xy_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { - do_blocking_move_to(raw.x, raw.y, current_position.z, fr_mm_s); +void do_blocking_move_to(const MachineState machine_state, const xy_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { + do_blocking_move_to(machine_state, raw.x, raw.y, current_position.z, fr_mm_s); } -void do_blocking_move_to(const xyz_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { - do_blocking_move_to(raw.x, raw.y, raw.z, fr_mm_s); +void do_blocking_move_to(const MachineState machine_state, const xyz_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { + do_blocking_move_to(machine_state, raw.x, raw.y, raw.z, fr_mm_s); } -void do_blocking_move_to(const xyze_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { - do_blocking_move_to(raw.x, raw.y, raw.z, fr_mm_s); +void do_blocking_move_to(const MachineState machine_state, const xyze_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { + do_blocking_move_to(machine_state, raw.x, raw.y, raw.z, fr_mm_s); } -void do_blocking_move_to_x(const float& rx, const feedRate_t& fr_mm_s /*=0.0*/) { - do_blocking_move_to(rx, current_position.y, current_position.z, fr_mm_s); +void do_blocking_move_to_x(const MachineState machine_state, const float& rx, const feedRate_t& fr_mm_s /*=0.0*/) { + do_blocking_move_to(machine_state, rx, current_position.y, current_position.z, fr_mm_s); } -void do_blocking_move_to_y(const float& ry, const feedRate_t& fr_mm_s /*=0.0*/) { - do_blocking_move_to(current_position.x, ry, current_position.z, fr_mm_s); +void do_blocking_move_to_y(const MachineState machine_state, const float& ry, const feedRate_t& fr_mm_s /*=0.0*/) { + do_blocking_move_to(machine_state, current_position.x, ry, current_position.z, fr_mm_s); } -void do_blocking_move_to_z(const float& rz, const feedRate_t& fr_mm_s /*=0.0*/) { - do_blocking_move_to_xy_z(current_position, rz, fr_mm_s); +void do_blocking_move_to_z(const MachineState machine_state, const float& rz, const feedRate_t& fr_mm_s /*=0.0*/) { + do_blocking_move_to_xy_z(machine_state, current_position, rz, fr_mm_s); } -void do_blocking_move_to_xy(const float& rx, const float& ry, const feedRate_t& fr_mm_s /*=0.0*/) { - do_blocking_move_to(rx, ry, current_position.z, fr_mm_s); +void do_blocking_move_to_xy(const MachineState machine_state, const float& rx, const float& ry, const feedRate_t& fr_mm_s /*=0.0*/) { + do_blocking_move_to(machine_state, rx, ry, current_position.z, fr_mm_s); } -void do_blocking_move_to_xy(const xy_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { - do_blocking_move_to_xy(raw.x, raw.y, fr_mm_s); +void do_blocking_move_to_xy(const MachineState machine_state, const xy_pos_t& raw, const feedRate_t& fr_mm_s /*=0.0f*/) { + do_blocking_move_to_xy(machine_state, raw.x, raw.y, fr_mm_s); } -void do_blocking_move_to_xy_z(const xy_pos_t& raw, const float& z, const feedRate_t& fr_mm_s /*=0.0f*/) { - do_blocking_move_to(raw.x, raw.y, z, fr_mm_s); +void do_blocking_move_to_xy_z(const MachineState machine_state, const xy_pos_t& raw, const float& z, const feedRate_t& fr_mm_s /*=0.0f*/) { + do_blocking_move_to(machine_state, raw.x, raw.y, z, fr_mm_s); } -void do_z_clearance(const float& zclear, const bool z_trusted /*=true*/, const bool raise_on_untrusted /*=true*/, const bool lower_allowed /*=false*/) { +void do_z_clearance(const MachineState machine_state, const float& zclear, const bool z_trusted /*=true*/, const bool raise_on_untrusted /*=true*/, const bool lower_allowed /*=false*/) { const bool rel = raise_on_untrusted && !z_trusted; float zdest = zclear + (rel ? current_position.z : 0.0f); if (!lower_allowed) NOLESS(zdest, current_position.z); - do_blocking_move_to_z(_MIN(zdest, Z_MAX_POS), TERN(HAS_BED_PROBE, z_probe_fast_mm_s, homing_feedrate(Z_AXIS))); + do_blocking_move_to_z(machine_state, _MIN(zdest, Z_MAX_POS), TERN(HAS_BED_PROBE, z_probe_fast_mm_s, homing_feedrate(Z_AXIS))); } // @@ -765,13 +766,14 @@ inline void segmented_line_to_destination(const feedRate_t& fr_mm_s, const float * * Return true if 'current_position' was set to 'destination' */ -inline bool line_to_destination_cartesian(const float32_t accel_mm_s2) { +inline bool line_to_destination_cartesian(const swordfish::status::MachineState machine_state, const float32_t accel_mm_s2) { const float scaled_fr_mm_s = MMS_SCALED(feedrate_mm_s); planner.buffer_line( destination, scaled_fr_mm_s, active_extruder, + machine_state, 0.0, accel_mm_s2); @@ -919,7 +921,7 @@ inline bool dual_x_carriage_unpark() { * * Before exit, current_position is set to destination. */ -void prepare_line_to_destination(const float32_t accel_mm_s2 /* = 0.0 */) { +void prepare_line_to_destination(const swordfish::status::MachineState machine_state, const float32_t accel_mm_s2 /* = 0.0 */) { auto& motionModule = MotionModule::getInstance(); auto& limits = motionModule.getLimits(); @@ -927,7 +929,7 @@ void prepare_line_to_destination(const float32_t accel_mm_s2 /* = 0.0 */) { limits.throwIfOutside(dest); - if (line_to_destination_cartesian(accel_mm_s2)) { + if (line_to_destination_cartesian(machine_state, accel_mm_s2)) { return; } @@ -1191,7 +1193,7 @@ void do_homing_move(const AxisEnum axis, const float distance, const feedRate_t cart_dist_mm # endif , - home_fr_mm_s, active_extruder); + home_fr_mm_s, active_extruder, MachineState::Homing); #endif planner.synchronize(); diff --git a/src/marlin/module/motion.h b/src/marlin/module/motion.h index cda3cafd30..4720eefbfb 100644 --- a/src/marlin/module/motion.h +++ b/src/marlin/module/motion.h @@ -83,17 +83,17 @@ FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) { #if ENABLED(DELTA) v = homing_feedrate_mm_m.z; #else - + switch (a) { case X_AXIS: v = homing_feedrate_mm_m.x; break; case Y_AXIS: v = homing_feedrate_mm_m.y; break; case Z_AXIS: default: v = homing_feedrate_mm_m.z; break; } - + #endif - return MMM_TO_MMS(v); + return MMM_TO_MMS(v); } feedRate_t get_homing_bump_feedrate(const AxisEnum axis); @@ -180,22 +180,22 @@ void sync_plan_position_e(); * Move the planner to the current position from wherever it last moved * (or from wherever it has been told it is located). */ -void line_to_current_position(const feedRate_t &fr_mm_s=feedrate_mm_s); +void line_to_current_position(const swordfish::status::MachineState machine_state, const feedRate_t &fr_mm_s=feedrate_mm_s); #if EXTRUDERS void unscaled_e_move(const float &length, const feedRate_t &fr_mm_s); #endif -void prepare_line_to_destination(const float32_t accel_mm_s2 = 0.0); +void prepare_line_to_destination(const swordfish::status::MachineState machine_state, const float32_t accel_mm_s2 = 0.0); -void _internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f +void _internal_move_to_destination(const swordfish::status::MachineState machine_state, const feedRate_t &fr_mm_s=0.0f #if IS_KINEMATIC , const bool is_fast=false #endif ); -inline void prepare_internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f) { - _internal_move_to_destination(fr_mm_s); +inline void prepare_internal_move_to_destination(const swordfish::status::MachineState machine_state, const feedRate_t &fr_mm_s=0.0f) { + _internal_move_to_destination(machine_state, fr_mm_s); } #if IS_KINEMATIC @@ -209,29 +209,29 @@ inline void prepare_internal_move_to_destination(const feedRate_t &fr_mm_s=0.0f) /** * Blocking movement and shorthand functions */ -void do_blocking_move_to(const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to(const xy_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to(const xyz_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to(const xyze_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to(const swordfish::status::MachineState machine_state, const float rx, const float ry, const float rz, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to(const swordfish::status::MachineState machine_state, const xy_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to(const swordfish::status::MachineState machine_state, const xyz_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to(const swordfish::status::MachineState machine_state, const xyze_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to_x(const float &rx, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to_y(const float &ry, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to_z(const float &rz, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to_x(const swordfish::status::MachineState machine_state, const float &rx, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to_y(const swordfish::status::MachineState machine_state, const float &ry, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to_z(const swordfish::status::MachineState machine_state, const float &rz, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to_xy(const float &rx, const float &ry, const feedRate_t &fr_mm_s=0.0f); -void do_blocking_move_to_xy(const xy_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); -FORCE_INLINE void do_blocking_move_to_xy(const xyz_pos_t &raw, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy(xy_pos_t(raw), fr_mm_s); } -FORCE_INLINE void do_blocking_move_to_xy(const xyze_pos_t &raw, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy(xy_pos_t(raw), fr_mm_s); } +void do_blocking_move_to_xy(const swordfish::status::MachineState machine_state, const float &rx, const float &ry, const feedRate_t &fr_mm_s=0.0f); +void do_blocking_move_to_xy(const swordfish::status::MachineState machine_state, const xy_pos_t &raw, const feedRate_t &fr_mm_s=0.0f); +FORCE_INLINE void do_blocking_move_to_xy(const swordfish::status::MachineState machine_state, const xyz_pos_t &raw, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy(machine_state, xy_pos_t(raw), fr_mm_s); } +FORCE_INLINE void do_blocking_move_to_xy(const swordfish::status::MachineState machine_state, const xyze_pos_t &raw, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy(machine_state, xy_pos_t(raw), fr_mm_s); } -void do_blocking_move_to_xy_z(const xy_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f); -FORCE_INLINE void do_blocking_move_to_xy_z(const xyz_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy_z(xy_pos_t(raw), z, fr_mm_s); } -FORCE_INLINE void do_blocking_move_to_xy_z(const xyze_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy_z(xy_pos_t(raw), z, fr_mm_s); } +void do_blocking_move_to_xy_z(const swordfish::status::MachineState machine_state, const xy_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f); +FORCE_INLINE void do_blocking_move_to_xy_z(const swordfish::status::MachineState machine_state, const xyz_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy_z(machine_state, xy_pos_t(raw), z, fr_mm_s); } +FORCE_INLINE void do_blocking_move_to_xy_z(const swordfish::status::MachineState machine_state, const xyze_pos_t &raw, const float &z, const feedRate_t &fr_mm_s=0.0f) { do_blocking_move_to_xy_z(machine_state, xy_pos_t(raw), z, fr_mm_s); } void remember_feedrate_and_scaling(); void remember_feedrate_scaling_off(); void restore_feedrate_and_scaling(); -void do_z_clearance(const float &zclear, const bool z_trusted=true, const bool raise_on_untrusted=true, const bool lower_allowed=false); +void do_z_clearance(const swordfish::status::MachineState machine_state, const float &zclear, const bool z_trusted=true, const bool raise_on_untrusted=true, const bool lower_allowed=false); /** * Homing and Trusted Axes diff --git a/src/marlin/module/planner.cpp b/src/marlin/module/planner.cpp index fa44df793b..e46e47114a 100644 --- a/src/marlin/module/planner.cpp +++ b/src/marlin/module/planner.cpp @@ -63,10 +63,11 @@ */ #include -#include +#include using namespace swordfish; using namespace swordfish::estop; +using namespace swordfish::status; #include "planner.h" #include "stepper.h" @@ -1718,6 +1719,7 @@ bool Planner::_buffer_steps( #endif const feedRate_t fr_mm_s, const uint8_t extruder, + const MachineState machine_state, const float& millimeters /* = 0.0*/, const float32_t accel_mm_s2 /* = 0.0*/ ) { @@ -1739,6 +1741,7 @@ bool Planner::_buffer_steps( #endif fr_mm_s, extruder, + machine_state, millimeters, accel_mm_s2)) { // Movement was not queued, probably because it was too short. @@ -1786,6 +1789,7 @@ bool Planner::_populate_block( #endif feedRate_t fr_mm_s, const uint8_t extruder, + const MachineState machine_state, const float& millimeters /* = 0.0*/, float32_t accel_mm_s2 /* = 0.0*/ ) { @@ -1879,6 +1883,8 @@ bool Planner::_populate_block( constexpr uint32_t esteps = 0; #endif + block->machine_state = machine_state; + // Clear all flags, including the "busy" bit block->flag = 0x00; @@ -2656,8 +2662,9 @@ bool Planner::buffer_segment( const float& e, const feedRate_t& fr_mm_s, const uint8_t extruder, + const MachineState machine_state, const float& millimeters /* = 0.0*/, - const float32_t accel_mm_s2 /* = 0.0*/ + const float32_t accel_mm_s2/* = 0.0*/ ) { // If we are cleaning, do not accept queuing of movements @@ -2732,6 +2739,7 @@ bool Planner::buffer_segment( #endif fr_mm_s, extruder, + machine_state, millimeters, accel_mm_s2)) { return false; @@ -2759,6 +2767,7 @@ bool Planner::buffer_line( const float& e, const feedRate_t& fr_mm_s, const uint8_t extruder, + const MachineState machine_state, const float millimeters, const float32_t accel_mm_s2 /* = 0.0*/ ) { @@ -2769,6 +2778,7 @@ bool Planner::buffer_line( machine, fr_mm_s, extruder, + machine_state, millimeters, accel_mm_s2); } // buffer_line() diff --git a/src/marlin/module/planner.h b/src/marlin/module/planner.h index 009e831b82..b5955fcde4 100644 --- a/src/marlin/module/planner.h +++ b/src/marlin/module/planner.h @@ -202,6 +202,8 @@ typedef struct block_t { final_rate, // The minimal rate at exit acceleration_steps_per_s2; // acceleration steps/sec^2 + swordfish::status::MachineState machine_state; + #if ENABLED(DIRECT_STEPPING) page_idx_t page_idx; // Page index used for direct stepping #endif @@ -681,6 +683,7 @@ class Planner { #endif const feedRate_t fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float &millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ); @@ -706,6 +709,7 @@ class Planner { #endif feedRate_t fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float &millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ); @@ -742,6 +746,7 @@ class Planner { const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float &millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ); @@ -750,6 +755,7 @@ class Planner { abce_pos_t &abce, const feedRate_t &fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float &millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ) { @@ -760,6 +766,7 @@ class Planner { abce.e, fr_mm_s, extruder, + machine_state, millimeters, accel_mm_s2 ); @@ -785,6 +792,7 @@ class Planner { const float &e, const feedRate_t &fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ); @@ -793,6 +801,7 @@ class Planner { const xyze_pos_t &cart, const feedRate_t &fr_mm_s, const uint8_t extruder, + const swordfish::status::MachineState machine_state, const float millimeters = 0.0, const float32_t accel_mm_s2 = 0.0 ) { @@ -803,6 +812,7 @@ class Planner { cart.e, fr_mm_s, extruder, + machine_state, millimeters, accel_mm_s2 ); diff --git a/src/marlin/module/stepper.cpp b/src/marlin/module/stepper.cpp index fc1a11addc..9c19dd5e44 100644 --- a/src/marlin/module/stepper.cpp +++ b/src/marlin/module/stepper.cpp @@ -92,10 +92,15 @@ Stepper stepper; // Singleton #include "motion.h" #include "../gcode/queue.h" +#include "../gcode/gcode.h" #include "../sd/cardreader.h" #include "../MarlinCore.h" #include "../HAL/shared/Delay.h" +#include + +using namespace swordfish::status; + #if ENABLED(INTEGRATED_BABYSTEPPING) # include "../feature/babystep.h" #endif @@ -1871,6 +1876,18 @@ void Stepper::pulse_phase_isr() { } while (--events_to_do); } +void Stepper::update_state() { + using namespace swordfish::status; + + auto& status_module = StatusModule::getInstance(); + + if (current_block) { + status_module.set_state(current_block->machine_state); + } else { + status_module.set_state(MachineState::Idle); + } +} + // This is the last half of the stepper interrupt: This one processes and // properly schedules blocks from the planner. This is executed after creating // the step pulses, so it is not time critical, as pulses are already done. @@ -2090,10 +2107,14 @@ uint32_t Stepper::block_phase_isr() { discard_current_block(); // Try to get a new block - if (!(current_block = planner.get_current_block())) + if (!(current_block = planner.get_current_block())) { + update_state(); + return interval; // No more queued movements! + } } + update_state(); // For non-inline cutter, grossly apply power #if ENABLED(LASER_FEATURE) && DISABLED(LASER_POWER_INLINE) cutter.apply_power(current_block->cutter_power); @@ -2323,9 +2344,13 @@ uint32_t Stepper::block_phase_isr() { // Calculate the initial timer interval interval = calc_timer_interval(current_block->initial_rate, &steps_per_isr); - } + } else { + // No new block found; so apply inline laser parameters + + update_state(); + #if ENABLED(LASER_POWER_INLINE_CONTINUOUS) - else { // No new block found; so apply inline laser parameters + // This should mean ending file with 'M5 I' will stop the laser; thus the inline flag isn't needed const power_status_t stat = planner.laser_inline.status; if (stat.isPlanned) { // Planner controls the laser @@ -2339,6 +2364,7 @@ uint32_t Stepper::block_phase_isr() { } } #endif + } } // Return the interval to wait diff --git a/src/marlin/module/stepper.h b/src/marlin/module/stepper.h index 3fa2df8b99..b831de8711 100644 --- a/src/marlin/module/stepper.h +++ b/src/marlin/module/stepper.h @@ -407,6 +407,8 @@ class Stepper { // The stepper block processing ISR phase static uint32_t block_phase_isr(); + static void update_state(); + #if ENABLED(LIN_ADVANCE) // The Linear advance ISR phase static uint32_t advance_isr(); diff --git a/src/marlin/pins/pinsDebug_list.h b/src/marlin/pins/pinsDebug_list.h index 8f18843c09..afb547c868 100644 --- a/src/marlin/pins/pinsDebug_list.h +++ b/src/marlin/pins/pinsDebug_list.h @@ -1247,6 +1247,12 @@ REPORT_NAME_DIGITAL(__LINE__, ZRIB_V20_D6_PIN) #if PIN_EXISTS(ZRIB_V20_D9) REPORT_NAME_DIGITAL(__LINE__, ZRIB_V20_D9_PIN) #endif +#if PIN_EXISTS(A_MAX) +REPORT_NAME_DIGITAL(__LINE__, A_MAX_PIN) +#endif +#if PIN_EXISTS(A_MIN) +REPORT_NAME_DIGITAL(__LINE__, A_MIN_PIN) +#endif #if PIN_EXISTS(X_SERIAL_TX) REPORT_NAME_DIGITAL(__LINE__, X_SERIAL_TX_PIN) #endif diff --git a/src/marlin/pins/samd/pins_boardinator.h b/src/marlin/pins/samd/pins_boardinator.h index 20deac672a..4bbede5776 100644 --- a/src/marlin/pins/samd/pins_boardinator.h +++ b/src/marlin/pins/samd/pins_boardinator.h @@ -45,11 +45,17 @@ // #define X_MIN_PIN 70 +#if MACHINE_TYPE == 5 || MACHINE_TYPE == 6 || MACHINE_TYPE == 7 || MACHINE_TYPE == 8 || MACHINE_TYPE == 9 +#define Y_MIN_PIN 71 +#define Y_MAX_PIN -1 +#define Y2_MIN_PIN 72 +#else #define Y_MAX_PIN 71 #define Y_MIN_PIN -1 #define Y2_MAX_PIN 72 +#endif #define Z_MAX_PIN 73 - +#define A_MAX_PIN 57 #define HAS_TOOL_PROBE 1 #define TOOL_PROBE_PIN 4 @@ -113,10 +119,16 @@ // // Misc. Functions // -#define LED_PIN 13 +#define LED_PIN 16 #define PS_ON_PIN 10 -// +#if MACHINE_TYPE == 5 + #define LED_COUNT 50 +#else + #define LED_COUNT 1 +#endif + +// // SD Support // #ifndef SDCARD_CONNECTION diff --git a/src/swordfish/Controller.cpp b/src/swordfish/Controller.cpp index 3e46a8a6e2..504e377e74 100644 --- a/src/swordfish/Controller.cpp +++ b/src/swordfish/Controller.cpp @@ -3,7 +3,7 @@ * * Created: 8/08/2021 1:31:37 pm * Author: smohekey - */ + */ #include "Controller.h" @@ -21,96 +21,98 @@ namespace swordfish { using namespace core; - + static constexpr uint32_t MAGIC = 0xBEEFDEAD; - + Controller* Controller::__instance = nullptr; core::ObjectField Controller::__toolingModuleField = { "tooling", 0, getToolsModule }; core::ObjectField Controller::__motionModuleField = { "motion", 1, getMotionModule }; core::ObjectField Controller::__estopModuleField = { "estop", 2, getEStopModule }; core::ObjectField Controller::__gpioModuleField = { "gpio", 3, getGPIOModule }; - + core::ObjectField Controller::__statusModuleField = { "status", 4, getStatusModule }; + core::Schema Controller::__schema = { utils::typeName(), nullptr, { - + }, { __toolingModuleField, __motionModuleField, __estopModuleField, - __gpioModuleField + __gpioModuleField, + __statusModuleField } }; core::Pack& Controller::getPack() { return _pack; } - + static bool readHeader(io::WrappingInputStream& stream, offset_t offset, uint32_t& length) { uint32_t magic; uint32_t self; uint32_t version; - + stream.seek(offset, io::Origin::Start); - + stream.read(&magic, 4); - + debug()("magic: ", (void*)magic); - + if(magic != MAGIC) { return false; } - + stream.read(&self, 4); - + debug()("self: ", self); - + if(self != offset) { return false; } - + stream.read(&version, 4); stream.read(&length, 4); - + debug()("version: ", version); debug()("length: ", length); - + return true; } static void readObject(io::InputStream& stream, uint32_t depth) { HAL_watchdog_refresh(); - + if(++depth > 10) { return; } - + uint16_t valuesLength; uint16_t objectCount; - + stream.read(&valuesLength, sizeof(valuesLength)); stream.read(&objectCount, sizeof(objectCount)); - + if(valuesLength > 1024 || objectCount > 1024) { return; } - + while(valuesLength) { uint8_t dummy; - + stream.read(&dummy, 1); - + valuesLength--; } - + while(objectCount) { readObject(stream, depth); - + objectCount--; } } - + void Controller::loadConfig(PersistentStoreInputStream& store, io::WrappingInputStream& stream, offset_t offset) { uint32_t magic; uint32_t self; @@ -118,45 +120,45 @@ namespace swordfish { uint32_t reserved; uint16_t crc; uint16_t storedCrc; - + stream.seek(offset, io::Origin::Start); - + store.resetCRC(); - + stream.read(&magic, 4); - + if(magic != MAGIC) { throw FormatException { "magic header is incorrect." }; } - + stream.read(&self, 4); - + if(self != offset) { throw FormatException { "self offset is incorrect." }; } - + stream.read(&version, 4); stream.read(&reserved, 4); - + Console::out() << "version: " << version << io::nl; - + read(stream); - + crc = store.getCRC(); - + stream.read(&storedCrc, 2); - + if(storedCrc != crc) { Console::out() << "crc: " << crc << " stored crc: " << storedCrc << io::nl; - + throw FormatException { "crc is incorrect." }; } } - + static offset_t align(offset_t current) { void* p = (void*)current; size_t space = CONFIG_END - current; - + return (offset_t)std::align(SFLASH_SECTOR_SIZE, SFLASH_SECTOR_SIZE, p, space); } @@ -170,9 +172,10 @@ namespace swordfish { &static_cast(__toolingModuleField.get(_pack)), &static_cast(__motionModuleField.get(_pack)), &static_cast(__estopModuleField.get(_pack)), - &static_cast(__gpioModuleField.get(_pack)) + &static_cast(__gpioModuleField.get(_pack)), + &static_cast(__statusModuleField.get(_pack)) }) { - + } void Controller::init() { @@ -182,9 +185,9 @@ namespace swordfish { GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val); - + while (GCLK->SYNCBUSY.bit.GENCTRL7); // Wait for synchronization - + // Check startup - does nothing if bootloader sets MCUSR to 0 const byte mcu = HAL_get_reset_source(); if (mcu & RST_POWER_ON) debug()(STR_POWERUP); @@ -192,10 +195,10 @@ namespace swordfish { if (mcu & RST_BROWN_OUT) debug()(STR_BROWNOUT_RESET); if (mcu & RST_WATCHDOG) debug()(STR_WATCHDOG_RESET); if (mcu & RST_SOFTWARE) debug()(STR_SOFTWARE_RESET); - + for(auto* module : _modules) { debug()("Initializing module ", module->name()); - + module->init(); } } @@ -205,76 +208,76 @@ namespace swordfish { module->idle(); } } - + bool Controller::findNewestConfig(PersistentStoreInputStream& store, io::WrappingInputStream& stream, offset_t& offset) { offset = 0; offset_t lastOffset = 0; - + while(offset < CONFIG_END - CONFIG_START) { debug()("Checking offset: ", (uint32_t)offset); - + uint32_t length; - + HAL_watchdog_refresh(); - + if(readHeader(stream, offset, length)) { lastOffset = offset; } else { break; } - + offset = align(offset + length); //offset += SFLASH_SECTOR_SIZE; } - + // now work backwards finding a valid config - + offset = lastOffset; - + while(offset >= 0) { try { loadConfig(store, stream, offset); - + _configEnd = stream.seek(0, io::Origin::Current); - + return true; } catch(Exception& e) { - + } - + offset -= SFLASH_SECTOR_SIZE; } - + return false; } - + void Controller::load() { //reset(); - + PersistentStoreInputStream store; - + io::WrappingInputStream stream(store, CONFIG_START, CONFIG_END, 0); - + offset_t offset; - + if(!findNewestConfig(store, stream, offset)) { Console::out() << "No valid config found." << io::nl; - + save(); } else { Console::out() << "Found config " << _configVersion << " at " << _configStart + CONFIG_START << " with length " << _configEnd - _configStart << io::nl; } } - + static bool validateCRC(io::WrappingInputStream& stream, offset_t offset, uint16_t crc) { uint16_t storedCRC; - + stream.seek(offset, io::Origin::Start); - + stream.read(&storedCRC, sizeof(uint16_t)); - + debug()("storedCRC: ", storedCRC, " CRC: ", crc); - + return storedCRC == crc; } @@ -282,84 +285,84 @@ namespace swordfish { //debug()(_configEnd); offset_t offset = _configStart; uint16_t crc = 0; - + PersistentStoreInputStream inputStore; PersistentStoreOutputStream outputStore; io::WrappingInputStream input(inputStore, CONFIG_START, CONFIG_END, 0); io::WrappingOutputStream output(outputStore, CONFIG_START, CONFIG_END, 0); - + _configVersion++; - + do { HAL_watchdog_refresh(); - + debug()("attempting to write at ", (uint32_t)offset); - + outputStore.resetCRC(); - + output.seek(offset, io::Origin::Start); - + uint32_t buffer = MAGIC; output.write(&buffer, 4); - + buffer = output.seek(0, io::Origin::Current); - + buffer -= 4; output.write(&buffer, 4); - + buffer = _configVersion; output.write(&buffer, 4); - + debug()("version: ", buffer); - + buffer = _pack.length(); output.write(&buffer, 4); - + debug()("length: ", buffer); - + write(output); - + crc = outputStore.getCRC(); - + debug()("crc: ", crc); - + output.write(&crc, 2); - + offset += SFLASH_SECTOR_SIZE; } while((offset < CONFIG_END - CONFIG_START) && !validateCRC(input, output.seek(-2, io::Origin::Current), crc)); } - + void Controller::reset() { Adafruit_FlashTransport_QSPI transport = { }; Adafruit_SPIFlashBase flash = { &transport }; - + flash.begin(nullptr); - + _configStart = _configEnd = _configVersion = 0; - + uint32_t offset = CONFIG_START; - + debug()("Resetting eeprom."); - + while(offset < CONFIG_END) { auto block = offset / SFLASH_BLOCK_SIZE; - + if(block > 0) { debug()("Erasing address: ", offset, " block: ", block); - + flash.eraseBlock(block); - + offset += SFLASH_BLOCK_SIZE; } else { auto sector = offset / SFLASH_SECTOR_SIZE; - + debug()("Erasing address: ", offset, " sector: ", sector); - + flash.eraseSector(sector); - + offset += SFLASH_SECTOR_SIZE; } - + HAL_watchdog_refresh(); } } @@ -384,4 +387,7 @@ namespace swordfish { return &gpio::GPIOModule::getInstance(parent); } + swordfish::status::StatusModule* Controller::getStatusModule([[maybe_unused]] Object* parent) { + return &status::StatusModule::getInstance(parent); + } } \ No newline at end of file diff --git a/src/swordfish/Controller.h b/src/swordfish/Controller.h index d25e4cb62d..b2374396ce 100644 --- a/src/swordfish/Controller.h +++ b/src/swordfish/Controller.h @@ -3,7 +3,7 @@ * * Created: 8/08/2021 1:32:05 pm * Author: smohekey - */ + */ #pragma once @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include "PersistentStore.h" @@ -25,52 +27,56 @@ namespace swordfish { namespace io { class WrappingInputStream; } - + class Controller : public core::Object { private: static tools::ToolsModule* getToolsModule([[maybe_unused]] Object* parent); - + static motion::MotionModule* getMotionModule([[maybe_unused]] Object* parent); - + static estop::EStopModule* getEStopModule([[maybe_unused]] Object* parent); - + static gpio::GPIOModule* getGPIOModule([[maybe_unused]] Object* parent); - + + static status::StatusModule* getStatusModule([[maybe_unused]] Object* parent); + static core::ObjectField __toolingModuleField; static core::ObjectField __motionModuleField; static core::ObjectField __estopModuleField; static core::ObjectField __gpioModuleField; + static core::ObjectField __statusModuleField; static Controller* __instance; - + Controller(); bool findNewestConfig(PersistentStoreInputStream& store, io::WrappingInputStream& stream, offset_t& offset); void loadConfig(PersistentStoreInputStream& store, io::WrappingInputStream& stream, offset_t offset); + protected: static core::Schema __schema; - + core::Pack _pack; - + uint32_t _configVersion; uint32_t _configStart; uint32_t _configEnd; - - std::array _modules; - + + std::array _modules; + virtual core::Pack& getPack() override; - + public: virtual ~Controller() { - + } - + void init(); void idle(); void load(); void save(); void reset(); - + static Controller& getInstance(); }; } \ No newline at end of file diff --git a/src/swordfish/Exception.h b/src/swordfish/Exception.h index 21f813b104..d136a9a626 100644 --- a/src/swordfish/Exception.h +++ b/src/swordfish/Exception.h @@ -3,7 +3,7 @@ * * Created: 30/09/2021 1:06:47 pm * Author: smohekey - */ + */ #pragma once @@ -11,16 +11,15 @@ namespace swordfish { namespace io { class Writer; } - + class Exception { protected: virtual ~Exception() { } - + virtual void writeType(io::Writer& writer) const = 0; virtual void writeMessage(io::Writer& writer) const = 0; public: virtual void writeJson(io::Writer& writer) const; }; - - + } \ No newline at end of file diff --git a/src/swordfish/core/Schema.h b/src/swordfish/core/Schema.h index 76add6258d..5cbe4c780f 100644 --- a/src/swordfish/core/Schema.h +++ b/src/swordfish/core/Schema.h @@ -113,7 +113,7 @@ namespace swordfish::core { template< typename T> class ValueField : public ValueFieldBase { - private: + protected: const uint32_t _byteOffset; const T _defaultValue; @@ -205,6 +205,10 @@ namespace swordfish::core { ValueField(name, byteOffset, defaultValue), _validate(validate) { } + virtual void init(Pack& pack) override { + ValueField::set(pack, ValueField::_defaultValue); + } + virtual void set(Pack& pack, const T value) override { if (_validate) { _validate(this->get(pack), value); diff --git a/src/swordfish/debug.h b/src/swordfish/debug.h index e10c9e1194..6cab5e3379 100644 --- a/src/swordfish/debug.h +++ b/src/swordfish/debug.h @@ -14,7 +14,7 @@ #include namespace swordfish { -#ifdef DEBUG +#if defined(DEBUG) extern io::Writer out; struct debug { diff --git a/src/swordfish/modules/CMakeLists.txt b/src/swordfish/modules/CMakeLists.txt index ce7934fb0e..8ac32a3ccb 100644 --- a/src/swordfish/modules/CMakeLists.txt +++ b/src/swordfish/modules/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(estop) add_subdirectory(gcode) add_subdirectory(gpio) add_subdirectory(motion) +add_subdirectory(status) add_subdirectory(tools) diff --git a/src/swordfish/modules/estop/EStopModule.cpp b/src/swordfish/modules/estop/EStopModule.cpp index 9f9871b411..58cd3620c9 100644 --- a/src/swordfish/modules/estop/EStopModule.cpp +++ b/src/swordfish/modules/estop/EStopModule.cpp @@ -7,6 +7,7 @@ #define HAS_Z_BRAKE 1 +#include #include #include #include @@ -16,10 +17,12 @@ #include #include +#include #include namespace swordfish::estop { using namespace swordfish::tools; + using namespace swordfish::status; EStopModule* EStopModule::__instance = nullptr; @@ -39,6 +42,14 @@ namespace swordfish::estop { _pack(__schema, *this, &(Module::_pack)), _estopISR(std::bind(&EStopModule::handleEStop, this), ESTOP_PIN, CHANGE, false), _triggered(readPin()) { + + if (_triggered) { + StatusModule::getInstance().set_state(MachineState::EmergencyStop); + } + } + + void EStopModule::idle() { + checkOrClear(); } void EStopModule::handleEStop() { @@ -58,17 +69,22 @@ namespace swordfish::estop { planner.quick_stop(); planner.clear_block_buffer(); queue.clear(); + gcode.abort_current(); set_axis_never_homed(X_AXIS); set_axis_never_homed(Y_AXIS); set_axis_never_homed(Z_AXIS); + + auto& statusModule = StatusModule::getInstance(); + + statusModule.set_state(MachineState::EmergencyStop); } } bool EStopModule::checkOrClear() { __disable_irq(); - if (_triggered && readPin()) { + if (/*_triggered && */readPin()) { __enable_irq(); return false; @@ -78,10 +94,12 @@ namespace swordfish::estop { _triggered = false; auto& toolsModule = ToolsModule::getInstance(); + auto& statusModule = StatusModule::getInstance(); auto& driver = toolsModule.getCurrentDriver(); stepper.wake_up(); driver.emergencyClear(); + statusModule.set_state(MachineState::Idle); debug()("estop cleared"); } @@ -92,6 +110,8 @@ namespace swordfish::estop { } void EStopModule::throwIfTriggered() { + GcodeSuite::throwIfAborted(); + if (!checkOrClear()) { throw EStopException(); } diff --git a/src/swordfish/modules/estop/EStopModule.h b/src/swordfish/modules/estop/EStopModule.h index 9adfa409b1..497f018863 100644 --- a/src/swordfish/modules/estop/EStopModule.h +++ b/src/swordfish/modules/estop/EStopModule.h @@ -45,7 +45,9 @@ namespace swordfish::estop { virtual const char* name() override { return "Emergency Stop"; } + virtual void init() override; + virtual void idle() override; bool isTriggered() { return _triggered; diff --git a/src/swordfish/modules/gcode/CommandException.cpp b/src/swordfish/modules/gcode/CommandException.cpp index 333b31a93f..7f149b0db2 100644 --- a/src/swordfish/modules/gcode/CommandException.cpp +++ b/src/swordfish/modules/gcode/CommandException.cpp @@ -3,13 +3,13 @@ * * Created: 10/11/2021 12:25:06 pm * Author: smohekey - */ + */ #include #include "CommandException.h" -namespace swordfish::gcode { +namespace swordfish { void CommandException::writeType(io::Writer& writer) const { writer << "CommandException"; } diff --git a/src/swordfish/modules/gcode/CommandException.h b/src/swordfish/modules/gcode/CommandException.h index 2728e6ac07..ee83b7a107 100644 --- a/src/swordfish/modules/gcode/CommandException.h +++ b/src/swordfish/modules/gcode/CommandException.h @@ -3,26 +3,26 @@ * * Created: 10/11/2021 12:23:08 pm * Author: smohekey - */ + */ #pragma once #include -namespace swordfish::gcode { +namespace swordfish { class CommandException : public Exception { private: const char* _message; - + protected: virtual void writeType(io::Writer& writer) const override; virtual void writeMessage(io::Writer& writer) const override; - + public: CommandException(const char* message) : _message(message) { - + } - + virtual ~CommandException() { } }; } \ No newline at end of file diff --git a/src/swordfish/modules/motion/MotionModule.cpp b/src/swordfish/modules/motion/MotionModule.cpp index 4702cdfcdb..62196da413 100644 --- a/src/swordfish/modules/motion/MotionModule.cpp +++ b/src/swordfish/modules/motion/MotionModule.cpp @@ -9,6 +9,7 @@ #include "MotionModule.h" +#include #include #include #include @@ -17,12 +18,14 @@ extern float32_t rapidrate_mm_s; #include #include +#include namespace swordfish::motion { using namespace Eigen; using namespace swordfish::core; using namespace swordfish::estop; + using namespace swordfish::status; using namespace swordfish::utils; MotionModule* MotionModule::__instance = nullptr; @@ -102,39 +105,7 @@ namespace swordfish::motion { } void MotionModule::move(Movement movement) { - /*EStopModule::getInstance().throwIfTriggered(); - - debug()("current -> x: ", current_position.x, ", y: ", current_position.y, ", z: ", current_position.z, ", feedRate: ", feedrate_mm_s); - debug()("requested -> x: ", movement.x, ", y: ", movement.y, ", z: ", movement.z, ", feedRate: ", movement.feedRate, ", relative: ", movement.relative); - - Vector3f dest = { - isnan(movement.x) ? current_position.x : (movement.relative ? current_position.x + movement.x : movement.x - _offset(X)), - isnan(movement.y) ? current_position.y : (movement.relative ? current_position.y + movement.y : movement.y - _offset(Y)), - isnan(movement.z) ? current_position.z : (movement.relative ? current_position.z + movement.z : movement.z - _offset(Z)) - }; - - _limits.throwIfOutside(dest); - - destination.x = dest(X); - destination.y = dest(Y); - destination.z = dest(Z); - - feedRate_t old_feedrate = feedrate_mm_s; - - try { - feedrate_mm_s = isnan(movement.feedRate) ? feedrate_mm_s : movement.feedRate; - - debug()("actual -> x: ", destination.x, ", y: ", destination.y, ", z: ", destination.z, ", f: ", feedrate_mm_s); - - prepare_line_to_destination(); - planner.synchronize(); - } catch { - feedrate_mm_s = old_feedrate; - - throw; - }*/ - - // EStopModule::getInstance().throwIfTriggered(); + gcode.throwIfAborted(); Vector4f currentNative { current_position.x, current_position.y, current_position.z, 1 }; Vector4f currentLogical = _logicalTransform * currentNative; @@ -170,6 +141,7 @@ namespace swordfish::motion { target, MMS_SCALED(isnan(movement.feedRate) ? feedrate_mm_s : movement.feedRate), active_extruder, + movement.state, 0.0, isnan(movement.accel_mm_s2) ? 0.0 : movement.accel_mm_s2); @@ -284,7 +256,8 @@ namespace swordfish::motion { .z = movement.z, .feedRate = isnan(movement.feedRate) ? rapidrate_mm_s : movement.feedRate, .relativeAxes = movement.relativeAxes, - .accel_mm_s2 = isnan(movement.accel_mm_s2) ? planner.settings.travel_acceleration : movement.accel_mm_s2 }); + .accel_mm_s2 = isnan(movement.accel_mm_s2) ? planner.settings.travel_acceleration : movement.accel_mm_s2, + .state = MachineState::RapidMove }); } void MotionModule::feedMove(Movement movement) { @@ -293,6 +266,7 @@ namespace swordfish::motion { .z = movement.z, .feedRate = isnan(movement.feedRate) ? feedrate_mm_s : movement.feedRate, .relativeAxes = movement.relativeAxes, - .accel_mm_s2 = isnan(movement.accel_mm_s2) ? planner.settings.acceleration : movement.accel_mm_s2 }); + .accel_mm_s2 = isnan(movement.accel_mm_s2) ? planner.settings.acceleration : movement.accel_mm_s2, + .state = MachineState::FeedMove }); } } // namespace swordfish::motion \ No newline at end of file diff --git a/src/swordfish/modules/motion/MotionModule.h b/src/swordfish/modules/motion/MotionModule.h index 5d674d680c..734ddb6b74 100644 --- a/src/swordfish/modules/motion/MotionModule.h +++ b/src/swordfish/modules/motion/MotionModule.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "CoordinateSystem.h" #include "CoordinateSystemTable.h" @@ -50,6 +51,7 @@ namespace swordfish::motion { float32_t feedRate = NaN; utils::Flags relativeAxes = AxisSelector::None; float32_t accel_mm_s2 = NaN; + swordfish::status::MachineState state; }; class Limits; diff --git a/src/swordfish/modules/status/CmakeLists.txt b/src/swordfish/modules/status/CmakeLists.txt new file mode 100644 index 0000000000..7dc297228c --- /dev/null +++ b/src/swordfish/modules/status/CmakeLists.txt @@ -0,0 +1,9 @@ +target_sources(${PROJECT_NAME}.elf + PRIVATE + Color.cpp + Color.h + StatusModule.cpp + StatusModule.h + WS2812Driver.cpp + WS2812Driver.h +) diff --git a/src/swordfish/modules/status/Color.cpp b/src/swordfish/modules/status/Color.cpp new file mode 100644 index 0000000000..8d14bafb6f --- /dev/null +++ b/src/swordfish/modules/status/Color.cpp @@ -0,0 +1,207 @@ +#include +#include "Color.h" +#include + +namespace swordfish::status { + Hsl Rgb::to_hsl() { + float32_t r = this->r; + float32_t g = this->g; + float32_t b = this->b; + + float32_t min = std::min(r, std::min(g, b)); + float32_t max = std::max(r, std::max(g, b)); + float32_t delta = max - min; + + float32_t h = 0.0; + float32_t s = 0.0; + float32_t l = (max + min) / 2; + + if (delta == 0) { + h = s = 0; + } + else { + if (l < 0.5) { + s = delta / (max + min) * 100; + } + else { + s = delta / (1 - std::abs(2 * l - 1)) * 100; + } + + if (r == max) { + h = (g - b) / delta; + } + else if (g == max) { + h = (b - r) / delta + 2; + } + else if (b == max) { + h = (r - g) / delta + 4; + } + h = fmod(60 * h + 360, 360); + } + l *= 100; + + return Hsl { h, s, l }; + } + + Hsv Rgb::to_hsv() { + float32_t r = this->r; + float32_t g = this->g; + float32_t b = this->b; + + float32_t min = std::min(r, std::min(g, b)); + float32_t max = std::max(r, std::max(g, b)); + float32_t delta = max - min; + + float32_t h = 0.0; + float32_t s = (max > 1e-3) ? (delta / max) : 0; + float32_t v = max; + + if (delta == 0) { + h = 0; + } else { + if (r == max) { + h = (g - b) / delta; + } + else if (g == max) { + h = 2 + (b - r) / delta; + } + else if (b == max) { + h = 4 + (r - g) / delta; + } + + h *= 60; + h = std::fmod(h + 360, 360); + } + + return Hsv { + h, s, v + }; + } + + uint32_t Rgb::to_packed() { + const auto [r, g, b] = to_rgb_u8(); + + return ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b; + } + + std::tuple Rgb::to_rgb_u8() { + return { + (uint8_t)(std::clamp(r, 0.0f, 1.0f) * 255.0), + (uint8_t)(std::clamp(g, 0.0f, 1.0f) * 255.0), + (uint8_t)(std::clamp(b, 0.0f, 1.0f) * 255.0) + }; + } + + Rgb Rgb::from_rgb_u8(uint8_t r, uint8_t g, uint8_t b) { + return Rgb { + r: r / 255.0f, + g: g / 255.0f, + b: b / 255.0f + }; + } + + float32_t hue_to_rgb(float32_t v1, float32_t v2, float32_t vh) { + if (vh < 0) vh += 1; + if (vh > 1) vh -= 1; + + if (6 * vh < 1) { + return v1 + (v2 - v1) * 6 * vh; + } + + if (2 * vh < 1) { + return v2; + } + + if (3 * vh < 2) { + return v1 + (v2 - v1)*(2.0 / 3.0 - vh) * 6; + } + + return v1; + } + + Rgb Hsl::to_rgb() { + float32_t h = this->h / 360; + float32_t s = this->s / 100; + float32_t l = this->l / 100; + + float32_t r = 0; + float32_t g = 0; + float32_t b = 0; + + if (s == 0) { + r = g = b = l; + } else { + float32_t temp1, temp2; + + temp2 = (l < 0.5) ? (l*(1 + s)) : (l + s - (s*l)); + temp1 = 2 * l - temp2; + + r = hue_to_rgb(temp1, temp2, h + 1.0 / 3.0); + g = hue_to_rgb(temp1, temp2, h); + b = hue_to_rgb(temp1, temp2, h - 1.0 / 3.0); + } + + return Rgb { r, g, b }; + } + + Rgb Hsv::to_rgb() { + int range = (int)floor(this->h / 60); + float32_t c = this->v * this->s; + float32_t x = c * (1 - std::abs(std::fmod(this->h / 60, 2) - 1)); + float32_t m = this->v - c; + + float32_t r, g, b; + + switch (range) { + case 0: { + r = (c + m); + g = (x + m); + b = m; + + break; + } + + case 1: { + r = (x + m); + g = (c + m); + b = m; + + break; + } + + case 2: { + r = m; + g = (c + m); + b = (x + m); + + break; + } + + case 3: { + r = m; + g = (x + m); + b = (c + m); + + break; + } + + case 4: { + r = (x + m); + g = m; + b = (c + m); + + break; + } + + default: { + r = (c + m); + g = m; + b = (x + m); + + break; + } + } + + return Rgb { r, g, b }; + } +} \ No newline at end of file diff --git a/src/swordfish/modules/status/Color.h b/src/swordfish/modules/status/Color.h new file mode 100644 index 0000000000..a85c64ee07 --- /dev/null +++ b/src/swordfish/modules/status/Color.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +namespace swordfish::status { + class Hsl; + class Hsv; + + class Rgb { + public: + float32_t r; + float32_t g; + float32_t b; + + Hsl to_hsl(); + Hsv to_hsv(); + + uint32_t to_packed(); + + std::tuple to_rgb_u8(); + + static Rgb from_rgb_u8(uint8_t r, uint8_t g, uint8_t b); + }; + + class Hsl { + public: + float32_t h; + float32_t s; + float32_t l; + + Rgb to_rgb(); + }; + + class Hsv { + public: + float32_t h; + float32_t s; + float32_t v; + + Rgb to_rgb(); + }; +} \ No newline at end of file diff --git a/src/swordfish/modules/status/StatusModule.cpp b/src/swordfish/modules/status/StatusModule.cpp new file mode 100644 index 0000000000..838cc987af --- /dev/null +++ b/src/swordfish/modules/status/StatusModule.cpp @@ -0,0 +1,193 @@ +/* + * StatusModule.cpp + * + * Created: 30/09/2021 9:48:01 am + * Author: smohekey + */ + +#include "Color.h" +#include "StatusModule.h" +#include +#include + +namespace swordfish::status { + using swordfish::estop::EStopModule; + + core::ValidatedValueField StatusModule::led_count_field__ = { "ledCount", 0, 0, led_count_changed }; + core::ValidatedValueField StatusModule::led_brightness_field__ = { "ledBrightness", 2, 128, led_brightness_changed }; + core::ValidatedValueField StatusModule::led_sweep_time_field__ { "ledSweepTime", 3, 2000, led_sweep_time_changed }; + + StatusModule* StatusModule::instance__ = nullptr; + + core::Schema StatusModule::schema__ = { + utils::typeName(), + &(Module::__schema), { + led_count_field__, + led_brightness_field__, + led_sweep_time_field__, + }, { + + } + }; + + void StatusModule::led_count_changed(uint16_t old_led_count, uint16_t led_count) { + auto& status_module = StatusModule::getInstance(); + + status_module.driver_.set_led_count(led_count); + } + + void StatusModule::led_brightness_changed(uint8_t old_led_brightness, uint8_t led_brightness) { + auto& status_module = StatusModule::getInstance(); + + status_module.driver_.set_brightness(led_brightness); + } + + void StatusModule::led_sweep_time_changed(uint16_t old_led_sweep_time, uint16_t led_sweep_time) { + auto& status_module = StatusModule::getInstance(); + + status_module.driver_.set_sweep_time(led_sweep_time); + } + + StatusModule::StatusModule(core::Object* parent) : + Module(parent), + pack_(schema__, *this, &(Module::_pack)), + driver_(led_count_field__.get(pack_), led_brightness_field__.get(pack_), led_sweep_time_field__.get(pack_)), + state_ { MachineState::Idle } { + + } + + void StatusModule::update() { + switch (state_) { + case MachineState::Idle: { + //debug()("MachineState::Idle"); + + driver_.set_color(0, 255, 0); + driver_.set_sweep(true); + + break; + } + + case MachineState::EmergencyStop: { + //debug()("MachineState::EmergencyStop"); + + driver_.set_color(255, 0, 0); + driver_.set_sweep(false); + + break; + } + + case MachineState::FeedMove: { + //debug()("MachineState::FeedMove"); + + driver_.set_color(0, 255, 0); + driver_.set_sweep(false); + + break; + } + + case MachineState::RapidMove: { + //debug()("MachineState::RapidMove"); + + driver_.set_color(128, 128, 0); + driver_.set_sweep(false); + + break; + } + + case MachineState::Homing: { + //debug()("MachineState::Homing"); + + driver_.set_color(0, 0, 255); + driver_.set_sweep(true); + + break; + } + + case MachineState::AwaitingInput: { + //debug()("MaachineState::AwaitingInput"); + + driver_.set_color(0, 128, 128); + driver_.set_sweep(false); + + break; + } + + case MachineState::SpindleRamp: { + //debug()("MachineState::SpindleRamp"); + + driver_.set_color(128, 128, 128); + driver_.set_sweep(false); + + break; + } + + case MachineState::Probing: { + //debug()("MachineState::Probing"); + + driver_.set_color(16, 16, 255); + driver_.set_sweep(true); + + break; + } + } + } + + void StatusModule::set_state(MachineState state) { + __disable_irq(); + + //state_.clear(); + //state_.push_back(state); + state_ = state; + + update(); + + __enable_irq(); + } + + /*void StatusModule::push_state(MachineState state) { + __disable_irq(); + + state_.push_back(state); + + update(); + + __enable_irq(); + }*/ + + MachineState& StatusModule::peek_state() { + return state_; + } + + /*void StatusModule::pop_state() { + __disable_irq(); + + if (state_.size() > 1) { + state_.pop_back(); + + update(); + } else { + //debug()("no state to pop"); + } + + __enable_irq(); + }*/ + + void StatusModule::read(io::InputStream& stream) { + Module::read(stream); + + driver_.set_led_count(led_count_field__.get(pack_)); + driver_.set_brightness(led_brightness_field__.get(pack_)); + driver_.set_sweep_time(led_sweep_time_field__.get(pack_)); + } + + void StatusModule::init() { + update(); + + driver_.init(); + } + + swordfish::status::StatusModule& StatusModule::getInstance(core::Object* parent) { + return *(instance__ ?: instance__ = new StatusModule(parent)); + } +} + diff --git a/src/swordfish/modules/status/StatusModule.h b/src/swordfish/modules/status/StatusModule.h new file mode 100644 index 0000000000..7e8844b4e1 --- /dev/null +++ b/src/swordfish/modules/status/StatusModule.h @@ -0,0 +1,104 @@ +/* + * StatusModule.h + * + * Created: 30/09/2021 8:52:21 am + * Author: smohekey + */ + + +#pragma once + +#include +#include +#include +#include + +#include "WS2812Driver.h" + +namespace swordfish::status { + enum class MachineState { + Idle, + EmergencyStop, + FeedMove, + RapidMove, + Homing, + AwaitingInput, + SpindleRamp, + Probing, + }; + + class StatusModule : public Module { + private: + static core::ValidatedValueField led_count_field__; + static core::ValidatedValueField led_brightness_field__; + static core::ValidatedValueField led_sweep_time_field__; + + static StatusModule* instance__; + + static void led_count_changed(uint16_t old_led_count, uint16_t led_count); + static void led_brightness_changed(uint8_t old_led_brightness, uint8_t led_brightness); + static void led_sweep_time_changed(uint16_t old_led_sweep_time, uint16_t led_sweep_time); + + StatusModule(core::Object* parent); + + protected: + friend WS2812Driver; + + static core::Schema schema__; + + core::Pack pack_; + WS2812Driver driver_; + //std::vector state_; + MachineState state_; + + core::Pack& getPack() override { + return pack_; + } + + void update(); + + public: + virtual ~StatusModule() { } + + WS2812Driver& driver() { + return driver_; + } + + void set_state(MachineState state); + //void push_state(MachineState state); + MachineState& peek_state(); + //void pop_state(); + + virtual const char* name() override { return "Status"; } + virtual void init() override; + virtual void read(io::InputStream& stream) override; + + static StatusModule& getInstance(core::Object* parent = nullptr); + }; + + class TemporaryState { + private: + MachineState old_state_; + + public: + TemporaryState(MachineState temporary_state) { + auto& status_module = StatusModule::getInstance(); + + old_state_ = status_module.peek_state(); + + status_module.set_state(temporary_state); + } + + ~TemporaryState() { + restore(); + } + + inline void restore() { + if (!swordfish::estop::EStopModule::getInstance().checkOrClear()) { + StatusModule::getInstance().set_state(MachineState::EmergencyStop); + } else { + StatusModule::getInstance().set_state(old_state_); + } + } + }; +} \ No newline at end of file diff --git a/src/swordfish/modules/status/WS2812Driver.cpp b/src/swordfish/modules/status/WS2812Driver.cpp new file mode 100644 index 0000000000..5ec8063d34 --- /dev/null +++ b/src/swordfish/modules/status/WS2812Driver.cpp @@ -0,0 +1,284 @@ +#include +#include + +#include "StatusModule.h" +#include "WS2812Driver.h" + +namespace swordfish::status { + static const u8 gamma_table__[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, + 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, + 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81, + 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96, 97, 99, 100, 102, + 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, + 127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148, 150, 152, + 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, + 184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215, + 218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252, + 255}; + + WS2812Driver::WS2812Driver(u16 led_count, u8 led_brightness, u16 sweep_time) : + dma_desc_ { nullptr, nullptr }, + led_count_(led_count), + buffer_length_(0), + frame_period_(0), + buffers_ { nullptr, nullptr }, + active_buffer_(0), + active_r_(0), + active_g_(255), + active_b_(0), + brightness_(255), + counter_(0), + sweep_(false), + reverse_(false) + { + set_led_count(led_count); + set_sweep_time(sweep_time); + } + + void WS2812Driver::set_led_count(u16 led_count) { + debug()("led_count: ", led_count); + + led_count_ = led_count; + buffer_length_ = (led_count + 40) * 3 * 4; + frame_period_ = (u32)(3000000/buffer_length_); + + if(buffers_[0]) { + delete buffers_[0]; + } + + if(buffers_[1]) { + delete buffers_[1]; + } + + buffers_[0] = new u8[buffer_length_]; + buffers_[1] = new u8[buffer_length_]; + + memset(buffers_[0], 0x00, buffer_length_); + memset(buffers_[1], 0x00, buffer_length_); + + // reconfigure DMAC + + if(dma_desc_[0]) { + dma_.changeDescriptor(dma_desc_[0], buffers_[0], (void *)&I2S->TXDATA.reg, buffer_length_); + } + + if(dma_desc_[1]) { + dma_.changeDescriptor(dma_desc_[1], buffers_[1], (void *)&I2S->TXDATA.reg, buffer_length_); + } + } + + void WS2812Driver::set_color(u8 r, u8 g, u8 b) { + active_r_ = r; + active_g_ = g; + active_b_ = b; + } + + void WS2812Driver::set_sweep(bool sweep) { + sweep_ = sweep; + } + + void WS2812Driver::set_brightness(u8 brightness) { + brightness_ = brightness; + } + + void WS2812Driver::set_sweep_time(u16 sweep_time) { + sweep_time_ = (u32)((f32)sweep_time / 3.0f); + + debug()("sweep_time: ", sweep_time_); + } + + void dma_callback(Adafruit_ZeroDMA *dma) { + (void) dma; + + auto& driver = StatusModule::getInstance().driver(); + + driver.update(); + } + + void WS2812Driver::init() { + dma_.setTrigger(I2S_DMAC_ID_TX_0); + dma_.setAction(DMA_TRIGGER_ACTON_BEAT); + dma_.allocate(); + + dma_desc_[0] = dma_.addDescriptor(buffers_[0], (void *)&I2S->TXDATA.reg, buffer_length_, DMA_BEAT_SIZE_BYTE, true, false); + dma_desc_[1] = dma_.addDescriptor(buffers_[1], (void *)&I2S->TXDATA.reg, buffer_length_, DMA_BEAT_SIZE_BYTE, true, false); + + dma_desc_[0]->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_INT; + dma_desc_[1]->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_INT; + + dma_.loop(true); + dma_.setCallback(dma_callback); + + // enable I2S SDO on port PA21 (D32) + PORT->Group[0].PINCFG[21].bit.PMUXEN = 1; + PORT->Group[0].PMUX[21 >> 1].bit.PMUXO = 0x9; + + // enable I2S FS on port PA20 (D33) + //PORT->Group[0].PINCFG[20].bit.PMUXEN = 1; + //PORT->Group[0].PMUX[20 >> 1].bit.PMUXE = 0x9; + + // TEMPORARY + // enable I2S SCK on port PB12 (D18) + //PORT->Group[1].PINCFG[12].bit.PMUXEN = 1; + //PORT->Group[1].PMUX[12 >> 1].bit.PMUXE = 0x9; + + // enable APBD for I2S + MCLK->APBDMASK.bit.I2S_ = true; + + // connect 12MHz clock generator to I2S + GCLK->PCHCTRL[I2S_GCLK_ID_0].reg = GCLK_PCHCTRL_GEN(4) | GCLK_PCHCTRL_CHEN; + while (0 == (GCLK->PCHCTRL[I2S_GCLK_ID_0].reg & GCLK_PCHCTRL_CHEN)); + + GCLK->PCHCTRL[I2S_GCLK_ID_1].reg = GCLK_PCHCTRL_GEN(4) | GCLK_PCHCTRL_CHEN; + while (0 == (GCLK->PCHCTRL[I2S_GCLK_ID_1].reg & GCLK_PCHCTRL_CHEN)); + + // reset I2S + I2S->CTRLA.bit.SWRST = true; + while (I2S->SYNCBUSY.bit.SWRST); + + // configure I2S clocks + I2S->CLKCTRL[0].reg = I2S_CLKCTRL_SLOTSIZE_8 + | I2S_CLKCTRL_NBSLOTS(1) + | I2S_CLKCTRL_MCKEN + | I2S_CLKCTRL_MCKSEL_GCLK + | I2S_CLKCTRL_SCKSEL_MCKDIV + | I2S_CLKCTRL_FSSEL_SCKDIV + | I2S_CLKCTRL_MCKOUTDIV(0) + | I2S_CLKCTRL_MCKDIV(3); + + I2S->TXCTRL.reg = I2S_TXCTRL_MONO_STEREO + | I2S_TXCTRL_DATASIZE_8 + | I2S_TXCTRL_TXSAME_ZERO + | I2S_TXCTRL_TXDEFAULT_ZERO; + + I2S->CTRLA.bit.ENABLE = true; + while(I2S->SYNCBUSY.bit.ENABLE); + + I2S->CTRLA.bit.CKEN0 = true; + while(I2S->SYNCBUSY.bit.CKEN0); + + I2S->CTRLA.bit.CKEN1 = true; + while(I2S->SYNCBUSY.bit.CKEN1); + + I2S->CTRLA.bit.TXEN = true; + while(I2S->SYNCBUSY.bit.TXEN); + + dma_.startJob(); + } + + void WS2812Driver::write_u8(u8 value) { + static constexpr u32 PATTERNS[] = {0b10001000, 0b10001110, 0b11101000, 0b11101110}; + + //value = gamma_table__[value]; + + for(auto i = 0; i < 4; i ++) { + auto bits = (value & 0b11000000) >> 6; + + buffers_[active_buffer_][buffer_index_++] = PATTERNS[bits]; + + value <<= 2; + } + } + + void WS2812Driver::write_color(u8 r, u8 g, u8 b) { + write_u8(g > brightness_ ? brightness_ : g); + write_u8(r > brightness_ ? brightness_ : r); + write_u8(b > brightness_ ? brightness_ : b); + } + + f32 lerp(f32 start, f32 end, f32 fraction) { + return (start + (end - start) * fraction); + } + + f32 ease_in(f32 t) { + return t * t; + } + + f32 flip(f32 x) { + return 1.0f - x; + } + + f32 ease_out(f32 t) { + auto v = flip(t); + + return flip(v * v); + } + + f32 ease_in_out(f32 t) { + return lerp(ease_in(t), ease_out(t), t); + } + + f32 ease_out_in(f32 t) { + return lerp(ease_out(t), ease_in(t), t); + } + + f32 ease_in_out_exp(f32 t) { + return t == 0.0f + ? 0.0f + : t == 1.0f + ? 1.0f + : t < 0.5f ? powf(2, 20 * t - 10) / 2 + : (2 - powf(2, -20 * t + 10)) / 2; + } + + void WS2812Driver::update() { + active_buffer_ = 1 - active_buffer_; + buffer_index_ = 0; + + const u32 tail_length_ = 20; + + if (sweep_) { + u32 progress = counter_ % sweep_time_; + f32 global_t = (f32)progress / (f32)sweep_time_; + + if (progress == 0) { + reverse_ = !reverse_; + } + + u32 vled_count = led_count_ + tail_length_ + 2; + i32 head = (i32)((f32)vled_count * global_t); + i32 tail = head - tail_length_; + + if (reverse_) { + tail = led_count_ - head; + head = tail + tail_length_; + } + + for (i32 i = 0; i < led_count_; i ++) { + + if (tail <= i && i < head) { + f32 t = std::fmod((f32)((i - tail) % tail_length_) / (float32_t)tail_length_, 1.0f); + + if (reverse_) { + t = 1.0f - t; + } + + f32 v = ease_in_out(t); + + write_color( + (u8)(active_r_ * v), + (u8)(active_g_ * v), + (u8)(active_b_ * v) + ); + } else { + write_color(0, 0, 0); + } + } + } else { + for (auto i = 0; i < led_count_; i ++) { + write_color(active_r_, active_g_, active_b_); + } + } + + counter_ += 1; //frame_period_; + } +} diff --git a/src/swordfish/modules/status/WS2812Driver.h b/src/swordfish/modules/status/WS2812Driver.h new file mode 100644 index 0000000000..e1ecc7bd2c --- /dev/null +++ b/src/swordfish/modules/status/WS2812Driver.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#include + +#include + +#include "Color.h" + +namespace swordfish::status { + class WS2812Driver { + private: + Adafruit_ZeroDMA dma_; + DmacDescriptor* dma_desc_[2]; + u16 led_count_; + usize buffer_length_; + u32 frame_period_; + u32 sweep_time_; + u8* buffers_[2]; + usize active_buffer_; + usize buffer_index_; + u8 active_r_; + u8 active_g_; + u8 active_b_; + u8 brightness_; + u32 counter_; + bool sweep_; + bool reverse_; + + void write_u8(u8 value); + void write_color(u8 r, u8 g, u8 b); + + public: + WS2812Driver(u16 led_count, u8 led_brightness, u16 sweep_time); + + void set_led_count(u16 led_count); + void set_sweep_time(u16 sweep_time); + void set_color(u8 r, u8 g, u8 b); + void set_sweep(bool sweep); + void set_brightness(u8 brightness); + void init(); + + void update(); + }; +} \ No newline at end of file diff --git a/src/swordfish/modules/tools/DriverParameterDefinition.h b/src/swordfish/modules/tools/DriverParameterDefinition.h index a657521081..0d6a2add98 100644 --- a/src/swordfish/modules/tools/DriverParameterDefinition.h +++ b/src/swordfish/modules/tools/DriverParameterDefinition.h @@ -3,18 +3,20 @@ * * Created: 18/10/2021 1:40:30 pm * Author: smohekey - */ + */ #pragma once +#include + namespace swordfish::tools { enum class DriverParameterType { Integer, - String, + String, }; - + struct DriverParameterDefinition { - const uint16_t id; + const u16 id; const char* name; const DriverParameterType type; }; diff --git a/src/swordfish/modules/tools/ToolsModule.cpp b/src/swordfish/modules/tools/ToolsModule.cpp index 9d683ad1ab..749c8a4016 100644 --- a/src/swordfish/modules/tools/ToolsModule.cpp +++ b/src/swordfish/modules/tools/ToolsModule.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "ToolsModule.h" @@ -38,6 +39,7 @@ namespace swordfish::tools { using namespace swordfish::estop; using namespace swordfish::motion; using namespace swordfish::utils; + using namespace swordfish::status; ToolsModule* ToolsModule::__instance = nullptr; @@ -510,7 +512,7 @@ namespace swordfish::tools { loadTool(*nextTool); } } - } catch (EStopException& e) { + } catch (Exception& e) { } motionModule.setActiveCoordinateSystem(oldWCS); @@ -621,7 +623,7 @@ namespace swordfish::tools { _flags[HomingFlag] = true; - motionModule.move({ .x = 100, .feedRate = homing_feedrate(X_AXIS), .relativeAxes = AxisSelector::All }); + motionModule.move({ .x = 100, .feedRate = homing_feedrate(X_AXIS), .relativeAxes = AxisSelector::All, .state = MachineState::Homing }); planner.synchronize(); diff --git a/src/swordfish/types.h b/src/swordfish/types.h index 360ae58bce..beab7371ee 100644 --- a/src/swordfish/types.h +++ b/src/swordfish/types.h @@ -3,7 +3,7 @@ * * Created: 8/08/2021 4:49:56 pm * Author: smohekey - */ + */ #pragma once @@ -16,6 +16,21 @@ typedef float float32_t; typedef double float64_t; +typedef size_t usize; + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef float f32; +typedef double f64; + typedef int64_t offset_t; enum {