diff --git a/makefiles/virtual/uCNC.dev b/makefiles/virtual/uCNC.dev index 32ec8f46c..3b2c21fbc 100644 --- a/makefiles/virtual/uCNC.dev +++ b/makefiles/virtual/uCNC.dev @@ -29,7 +29,7 @@ IncludeVersionInfo=0 SupportXPThemes=0 CompilerSet=1 CompilerSettings=000000e0a0000000001000000 -UnitCount=81 +UnitCount=80 [VersionInfo] Major=1 diff --git a/uCNC/cnc_config.h b/uCNC/cnc_config.h index 81382af12..86100348e 100644 --- a/uCNC/cnc_config.h +++ b/uCNC/cnc_config.h @@ -210,6 +210,13 @@ extern "C" // #define DEFAULT_LASER_PPI 254 // #define DEFAULT_LASER_PPI_USWIDTH 1500 +/** + * + * Enables Plasma THC capabilities + * + * **/ +// #define ENABLE_PLASMA_THC + /** * Feed overrides increments and percentage ranges * */ @@ -312,7 +319,13 @@ extern "C" // #define ENABLE_IO_MODULES // #define ENABLE_PARSER_MODULES // #define ENABLE_MOTION_CONTROL_MODULES -// #define ENABLE_SETTINGS_MODULES + + /** + * Settings extensions are enabled by default + * Uncomment to disable this extension. + * Some option might override this (like ENABLE_TOOL_PID_CONTROLLER) + * */ +// #define DISABLE_SETTINGS_MODULES /** * Report specific options diff --git a/uCNC/cnc_hal_config.h b/uCNC/cnc_hal_config.h index 246e75dd0..c69b503a7 100644 --- a/uCNC/cnc_hal_config.h +++ b/uCNC/cnc_hal_config.h @@ -133,13 +133,6 @@ extern "C" // #define INVERT_LASER_PPI_LOGIC #endif -/** - * - * Enables Plasma THC capabilities - * - * **/ -// #define ENABLE_PLASMA_THC - /** * * Tool pallete diff --git a/uCNC/src/README.md b/uCNC/src/README.md index 491daf25f..c85cfad69 100644 --- a/uCNC/src/README.md +++ b/uCNC/src/README.md @@ -12,6 +12,7 @@ These files contain initialization code for all modules that extend µCNC functi _**Jump to section**_ * [Adding custom modules to µCNC](#adding-custom-modules-to-µcnc) * [µCNC existing events/delegates](#µcnc-existing-eventsdelegates) + * [µCNC existing hooks](#µcnc-existing-hooks) * [modules.h and events](#modulesh-and-events) * [Creating a new custom event listener](#creating-a-new-custom-event-listener) * [Creating a new custom event](#creating-a-new-custom-event) @@ -25,6 +26,7 @@ __NOTE__: _Version 1.4.6 implemented changes to module initialization. Also addi µCNC has implemented a module system that allows the user to perform custom actions that get executed in an event/delegate fashion style similar to what is done with C#. Multiple callbacks functions can be attached to the same event. These modules can be quite useful and perform several things like adding custom custom gcodes to perform actions, or modifying IO states if a given condition is verified. µCNC already has a few useful modules like PID controller, Encoder module, TMC drivers support and custom G/M code support. +Version 1.8 also introduces the concept of simple hooks. These hooks are simple function pointers that execute the assigned callback at that time. They are usually used inside interrupt service routines and provide a way to extend ISR's with small extra code blocks to perform certain tasks. Unlike events, simple hooks can only run a single callback. The active callback is the last one to attach to any give hook. ## µCNC existing events/delegates @@ -184,6 +186,18 @@ typedef struct } motion_data_t; ``` +## µCNC existing hooks + +These are the list of available hooks inside + +__NOTE__: Not all simple hooks may be listed here. To find all available simple hooks declarations, do a search on all files (on VSCode in Windows it's Ctrl+Shift+F) of the project of `DECL_HOOK`. You can also search for the `HOOK_INVOKE` to see what argument is being passed to the simple hook handler. + +| Event name | Argument | Enable option | Description | +| --- | --- | --- | --- | +| itp_rt_pre_stepbits | int*, int* | ENABLE_RT_SYNC_MOTIONS | Fires when the next computed step bits and dirs have been computed to be output. Args are a pointer the stepbit var and a pointer to a dirbit var | +| itp_rt_stepbits | int, int | ENABLE_RT_SYNC_MOTIONS | Fires when the setpbits have been output to the IO. Args are the stepbit mask value and the step ISR flags value | +| encoder_index | void | ENCODER_COUNT | Fires when the index of the specialized rpm encoder is triggered. Has no args | + ## modules.h and events `src/module.h` exposes a few handy macros that make event listeners, or custom events creations easy. diff --git a/uCNC/src/cnc_hal_config_helper.h b/uCNC/src/cnc_hal_config_helper.h index ccfb7fd87..35286a053 100644 --- a/uCNC/src/cnc_hal_config_helper.h +++ b/uCNC/src/cnc_hal_config_helper.h @@ -447,7 +447,9 @@ extern "C" /*laser ppi*/ #if (TOOL_COUNT < 1) #undef ENABLE_LASER_PPI +#undef ENABLE_PLASMA_THC #endif + #ifdef ENABLE_LASER_PPI #ifndef MCU_HAS_ONESHOT_TIMER #error "The current MCU does not support ONESHOT_TIMER or the ONESHOT_TIMER is not configured" @@ -2121,8 +2123,18 @@ typedef uint16_t step_t; #endif #endif -#ifdef ENABLE_PLASMA_THC +#ifndef DISABLE_SETTINGS_MODULES +#define ENABLE_SETTINGS_MODULES +#endif +#ifdef ENABLE_LASER_PPI +// forces modes +#ifndef ENABLE_RT_SYNC_MOTIONS +#define ENABLE_RT_SYNC_MOTIONS +#endif +#endif + +#ifdef ENABLE_PLASMA_THC // forces modes #ifndef ENABLE_TOOL_PID_CONTROLLER #define ENABLE_TOOL_PID_CONTROLLER @@ -2136,7 +2148,6 @@ typedef uint16_t step_t; #ifndef ENABLE_RT_SYNC_MOTIONS #define ENABLE_RT_SYNC_MOTIONS #endif - #endif #ifdef ENABLE_TOOL_PID_CONTROLLER diff --git a/uCNC/src/core/interpolator.c b/uCNC/src/core/interpolator.c index 1f4cbe664..eb67fff1c 100644 --- a/uCNC/src/core/interpolator.c +++ b/uCNC/src/core/interpolator.c @@ -66,7 +66,8 @@ static volatile uint8_t itp_step_lock; #endif #ifdef ENABLE_RT_SYNC_MOTIONS -volatile int32_t itp_sync_step_counter; +// deprecated with new hooks +// volatile int32_t itp_sync_step_counter; void itp_update_feed(float feed) { @@ -96,6 +97,9 @@ bool itp_sync_ready(void) return false; } + +CREATE_HOOK(itp_rt_pre_stepbits); +CREATE_HOOK(itp_rt_stepbits); #endif static void itp_sgm_buffer_read(void); @@ -854,24 +858,6 @@ uint32_t itp_get_rt_line_number(void) } #endif -#ifdef ENABLE_LASER_PPI -// turn laser off callback -MCU_CALLBACK void laser_ppi_turnoff_cb(void) -{ -#ifndef INVERT_LASER_PPI_LOGIC - io_clear_output(LASER_PPI); -#else - io_set_output(LASER_PPI); -#endif -} -#endif - -#ifdef ENABLE_RT_SYNC_MOTIONS -void __attribute__((weak)) itp_rt_stepbits(uint8_t *stepbits, uint8_t *dirs) -{ -} -#endif - // always fires after pulse MCU_CALLBACK void mcu_step_reset_cb(void) { @@ -883,9 +869,6 @@ MCU_CALLBACK void mcu_step_cb(void) { static uint8_t stepbits = 0; static bool itp_busy = false; -#ifdef ENABLE_LASER_PPI - static uint16_t new_laser_ppi = 0; -#endif #ifdef RT_STEP_PREVENT_CONDITION if (RT_STEP_PREVENT_CONDITION) @@ -899,6 +882,17 @@ MCU_CALLBACK void mcu_step_cb(void) return; } + uint8_t new_stepbits = stepbits; + io_toggle_steps(new_stepbits); + + // sets step bits +#ifdef ENABLE_RT_SYNC_MOTIONS + if (new_stepbits && itp_rt_sgm) + { + HOOK_INVOKE(itp_rt_stepbits, new_stepbits, itp_rt_sgm->flags); + } +#endif + if (itp_rt_sgm != NULL) { if (itp_rt_sgm->flags & ITP_UPDATE) @@ -911,18 +905,7 @@ MCU_CALLBACK void mcu_step_cb(void) #if TOOL_COUNT > 0 if (itp_rt_sgm->flags & ITP_UPDATE_TOOL) { -#ifdef ENABLE_LASER_PPI - if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) - { - new_laser_ppi = itp_rt_sgm->spindle; - } - else - { -#endif - tool_set_speed(itp_rt_sgm->spindle); -#ifdef ENABLE_LASER_PPI - } -#endif + tool_set_speed(itp_rt_sgm->spindle); } #endif itp_rt_sgm->flags &= ~(ITP_UPDATE); @@ -937,30 +920,6 @@ MCU_CALLBACK void mcu_step_cb(void) } } - uint8_t new_stepbits = stepbits; - - // sets step bits -#ifdef ENABLE_LASER_PPI - if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) - { - if (new_stepbits & LASER_PPI_MASK) - { - if (new_laser_ppi) - { - mcu_config_timeout(&laser_ppi_turnoff_cb, new_laser_ppi); - new_laser_ppi = 0; - } - mcu_start_timeout(); -#ifndef INVERT_LASER_PPI_LOGIC - io_set_output(LASER_PPI); -#else - io_clear_output(LASER_PPI); -#endif - } - } -#endif - io_toggle_steps(new_stepbits); - // if buffer empty loads one if (itp_rt_sgm == NULL) { @@ -1039,12 +998,15 @@ MCU_CALLBACK void mcu_step_cb(void) } } -#ifdef ENABLE_RT_SYNC_MOTIONS - if (new_stepbits && (itp_rt_sgm->flags & ITP_SYNC)) - { - itp_sync_step_counter++; - } -#endif + /* + Must put this on G33 module + #ifdef ENABLE_RT_SYNC_MOTIONS + if (new_stepbits && (itp_rt_sgm->flags & ITP_SYNC)) + { + itp_sync_step_counter++; + } + #endif + */ new_stepbits = 0; itp_busy = true; @@ -1218,7 +1180,7 @@ MCU_CALLBACK void mcu_step_cb(void) static uint8_t last_dirs = 0; if (new_stepbits) { - itp_rt_stepbits(&new_stepbits, &dirs); + HOOK_INVOKE(itp_rt_pre_stepbits, &new_stepbits, &dirs); if (dirs != last_dirs) { last_dirs = dirs; diff --git a/uCNC/src/core/interpolator.h b/uCNC/src/core/interpolator.h index 3d63af062..fc92a967b 100644 --- a/uCNC/src/core/interpolator.h +++ b/uCNC/src/core/interpolator.h @@ -92,7 +92,7 @@ extern "C" float itp_get_rt_feed(void); bool itp_is_empty(void); uint8_t itp_sync(void); - + void itp_sync_spindle(void); void itp_start(bool is_synched); #if (defined(ENABLE_DUAL_DRIVE_AXIS) || defined(KINEMATICS_MOTION_BY_SEGMENTS)) @@ -102,10 +102,11 @@ extern "C" uint32_t itp_get_rt_line_number(void); #endif #ifdef ENABLE_RT_SYNC_MOTIONS - extern volatile int32_t itp_sync_step_counter; + // extern volatile int32_t itp_sync_step_counter; void itp_update_feed(float feed); bool itp_sync_ready(void); - void itp_rt_stepbits(uint8_t *stepbits, uint8_t* dirs); + DECL_HOOK(itp_rt_pre_stepbits, uint8_t *, uint8_t *); + DECL_HOOK(itp_rt_stepbits, uint8_t, uint8_t); #endif #ifdef __cplusplus diff --git a/uCNC/src/core/parser.c b/uCNC/src/core/parser.c index 9d9cb6d27..6c03806ae 100644 --- a/uCNC/src/core/parser.c +++ b/uCNC/src/core/parser.c @@ -30,11 +30,6 @@ // extended codes #define M10 EXTENDED_MCODE(10) -#ifdef ENABLE_LASER_PPI -#define M126 EXTENDED_MCODE(126) -#define M127 EXTENDED_MCODE(127) -#define M128 EXTENDED_MCODE(128) -#endif #define PARSER_PARAM_SIZE (sizeof(float) * AXIS_COUNT) // parser parameters array size #define PARSER_PARAM_ADDR_OFFSET (PARSER_PARAM_SIZE + 1) // parser parameters array size + 1 crc byte @@ -64,10 +59,6 @@ static uint8_t parser_wco_counter; static float g92permanentoffset[AXIS_COUNT]; static int32_t rt_probe_step_pos[STEPPER_COUNT]; static float parser_last_pos[AXIS_COUNT]; -#ifdef ENABLE_LASER_PPI -// turn laser off callback -extern MCU_CALLBACK void laser_ppi_turnoff_cb(void); -#endif static unsigned char parser_get_next_preprocessed(bool peek); FORCEINLINE static void parser_get_comment(unsigned char start_char); @@ -1089,20 +1080,6 @@ static uint8_t parser_validate_command(parser_state_t *new_state, parser_words_t return STATUS_GCODE_VALUE_WORD_MISSING; } break; -#endif -#ifdef ENABLE_LASER_PPI - case M127: - case M128: - // prevents command execution if mode disabled - if (!(g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE))) - { - return STATUS_LASER_PPI_MODE_DISABLED; - } - case M126: - if (CHECKFLAG(cmd->words, (GCODE_WORD_P)) != (GCODE_WORD_P)) - { - return STATUS_GCODE_VALUE_WORD_MISSING; - } #endif } @@ -1165,32 +1142,7 @@ uint8_t parser_exec_command(parser_state_t *new_state, parser_words_t *words, pa } break; #endif -#ifdef ENABLE_LASER_PPI - case M126: - g_settings.laser_mode &= ~(LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE); - switch ((((uint8_t)words->p))) - { - case 1: - g_settings.laser_mode |= LASER_PPI_MODE; - break; - case 2: - g_settings.laser_mode |= LASER_PPI_VARPOWER_MODE; - break; - case 3: - g_settings.laser_mode |= (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE); - break; - } - parser_config_ppi(); - break; - case M127: - g_settings.step_per_mm[STEPPER_COUNT - 1] = words->p * MM_INCH_MULT; - parser_config_ppi(); - break; - case M128: - g_settings.laser_ppi_uswidth = (uint16_t)words->p; - parser_config_ppi(); - break; -#endif + default: error = STATUS_GCODE_UNSUPPORTED_COMMAND; #ifdef ENABLE_PARSER_MODULES @@ -2376,19 +2328,6 @@ static uint8_t parser_mcode_word(uint8_t code, uint8_t mantissa, parser_state_t cmd->group_extended = M10; return STATUS_OK; #endif -#ifdef ENABLE_LASER_PPI - case 126: - case 127: - case 128: - if (cmd->group_extended > 0) - { - // there is a collision of custom gcode commands (only one per line can be processed) - return STATUS_GCODE_MODAL_GROUP_VIOLATION; - } - // tells the gcode validation and execution functions this is custom code(ID must be unique) - cmd->group_extended = EXTENDED_MCODE(code); - return STATUS_OK; -#endif default: return STATUS_GCODE_UNSUPPORTED_COMMAND; @@ -2624,9 +2563,6 @@ void parser_reset(bool stopgroup_only) parser_state.groups.tool_change = 1; parser_state.tool_index = g_settings.default_tool; parser_state.groups.path_mode = G61; -#ifdef ENABLE_LASER_PPI - parser_config_ppi(); -#endif #endif parser_state.groups.motion = G1; // G1 parser_state.groups.units = G21; // G21 @@ -3023,25 +2959,3 @@ void parser_machine_to_work(float *axis) } #endif } - -#ifdef ENABLE_LASER_PPI -void parser_config_ppi(void) -{ - g_settings.acceleration[STEPPER_COUNT - 1] = FLT_MAX; - if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) - { - // if previously disabled, reload default value - if (!g_settings.step_per_mm[STEPPER_COUNT - 1]) - { - g_settings.step_per_mm[STEPPER_COUNT - 1] = g_settings.laser_ppi * MM_INCH_MULT; - } - g_settings.max_feed_rate[STEPPER_COUNT - 1] = (60000000.0f / (g_settings.laser_ppi_uswidth * g_settings.step_per_mm[STEPPER_COUNT - 1])); - mcu_config_timeout(&laser_ppi_turnoff_cb, g_settings.laser_ppi_uswidth); - } - else - { - g_settings.step_per_mm[STEPPER_COUNT - 1] = 0; - g_settings.max_feed_rate[STEPPER_COUNT - 1] = FLT_MAX; - } -} -#endif diff --git a/uCNC/src/core/parser.h b/uCNC/src/core/parser.h index 88731db45..4d542ab4d 100644 --- a/uCNC/src/core/parser.h +++ b/uCNC/src/core/parser.h @@ -287,9 +287,6 @@ extern "C" void parser_machine_to_work(float *axis); uint8_t parser_get_float(float *value); uint8_t parser_exec_command(parser_state_t *new_state, parser_words_t *words, parser_cmd_explicit_t *cmd); -#ifdef ENABLE_LASER_PPI - void parser_config_ppi(void); -#endif #ifdef ENABLE_PARSER_MODULES // generates a default delegate, event and handler hook diff --git a/uCNC/src/hal/tools/tools/laser_ppi.c b/uCNC/src/hal/tools/tools/laser_ppi.c index 2e45763c1..85af14434 100644 --- a/uCNC/src/hal/tools/tools/laser_ppi.c +++ b/uCNC/src/hal/tools/tools/laser_ppi.c @@ -36,6 +36,204 @@ #ifdef ENABLE_LASER_PPI +/** + * + * Motion and interpolator related stuff + * + * **/ + +// turn laser off callback via ONESHOT timer +MCU_CALLBACK void laser_ppi_turnoff_cb(void) +{ +#ifndef INVERT_LASER_PPI_LOGIC + io_clear_output(LASER_PPI); +#else + io_set_output(LASER_PPI); +#endif +} + +// laser ppi pulse callback called from the step ISR +static uint16_t new_laser_ppi = 0; +MCU_CALLBACK void laser_ppi_pulse(uint8_t new_stepbits, uint8_t flags) +{ + if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) + { + if (new_stepbits & LASER_PPI_MASK) + { + if (new_laser_ppi) + { + mcu_config_timeout(&laser_ppi_turnoff_cb, new_laser_ppi); + new_laser_ppi = 0; + } + mcu_start_timeout(); +#ifndef INVERT_LASER_PPI_LOGIC + io_set_output(LASER_PPI); +#else + io_clear_output(LASER_PPI); +#endif + } + } +} + +// configs the parameters for laser PPI +// called by each custom laser PPI MCode and on parser reset +static void laser_ppi_config_parameters(void) +{ + g_settings.acceleration[STEPPER_COUNT - 1] = FLT_MAX; + if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) + { + // if previously disabled, reload default value + if (!g_settings.step_per_mm[STEPPER_COUNT - 1]) + { + g_settings.step_per_mm[STEPPER_COUNT - 1] = g_settings.laser_ppi * MM_INCH_MULT; + } + g_settings.max_feed_rate[STEPPER_COUNT - 1] = (60000000.0f / (g_settings.laser_ppi_uswidth * g_settings.step_per_mm[STEPPER_COUNT - 1])); + mcu_config_timeout(&laser_ppi_turnoff_cb, g_settings.laser_ppi_uswidth); + } + else + { + g_settings.step_per_mm[STEPPER_COUNT - 1] = 0; + g_settings.max_feed_rate[STEPPER_COUNT - 1] = FLT_MAX; + } +} + +/** + * + * Parser extensions + * Parser extensions are optional since these can be controlled via tool options + * + * **/ + +#ifdef ENABLE_PARSER_MODULES + +bool laser_ppi_parser_reset(void *args) +{ + laser_ppi_config_parameters(); + return EVENT_CONTINUE; +} +// create event listener +CREATE_EVENT_LISTENER(parser_reset, laser_ppi_parser_reset); + +#define M126 EXTENDED_MCODE(126) +#define M127 EXTENDED_MCODE(127) +#define M128 EXTENDED_MCODE(128) + +// this just parses and acceps the code +bool laser_ppi_mcodes_parse(void *args) +{ + gcode_parse_args_t *ptr = (gcode_parse_args_t *)args; + if (ptr->word == 'M') + { + switch (ptr->code) + { + case 126: + if (ptr->cmd->group_extended != 0) + { + // there is a collision of custom gcode commands (only one per line can be processed) + *(ptr->error) = STATUS_GCODE_MODAL_GROUP_VIOLATION; + } + else + { + ptr->cmd->group_extended = M126; + *(ptr->error) = STATUS_OK; + } + return EVENT_HANDLED; + case 127: + if (ptr->cmd->group_extended != 0) + { + // there is a collision of custom gcode commands (only one per line can be processed) + *(ptr->error) = STATUS_GCODE_MODAL_GROUP_VIOLATION; + } + else + { + ptr->cmd->group_extended = M127; + *(ptr->error) = STATUS_OK; + } + return EVENT_HANDLED; + case 128: + if (ptr->cmd->group_extended != 0) + { + // there is a collision of custom gcode commands (only one per line can be processed) + *(ptr->error) = STATUS_GCODE_MODAL_GROUP_VIOLATION; + } + else + { + ptr->cmd->group_extended = M128; + *(ptr->error) = STATUS_OK; + } + return EVENT_HANDLED; + } + } + + // if this is not catched by this parser, just send back the error so other extenders can process it + return EVENT_CONTINUE; +} + +CREATE_EVENT_LISTENER(gcode_parse, laser_ppi_mcodes_parse); + +// this actually performs 2 steps in 1 (validation and execution) +bool laser_ppi_mcodes_exec(void *args) +{ + gcode_exec_args_t *ptr = (gcode_exec_args_t *)args; + switch (ptr->cmd->group_extended) + { + case M127: + case M128: + // prevents command execution if mode disabled + if (!(g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE))) + { + *(ptr->error) = STATUS_LASER_PPI_MODE_DISABLED; + return EVENT_HANDLED; + } + case M126: + if (CHECKFLAG(ptr->cmd->words, (GCODE_WORD_P)) != (GCODE_WORD_P)) + { + *(ptr->error) = STATUS_GCODE_VALUE_WORD_MISSING; + return EVENT_HANDLED; + } + + *(ptr->error) = STATUS_OK; + break; + } + + switch (ptr->cmd->group_extended) + { + case M126: + g_settings.laser_mode &= ~(LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE); + switch ((((uint8_t)ptr->words->p))) + { + case 1: + g_settings.laser_mode |= LASER_PPI_MODE; + break; + case 2: + g_settings.laser_mode |= LASER_PPI_VARPOWER_MODE; + break; + case 3: + g_settings.laser_mode |= (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE); + break; + } + laser_ppi_config_parameters(); + return EVENT_HANDLED; + case M127: + g_settings.laser_ppi = (uint16_t)ptr->words->p; + laser_ppi_config_parameters(); + return EVENT_HANDLED; + case M128: + g_settings.laser_ppi_uswidth = (uint16_t)ptr->words->p; + laser_ppi_config_parameters(); + return EVENT_HANDLED; + } + + return EVENT_CONTINUE; +} + +CREATE_EVENT_LISTENER(gcode_exec, laser_ppi_mcodes_exec); +#endif + +/** + * Now starts the actual tool functions definitions + * These functions will then be called by the tool HAL + * **/ static void startup_code(void) { // force laser mode @@ -48,7 +246,15 @@ static void startup_code(void) #endif #endif g_settings.laser_mode |= LASER_PPI_MODE; - parser_config_ppi(); + laser_ppi_config_parameters(); + HOOK_ATTACH_CALLBACK(itp_rt_stepbits, laser_ppi_pulse); + + RUNONCE + { + ADD_EVENT_LISTENER(gcode_parse, laser_ppi_mcodes_parse); + ADD_EVENT_LISTENER(gcode_exec, laser_ppi_mcodes_exec); + RUNONCE_COMPLETE(); + } } static void shutdown_code(void) @@ -62,7 +268,8 @@ static void shutdown_code(void) #endif // restore laser mode g_settings.laser_mode &= ~(LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE); - parser_config_ppi(); + laser_ppi_config_parameters(); + HOOK_RELEASE(itp_rt_stepbits); } static void set_coolant(uint8_t value) @@ -73,6 +280,14 @@ static void set_coolant(uint8_t value) #endif } +static void set_speed(int16_t value) +{ + if (g_settings.laser_mode & (LASER_PPI_MODE | LASER_PPI_VARPOWER_MODE)) + { + new_laser_ppi = value; + } +} + static uint16_t get_speed(void) { return g_settings.step_per_mm[STEPPER_COUNT - 1]; @@ -84,7 +299,7 @@ const tool_t laser_ppi = { .pid_update = NULL, .range_speed = NULL, .get_speed = &get_speed, - .set_speed = NULL, + .set_speed = &set_speed, .set_coolant = &set_coolant}; #endif diff --git a/uCNC/src/module.h b/uCNC/src/module.h index 9f1ad3efe..ff9308bd5 100644 --- a/uCNC/src/module.h +++ b/uCNC/src/module.h @@ -102,6 +102,26 @@ extern "C" void mod_init(void); +// uses VARADIC MACRO available since C99 +#define DECL_HOOK(name, ...) \ + typedef void (*name##_delegate_t)(__VA_ARGS__); \ + extern name##_delegate_t name##_cb +#define CREATE_HOOK(name) name##_delegate_t name##_cb +#define HOOK_ATTACH_CALLBACK(name, cb) name##_cb = &cb +#define HOOK_RELEASE(name) name##_cb = NULL + +#define HOOK_INVOKE(name, ...) \ + if (name##_cb) \ + { \ + name##_cb(__VA_ARGS__); \ + } + +#define RUNONCE \ + static bool runonce = false; \ + if (!runonce) + +#define RUNONCE_COMPLETE() runonce = true + #ifdef __cplusplus } #endif diff --git a/uCNC/src/modules/encoder.c b/uCNC/src/modules/encoder.c index 927294d17..5279d8a72 100644 --- a/uCNC/src/modules/encoder.c +++ b/uCNC/src/modules/encoder.c @@ -36,18 +36,8 @@ static int32_t encoders_pos[ENCODERS]; static volatile uint32_t prev_time; static volatile uint32_t current_time; -static encoder_index_cb rpm_index_cb; bool encoder_rpm_updated; - -void encoder_attach_index_cb(encoder_index_cb callback) -{ - rpm_index_cb = callback; -} - -void encoder_dettach_index_cb(void) -{ - rpm_index_cb = NULL; -} +CREATE_HOOK(encoder_index); uint16_t encoder_get_rpm(void) { @@ -173,10 +163,7 @@ void encoders_update(uint8_t pulse, uint8_t diff) #endif { encoders_pos[RPM_ENCODER] = 0; - if (rpm_index_cb) - { - rpm_index_cb(); - } + HOOK_INVOKE(encoder_index); } } #endif diff --git a/uCNC/src/modules/encoder.h b/uCNC/src/modules/encoder.h index 89371874e..f07bc2206 100644 --- a/uCNC/src/modules/encoder.h +++ b/uCNC/src/modules/encoder.h @@ -36,17 +36,14 @@ extern "C" #define ENC6 6 #define ENC7 7 - typedef void (*encoder_index_cb)(void); - DECL_MODULE(encoder); + DECL_HOOK(encoder_index, void); int32_t encoder_get_position(uint8_t i); void encoder_print_values(void); void encoder_reset_position(uint8_t i, int32_t position); void encoders_reset_position(void); void encoders_itp_reset_rt_position(float *origin); void encoders_update(uint8_t pulse, uint8_t diff); - void encoder_attach_index_cb(encoder_index_cb callback); - void encoder_dettach_index_cb(void); uint16_t encoder_get_rpm(void); extern bool encoder_rpm_updated;