mirror of
https://github.com/grblHAL/core.git
synced 2026-02-05 08:34:01 +08:00
Updated to allow Bluetooth serial streams to be used for MPG/pendants.
Parking mode improvements. Removed requirement for external encoder for spindle sync if stepper spindle is enabled. Improved handling of $680 stepper enable delay.
This commit is contained in:
@@ -39,6 +39,7 @@ target_sources(grbl INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/ngc_flowctrl.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/regex.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/ioports.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/utf8.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/vfs.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/canbus.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pid.c
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## grblHAL ##
|
||||
|
||||
Latest build date is 20251109, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20251130, see the [changelog](changelog.md) for details.
|
||||
|
||||
> [!NOTE]
|
||||
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
|
||||
|
||||
8
alarms.c
8
alarms.c
@@ -7,18 +7,18 @@
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
grblHAL is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Grbl is distributed in the hope that it will be useful,
|
||||
grblHAL is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
20
alarms.h
20
alarms.h
@@ -3,22 +3,22 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2023 Terje Io
|
||||
Copyright (c) 2017-2025 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
grblHAL is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Grbl is distributed in the hope that it will be useful,
|
||||
grblHAL is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ALARMS_H_
|
||||
@@ -67,5 +67,13 @@ alarm_details_t *alarms_get_details (void);
|
||||
const char *alarms_get_description (alarm_code_t id);
|
||||
void alarms_register (alarm_details_t *details);
|
||||
|
||||
#endif
|
||||
static inline bool alarm_is_critical (alarm_code_t alarm)
|
||||
{
|
||||
return alarm == Alarm_HardLimit ||
|
||||
alarm == Alarm_SoftLimit ||
|
||||
alarm == Alarm_EStop ||
|
||||
alarm == Alarm_MotorFault ||
|
||||
alarm == Alarm_ExpanderException;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
31
changelog.md
31
changelog.md
@@ -1,5 +1,36 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20251130">Build 20251130
|
||||
|
||||
Core:
|
||||
|
||||
* Updated to allow Bluetooth serial streams to be used for MPG/pendants.
|
||||
|
||||
* Parking mode improvements.
|
||||
|
||||
* Removed requirement for external encoder for spindle sync if stepper spindle is enabled.
|
||||
|
||||
* Improved handling of `$680` stepper enable delay.
|
||||
|
||||
Drivers:
|
||||
|
||||
* ESP32, RP2040: Updated native Bluetooth implementations to allow Bluetooth serial streams to be used for MPG/pendants.
|
||||
|
||||
* RP2040: updated LED strip code to use non-blocking DMA.
|
||||
Extended spindle PWM frequency range down to ~10Hz. Ref. discussion [#155](https://github.com/grblHAL/RP2040/discussions/155).
|
||||
|
||||
* STM32F3xx: fixed compiler errors and warnings for generic board, ref. issue [#5](https://github.com/grblHAL/STM32F3xx/issues/5).
|
||||
|
||||
* STM32F4xx: refactored LED strip drivers, now supports up to two strips via DMA based PWM.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Bluetooth: updated to allow use for MPG/pendants.
|
||||
|
||||
* Misc, FNC Expander: added compile time option for PWM outputs, some general improvements.
|
||||
|
||||
---
|
||||
|
||||
<a name="20251111">Build 20251111
|
||||
|
||||
Core:
|
||||
|
||||
@@ -198,14 +198,6 @@
|
||||
#define SPINDLE_SYNC_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef SPINDLE_ENCODER_ENABLE
|
||||
#if SPINDLE_SYNC_ENABLE
|
||||
#define SPINDLE_ENCODER_ENABLE 1
|
||||
#else
|
||||
#define SPINDLE_ENCODER_ENABLE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TRINAMIC_ENABLE
|
||||
#define TRINAMIC_ENABLE 0
|
||||
#endif
|
||||
@@ -450,6 +442,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SPINDLE_ENCODER_ENABLE
|
||||
#if SPINDLE_SYNC_ENABLE && !(SPINDLE_ENABLE & (1 << SPINDLE_STEPPER))
|
||||
#define SPINDLE_ENCODER_ENABLE 1
|
||||
#else
|
||||
#define SPINDLE_ENCODER_ENABLE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef QEI_ENABLE
|
||||
#define QEI_ENABLE 0
|
||||
#endif
|
||||
|
||||
@@ -246,6 +246,26 @@
|
||||
#define TRINAMIC_MOTOR_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if MPG_ENABLE && !defined(MPG_STREAM)
|
||||
#if USB_SERIAL_CDC
|
||||
#define MPG_STREAM 0
|
||||
#else
|
||||
#define MPG_STREAM 1
|
||||
#endif
|
||||
#if (MODBUS_ENABLE & MODBUS_RTU_ENABLED) && defined(MODBUS_RTU_STREAM) && MODBUS_RTU_STREAM == MPG_STREAM
|
||||
#undef MPG_STREAM
|
||||
#define MPG_STREAM (MODBUS_RTU_STREAM + 1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MPG_ENABLE && MPG_ENABLE != 2 && MPG_STREAM == 20 && BLUETOOTH_ENABLE != 1
|
||||
#error "MPG can only be used with native Bluetooth and character mode switching!"
|
||||
#endif
|
||||
|
||||
#if BLUETOOTH_ENABLE == 2 && !defined(BLUETOOTH_STREAM)
|
||||
#define BLUETOOTH_STREAM 255 // Select first free UART stream
|
||||
#endif
|
||||
|
||||
#if USB_SERIAL_CDC && defined(SERIAL_PORT)
|
||||
#define SP0 1
|
||||
#else
|
||||
@@ -276,35 +296,37 @@
|
||||
#define TRINAMIC_TEST 0
|
||||
#endif
|
||||
|
||||
#if KEYPAD_ENABLE == 2 && MPG_ENABLE == 0
|
||||
#if MPG_ENABLE && MPG_STREAM != 20
|
||||
#define MPG_TEST 1
|
||||
#else
|
||||
#define MPG_TEST 0
|
||||
#endif
|
||||
|
||||
#if KEYPAD_ENABLE == 2 && !MPG_TEST
|
||||
#define KEYPAD_TEST 1
|
||||
#else
|
||||
#define KEYPAD_TEST 0
|
||||
#endif
|
||||
|
||||
#if (MODBUS_TEST + KEYPAD_TEST + (MPG_ENABLE ? 1 : 0) + TRINAMIC_TEST + (BLUETOOTH_ENABLE == 2 ? 1 : 0)) > (SP0 + SP1 + SP2)
|
||||
#error "Too many options that uses a serial port are enabled!"
|
||||
#if BLUETOOTH_ENABLE == 2 && (!MPG_ENABLE || MPG_STREAM != BLUETOOTH_STREAM)
|
||||
#define BT_TEST 1
|
||||
#else
|
||||
#define BT_TEST 0
|
||||
#endif
|
||||
|
||||
#if (MODBUS_TEST + KEYPAD_TEST + MPG_TEST + TRINAMIC_TEST + BT_TEST) > (SP0 + SP1 + SP2)
|
||||
#error "Too many options that requires a serial port are enabled!"
|
||||
#endif
|
||||
|
||||
#undef SP0
|
||||
#undef SP1
|
||||
#undef SP2
|
||||
#undef BT_TEST
|
||||
#undef MODBUS_TEST
|
||||
#undef MPG_TEST
|
||||
#undef KEYPAD_TEST
|
||||
#undef TRINAMIC_TEST
|
||||
|
||||
#if MPG_ENABLE && !defined(MPG_STREAM)
|
||||
#if USB_SERIAL_CDC
|
||||
#define MPG_STREAM 0
|
||||
#else
|
||||
#define MPG_STREAM 1
|
||||
#endif
|
||||
#if (MODBUS_ENABLE & MODBUS_RTU_ENABLED) && defined(MODBUS_RTU_STREAM) && MODBUS_RTU_STREAM == MPG_STREAM
|
||||
#undef MPG_STREAM
|
||||
#define MPG_STREAM (MODBUS_RTU_STREAM + 1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if KEYPAD_ENABLE == 2 && !defined(KEYPAD_STREAM)
|
||||
#if MPG_ENABLE
|
||||
#define KEYPAD_STREAM MPG_STREAM
|
||||
|
||||
80
grbl.h
80
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20251111
|
||||
#define GRBL_BUILD 20251130
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
@@ -113,48 +113,48 @@
|
||||
// at character value 128 (0x80) and up to 255 (0xFF). If the normal set of realtime commands,
|
||||
// such as status reports, feed hold, reset, and cycle start, are moved to the extended set
|
||||
// space, protocol.c's protocol_process_realtime() will need to be modified to accommodate the change.
|
||||
#define CMD_STATUS_REPORT 0x80 // TODO: use 0x05 ctrl-E ENQ instead?
|
||||
#define CMD_CYCLE_START 0x81 // TODO: use 0x06 ctrl-F ACK instead? or SYN/DC2/DC3?
|
||||
#define CMD_FEED_HOLD 0x82 // TODO: use 0x15 ctrl-U NAK instead?
|
||||
#define CMD_GCODE_REPORT 0x83
|
||||
#define CMD_SAFETY_DOOR 0x84
|
||||
#define CMD_JOG_CANCEL 0x85
|
||||
#define CMD_STATUS_REPORT 0x80 // (128) TODO: use 0x05 ctrl-E ENQ instead?
|
||||
#define CMD_CYCLE_START 0x81 // (129) TODO: use 0x06 ctrl-F ACK instead? or SYN/DC2/DC3?
|
||||
#define CMD_FEED_HOLD 0x82 // (130) TODO: use 0x15 ctrl-U NAK instead?
|
||||
#define CMD_GCODE_REPORT 0x83 // (131)
|
||||
#define CMD_SAFETY_DOOR 0x84 // (132)
|
||||
#define CMD_JOG_CANCEL 0x85 // (133)
|
||||
//#define CMD_DEBUG_REPORT 0x86 // Only when DEBUG enabled, sends debug report in '{}' braces.
|
||||
#define CMD_STATUS_REPORT_ALL 0x87
|
||||
#define CMD_OPTIONAL_STOP_TOGGLE 0x88
|
||||
#define CMD_SINGLE_BLOCK_TOGGLE 0x89
|
||||
#define CMD_OVERRIDE_FAN0_TOGGLE 0x8A //!< Toggle Fan 0 on/off, not implemented by the core.
|
||||
#define CMD_MPG_MODE_TOGGLE 0x8B //!< Toggle MPG mode on/off, available when the MPG stream is enabled with MPG mode 2.
|
||||
#define CMD_AUTO_REPORTING_TOGGLE 0x8C //!< Toggle auto real time reporting if configured.
|
||||
#define CMD_OVERRIDE_FEED_RESET 0x90 //!< Restores feed override value to 100%.
|
||||
#define CMD_OVERRIDE_FEED_COARSE_PLUS 0x91
|
||||
#define CMD_OVERRIDE_FEED_COARSE_MINUS 0x92
|
||||
#define CMD_OVERRIDE_FEED_FINE_PLUS 0x93
|
||||
#define CMD_OVERRIDE_FEED_FINE_MINUS 0x94
|
||||
#define CMD_OVERRIDE_RAPID_RESET 0x95 //!< Restores rapid override value to 100%.
|
||||
#define CMD_OVERRIDE_RAPID_MEDIUM 0x96
|
||||
#define CMD_OVERRIDE_RAPID_LOW 0x97
|
||||
#define CMD_STATUS_REPORT_ALL 0x87 // (135)
|
||||
#define CMD_OPTIONAL_STOP_TOGGLE 0x88 // (136)
|
||||
#define CMD_SINGLE_BLOCK_TOGGLE 0x89 // (137)
|
||||
#define CMD_OVERRIDE_FAN0_TOGGLE 0x8A //!< (138) Toggle Fan 0 on/off, not implemented by the core.
|
||||
#define CMD_MPG_MODE_TOGGLE 0x8B //!< (139) Toggle MPG mode on/off, available when the MPG stream is enabled with MPG mode 2.
|
||||
#define CMD_AUTO_REPORTING_TOGGLE 0x8C //!< (140) Toggle auto real time reporting if configured.
|
||||
#define CMD_OVERRIDE_FEED_RESET 0x90 //!< (144) Restores feed override value to 100%.
|
||||
#define CMD_OVERRIDE_FEED_COARSE_PLUS 0x91 // (145)
|
||||
#define CMD_OVERRIDE_FEED_COARSE_MINUS 0x92 // (146)
|
||||
#define CMD_OVERRIDE_FEED_FINE_PLUS 0x93 // (147)
|
||||
#define CMD_OVERRIDE_FEED_FINE_MINUS 0x94 // (148)
|
||||
#define CMD_OVERRIDE_RAPID_RESET 0x95 //!< (149) Restores rapid override value to 100%.
|
||||
#define CMD_OVERRIDE_RAPID_MEDIUM 0x96 // (150)
|
||||
#define CMD_OVERRIDE_RAPID_LOW 0x97 // (151)
|
||||
// #define CMD_OVERRIDE_RAPID_EXTRA_LOW 0x98 // *NOT SUPPORTED*
|
||||
#define CMD_OVERRIDE_SPINDLE_RESET 0x99 // Restores spindle override value to 100%.
|
||||
#define CMD_OVERRIDE_SPINDLE_COARSE_PLUS 0x9A
|
||||
#define CMD_OVERRIDE_SPINDLE_COARSE_MINUS 0x9B
|
||||
#define CMD_OVERRIDE_SPINDLE_FINE_PLUS 0x9C
|
||||
#define CMD_OVERRIDE_SPINDLE_FINE_MINUS 0x9D
|
||||
#define CMD_OVERRIDE_SPINDLE_STOP 0x9E
|
||||
#define CMD_OVERRIDE_COOLANT_FLOOD_TOGGLE 0xA0
|
||||
#define CMD_OVERRIDE_COOLANT_MIST_TOGGLE 0xA1
|
||||
#define CMD_PID_REPORT 0xA2
|
||||
#define CMD_TOOL_ACK 0xA3
|
||||
#define CMD_PROBE_CONNECTED_TOGGLE 0xA4
|
||||
#define CMD_OVERRIDE_SPINDLE_RESET 0x99 // (153) Restores spindle override value to 100%.
|
||||
#define CMD_OVERRIDE_SPINDLE_COARSE_PLUS 0x9A // (154)
|
||||
#define CMD_OVERRIDE_SPINDLE_COARSE_MINUS 0x9B // (155)
|
||||
#define CMD_OVERRIDE_SPINDLE_FINE_PLUS 0x9C // (156)
|
||||
#define CMD_OVERRIDE_SPINDLE_FINE_MINUS 0x9D // (157)
|
||||
#define CMD_OVERRIDE_SPINDLE_STOP 0x9E // (158)
|
||||
#define CMD_OVERRIDE_COOLANT_FLOOD_TOGGLE 0xA0 // (160)
|
||||
#define CMD_OVERRIDE_COOLANT_MIST_TOGGLE 0xA1 // (161)
|
||||
#define CMD_PID_REPORT 0xA2 // (162)
|
||||
#define CMD_TOOL_ACK 0xA3 // (163)
|
||||
#define CMD_PROBE_CONNECTED_TOGGLE 0xA4 // (164)
|
||||
// The following character codes are reserved for plugin use
|
||||
#define CMD_MACRO_0 0xB0
|
||||
#define CMD_MACRO_1 0xB1
|
||||
#define CMD_MACRO_2 0xB2
|
||||
#define CMD_MACRO_3 0xB3
|
||||
#define CMD_MACRO_4 0xB4
|
||||
#define CMD_MACRO_5 0xB5
|
||||
#define CMD_MACRO_6 0xB6
|
||||
#define CMD_MACRO_7 0xB7
|
||||
#define CMD_MACRO_0 0xB0 // (176)
|
||||
#define CMD_MACRO_1 0xB1 // (177)
|
||||
#define CMD_MACRO_2 0xB2 // (178)
|
||||
#define CMD_MACRO_3 0xB3 // (179)
|
||||
#define CMD_MACRO_4 0xB4 // (180)
|
||||
#define CMD_MACRO_5 0xB5 // (181)
|
||||
#define CMD_MACRO_6 0xB6 // (182)
|
||||
#define CMD_MACRO_7 0xB7 // (183)
|
||||
|
||||
// System motion line numbers must be zero.
|
||||
#define JOG_LINE_NUMBER 0
|
||||
|
||||
12
grbllib.c
12
grbllib.c
@@ -95,6 +95,7 @@ static driver_startup_t driver = { .ok = 0xFF };
|
||||
static core_task_t *next_task = NULL, *immediate_task = NULL, *on_booted = NULL, *systick_task = NULL, *last_freed = NULL;
|
||||
static on_linestate_changed_ptr on_linestate_changed;
|
||||
static settings_changed_ptr hal_settings_changed;
|
||||
static stepper_enable_ptr stepper_enable;
|
||||
|
||||
#ifdef KINEMATICS_API
|
||||
kinematics_t kinematics;
|
||||
@@ -211,6 +212,14 @@ static void onLinestateChanged (serial_linestate_t state)
|
||||
on_linestate_changed(state);
|
||||
}
|
||||
|
||||
static void stepperEnable (axes_signals_t enable, bool hold)
|
||||
{
|
||||
if(stepper_enable)
|
||||
stepper_enable(enable, hold);
|
||||
|
||||
sys.steppers_enabled = /*!hold &&*/ enable.bits == AXES_BITMASK;
|
||||
}
|
||||
|
||||
static void print_pos_msg (void *data)
|
||||
{
|
||||
hal.stream.write("grblHAL: power on self-test (POS) failed!" ASCII_EOL);
|
||||
@@ -354,6 +363,9 @@ int grbl_enter (void)
|
||||
|
||||
// check and configure driver
|
||||
|
||||
stepper_enable = hal.stepper.enable;
|
||||
hal.stepper.enable = stepperEnable;
|
||||
|
||||
#if ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING
|
||||
driver.amass = hal.driver_cap.amass_level >= MAX_AMASS_LEVEL;
|
||||
hal.driver_cap.amass_level = MAX_AMASS_LEVEL;
|
||||
|
||||
@@ -519,7 +519,7 @@ static void modbus_set_direction (bool tx)
|
||||
ioport_digital_out(dir_port, tx);
|
||||
}
|
||||
|
||||
static bool claim_stream (io_stream_properties_t const *sstream)
|
||||
static bool claim_stream (io_stream_properties_t const *sstream, void *data)
|
||||
{
|
||||
io_stream_t const *claimed = NULL;
|
||||
|
||||
@@ -598,7 +598,7 @@ void modbus_rtu_init (int8_t instance, int8_t dir_aux)
|
||||
|
||||
stream_instance = instance;
|
||||
|
||||
if((hal.driver_cap.modbus_rtu = stream_enumerate_streams(claim_stream) && (nvs_address = nvs_alloc(sizeof(rtu_settings_t))))) {
|
||||
if((hal.driver_cap.modbus_rtu = stream_enumerate_streams(claim_stream, NULL) && (nvs_address = nvs_alloc(sizeof(rtu_settings_t))))) {
|
||||
|
||||
if(stream.set_direction == NULL && dir_aux != -2) {
|
||||
|
||||
|
||||
@@ -462,10 +462,7 @@ bool protocol_exec_rt_system (void)
|
||||
hal.driver_reset();
|
||||
|
||||
// Halt everything upon a critical event flag. Currently hard and soft limits flag this.
|
||||
if((sys.blocking_event = (alarm_code_t)rt_exec == Alarm_HardLimit ||
|
||||
(alarm_code_t)rt_exec == Alarm_SoftLimit ||
|
||||
(alarm_code_t)rt_exec == Alarm_EStop ||
|
||||
(alarm_code_t)rt_exec == Alarm_MotorFault)) {
|
||||
if((sys.blocking_event = alarm_is_critical((alarm_code_t)rt_exec))) {
|
||||
|
||||
static const control_signals_t blocking_signals = { .e_stop = On, .motor_fault = On };
|
||||
|
||||
@@ -894,9 +891,9 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(uint8_t c)
|
||||
break;
|
||||
|
||||
case CMD_SAFETY_DOOR:
|
||||
if(state_get() != STATE_SAFETY_DOOR) {
|
||||
if((drop = state_get() != STATE_SAFETY_DOOR)) {
|
||||
sys.flags.is_parking = settings.parking.flags.enabled;
|
||||
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
|
||||
drop = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
153
report.c
153
report.c
@@ -2366,84 +2366,119 @@ status_code_t report_pins (sys_state_t state, char *args)
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32_t idx;
|
||||
const io_stream_properties_t *port;
|
||||
} port_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t instance;
|
||||
uint32_t n_pins;
|
||||
pin_info_t data[2];
|
||||
} port_pins_t;
|
||||
|
||||
static void get_uart_pins (xbar_t *pin, void *data)
|
||||
{
|
||||
if(pin->group >= PinGroup_UART && pin->group <= PinGroup_UART4)
|
||||
get_pin_info(pin, &((pin_data_t *)data)->pins[((pin_data_t *)data)->idx++]);
|
||||
if(pin->group == PinGroup_UART + ((port_pins_t *)data)->instance)
|
||||
get_pin_info(pin, &((port_pins_t *)data)->data[((port_pins_t *)data)->n_pins++]);
|
||||
}
|
||||
|
||||
static void count_uart_pins (xbar_t *pin, void *data)
|
||||
static bool report_port_info (const io_stream_properties_t *port, void *data)
|
||||
{
|
||||
if(pin->group >= PinGroup_UART && pin->group <= PinGroup_UART4)
|
||||
((pin_data_t *)data)->n_pins++;
|
||||
}
|
||||
if(!stream_is_uart(port->type))
|
||||
return false;
|
||||
|
||||
static void report_port_info (pin_info_t *pin)
|
||||
{
|
||||
port_pins_t pins = {0};
|
||||
const io_stream_status_t *status;
|
||||
|
||||
if(pin->function == Input_RX) {
|
||||
strcpy(buf, pin->port);
|
||||
strcat(buf, uitoa(pin->pin));
|
||||
strcat(buf, ",");
|
||||
strcat(buf, xbar_fn_to_pinname(Input_RX));
|
||||
strcat(buf, "|");
|
||||
hal.stream.write("[PORT:");
|
||||
hal.stream.write(uitoa(port->instance));
|
||||
hal.stream.write("|");
|
||||
if(port->type == StreamType_Bluetooth) {
|
||||
hal.stream.write("BT||");
|
||||
} else {
|
||||
|
||||
uint8_t instance = (pin->sortkey >> 16) - PinGroup_UART;
|
||||
|
||||
hal.stream.write("[PORT:");
|
||||
hal.stream.write(uitoa(instance));
|
||||
hal.stream.write("|");
|
||||
hal.stream.write(pin->description);
|
||||
hal.stream.write("|");
|
||||
hal.stream.write(*buf ? buf : "-|");
|
||||
if(*pin->port)
|
||||
hal.stream.write(pin->port);
|
||||
hal.stream.write(uitoa(pin->pin));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(xbar_fn_to_pinname(pin->function));
|
||||
if(hal.stream.write_char && (status = stream_get_uart_status(instance))) {
|
||||
hal.stream.write("|");
|
||||
hal.stream.write(uitoa(status->baud_rate));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write_char("87"[status->format.width]);
|
||||
hal.stream.write(",");
|
||||
hal.stream.write_char("NEOMS"[status->format.parity]);
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(((const char * const[]){"1", "1.5", "2", "0.5"})[status->format.stopbits]);
|
||||
if(status->flags.rts_handshake)
|
||||
hal.stream.write(",P");
|
||||
hal.stream.write("|");
|
||||
hal.stream.write_char("FC"[status->flags.claimed]);
|
||||
}
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
*buf = '\0';
|
||||
uint32_t idx = 0;
|
||||
pins.instance = port->instance;
|
||||
if(hal.enumerate_pins)
|
||||
hal.enumerate_pins(false, get_uart_pins, &pins);
|
||||
if(pins.n_pins) {
|
||||
hal.stream.write(pins.data[0].description);
|
||||
for(idx = 0; idx < pins.n_pins; idx++) {
|
||||
hal.stream.write("|");
|
||||
if(*pins.data[idx].port)
|
||||
hal.stream.write(pins.data[idx].port);
|
||||
hal.stream.write(uitoa(pins.data[idx].pin));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(xbar_fn_to_pinname(pins.data[idx].function));
|
||||
}
|
||||
for(; idx < 2; idx++)
|
||||
hal.stream.write("|");
|
||||
} else
|
||||
hal.stream.write("UART||");
|
||||
}
|
||||
|
||||
if(hal.stream.write_char && (status = stream_get_uart_status(port->instance))) {
|
||||
hal.stream.write("|");
|
||||
hal.stream.write(uitoa(status->baud_rate));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write_char("87"[status->format.width]);
|
||||
hal.stream.write(",");
|
||||
hal.stream.write_char("NEOMS"[status->format.parity]);
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(((const char * const[]){"1", "1.5", "2", "0.5"})[status->format.stopbits]);
|
||||
if(status->flags.rts_handshake)
|
||||
hal.stream.write(",P");
|
||||
hal.stream.write("|");
|
||||
hal.stream.write_char("FC"[status->flags.claimed]);
|
||||
}
|
||||
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_ports (io_stream_properties_t const *port, void *data)
|
||||
{
|
||||
if(stream_is_uart(port->type)) {
|
||||
((port_data_t *)data)[((port_data_t *)data)->idx].port = port;
|
||||
((port_data_t *)data)->idx++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool count_ports (io_stream_properties_t const *port, void *data)
|
||||
{
|
||||
if(stream_is_uart(port->type))
|
||||
(*(uint32_t *)data)++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cmp_ports (const void *a, const void *b)
|
||||
{
|
||||
return ((port_data_t *)a)->port->instance - ((port_data_t *)b)->port->instance;
|
||||
}
|
||||
|
||||
status_code_t report_uart_ports (sys_state_t state, char *args)
|
||||
{
|
||||
pin_data_t pin_data = {0};
|
||||
uint32_t n_ports = 0;
|
||||
port_data_t *port_data;
|
||||
|
||||
if(hal.enumerate_pins) {
|
||||
stream_enumerate_streams(count_ports, &n_ports);
|
||||
if(n_ports) {
|
||||
if((port_data = malloc(n_ports * sizeof(port_data_t)))) {
|
||||
|
||||
hal.enumerate_pins(false, count_uart_pins, (void *)&pin_data);
|
||||
port_data->idx = 0;
|
||||
stream_enumerate_streams(get_ports, port_data);
|
||||
|
||||
if((pin_data.pins = malloc(pin_data.n_pins * sizeof(pin_info_t)))) {
|
||||
|
||||
*buf = '\0';
|
||||
|
||||
hal.enumerate_pins(false, get_uart_pins, (void *)&pin_data);
|
||||
|
||||
qsort(pin_data.pins, pin_data.n_pins, sizeof(pin_info_t), cmp_pins);
|
||||
for(pin_data.idx = 0; pin_data.idx < pin_data.n_pins; pin_data.idx++)
|
||||
report_port_info(&pin_data.pins[pin_data.idx]);
|
||||
|
||||
free(pin_data.pins);
|
||||
qsort(port_data, n_ports, sizeof(port_data_t), cmp_ports);
|
||||
for(port_data->idx = 0; port_data->idx < n_ports; port_data->idx++)
|
||||
report_port_info(port_data[port_data->idx].port, NULL);
|
||||
|
||||
free(port_data);
|
||||
} else
|
||||
hal.enumerate_pins(false, report_pin, NULL);
|
||||
stream_enumerate_streams(report_port_info, NULL);
|
||||
}
|
||||
|
||||
return Status_OK;
|
||||
|
||||
13
settings.c
13
settings.c
@@ -434,6 +434,7 @@ static char probing_options[] = "Allow feed override,Apply soft limits,N/A,Auto
|
||||
static char control_signals[] = "Reset,Feed hold,Cycle start,Safety door,Block delete,Optional stop,EStop,Probe disconnected,Motor fault,Motor warning,Limits override,Single step blocks,Toolsetter overtravel";
|
||||
static char spindle_signals[] = "Spindle enable,Spindle direction,PWM";
|
||||
static char coolant_signals[] = "Flood,Mist";
|
||||
static char door_options[] = "Ignore when idle,Keep coolant state on door open";
|
||||
static char ganged_axes[] = "X-Axis,Y-Axis,Z-Axis";
|
||||
#if !AXIS_REMAP_ABC2UVW
|
||||
#if N_AXIS == 4
|
||||
@@ -950,6 +951,8 @@ static status_code_t set_parking_enable (setting_id_t id, uint_fast16_t int_valu
|
||||
if(settings.parking.flags.deactivate_upon_init)
|
||||
settings.parking.flags.enable_override_control = On;
|
||||
|
||||
//setting_remove_elements(Setting_ProbePullUpDisable, mask);
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
@@ -1951,7 +1954,7 @@ static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t
|
||||
#ifndef NO_SAFETY_DOOR_SUPPORT
|
||||
|
||||
case Setting_DoorOptions:
|
||||
available = hal.signals_cap.safety_door_ajar;
|
||||
available = hal.signals_cap.safety_door_ajar || !settings.parking.flags.enabled;
|
||||
break;
|
||||
|
||||
case Setting_DoorSpindleOnDelay:
|
||||
@@ -2106,7 +2109,7 @@ PROGMEM static const setting_detail_t setting_detail[] = {
|
||||
{ Setting_ParkingFastRate, Group_SafetyDoor, "Parking fast rate", "mm/min", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.rate, NULL, NULL },
|
||||
{ Setting_RestoreOverrides, Group_General, "Restore overrides", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_restore_overrides, get_int, NULL },
|
||||
#ifndef NO_SAFETY_DOOR_SUPPORT
|
||||
{ Setting_DoorOptions, Group_SafetyDoor, "Safety door options", NULL, Format_Bitfield, "Ignore when idle,Keep coolant state on open", NULL, NULL, Setting_IsExtended, &settings.safety_door.flags.value, NULL, is_setting_available },
|
||||
{ Setting_DoorOptions, Group_SafetyDoor, "Safety door options", NULL, Format_Bitfield, door_options, NULL, NULL, Setting_IsExtended, &settings.safety_door.flags.value, NULL, is_setting_available },
|
||||
#endif
|
||||
{ Setting_SleepEnable, Group_General, "Sleep enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_sleep_enable, get_int, is_setting_available },
|
||||
{ Setting_HoldActions, Group_General, "Feed hold actions", NULL, Format_Bitfield, "Disable laser during hold,Restore spindle and coolant state on resume", NULL, NULL, Setting_IsExtendedFn, set_hold_actions, get_int, NULL },
|
||||
@@ -2287,7 +2290,8 @@ PROGMEM static const setting_descr_t setting_descr[] = {
|
||||
{ Setting_ParkingFastRate, "Parking fast rate to target after pull-out in mm/min." },
|
||||
{ Setting_RestoreOverrides, "Restore overrides to default values at program end." },
|
||||
#ifndef NO_SAFETY_DOOR_SUPPORT
|
||||
{ Setting_DoorOptions, "Enable this if it is desirable to open the safety door when in IDLE mode (eg. for jogging)." },
|
||||
{ Setting_DoorOptions, "Ignore when idle: disregard door signal in IDLE state to allow jogging etc. Available when controller has door input.\n"
|
||||
"Keep coolant state on open: do not turn off coolant if on." },
|
||||
#endif
|
||||
{ Setting_SleepEnable, "Enable sleep mode." },
|
||||
{ Setting_HoldActions, "Actions taken during feed hold and on resume from feed hold." },
|
||||
@@ -3518,6 +3522,9 @@ void settings_init (void)
|
||||
uint32_t mask = 0b001 | (hal.driver_cap.toolsetter << 1) | (hal.driver_cap.probe2 << 2);
|
||||
setting_remove_elements(Setting_InvertProbePin, mask);
|
||||
setting_remove_elements(Setting_ProbePullUpDisable, mask);
|
||||
#ifndef NO_SAFETY_DOOR_SUPPORT
|
||||
setting_remove_elements(Setting_DoorOptions, ((!settings.parking.flags.enabled || hal.signals_cap.safety_door_ajar) << 1) | hal.signals_cap.safety_door_ajar);
|
||||
#endif
|
||||
|
||||
mask = 0b00011 | (hal.probe.select ? ((hal.driver_cap.toolsetter << 3) | (hal.driver_cap.probe2 << 4)) : 0);
|
||||
#if 0
|
||||
|
||||
@@ -576,16 +576,17 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
// Parking motion not possible. Just disable the spindle and coolant.
|
||||
// NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately.
|
||||
spindle_all_off(); // De-energize
|
||||
if (!settings.safety_door.flags.keep_coolant_on || sys_state == STATE_SLEEP)
|
||||
if(sys.flags.is_parking || sys_state == STATE_SLEEP || !settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
}
|
||||
} else {
|
||||
spindle_all_off(); // De-energize
|
||||
if (!settings.safety_door.flags.keep_coolant_on || sys_state == STATE_SLEEP)
|
||||
if(sys.flags.is_parking || sys_state == STATE_SLEEP || !settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
}
|
||||
sys.flags.is_parking = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -200,10 +200,11 @@ void st_wake_up (void)
|
||||
sys.steppers_deenergize = false;
|
||||
|
||||
hal.stepper.go_idle(true); // Reset step & dir outputs
|
||||
hal.stepper.wake_up();
|
||||
|
||||
if(settings.stepper_enable_delay) // TODO: do not add delay if deenergize is pending?
|
||||
if(!sys.steppers_enabled && settings.stepper_enable_delay)
|
||||
hal.delay_ms(settings.stepper_enable_delay, NULL);
|
||||
|
||||
hal.stepper.wake_up();
|
||||
}
|
||||
|
||||
// Stepper shutdown
|
||||
|
||||
52
stream.c
52
stream.c
@@ -89,7 +89,7 @@ void stream_register_streams (io_stream_details_t *details)
|
||||
}
|
||||
}
|
||||
|
||||
bool stream_enumerate_streams (stream_enumerate_callback_ptr callback)
|
||||
bool stream_enumerate_streams (stream_enumerate_callback_ptr callback, void *data)
|
||||
{
|
||||
if(callback == NULL)
|
||||
return false;
|
||||
@@ -100,7 +100,7 @@ bool stream_enumerate_streams (stream_enumerate_callback_ptr callback)
|
||||
while(details && !claimed) {
|
||||
uint_fast8_t idx;
|
||||
for(idx = 0; idx < details->n_streams; idx++) {
|
||||
if((claimed = callback(&details->streams[idx])))
|
||||
if((claimed = callback(&details->streams[idx], data)))
|
||||
break;
|
||||
}
|
||||
details = details->next;
|
||||
@@ -134,7 +134,8 @@ const io_stream_status_t *stream_get_uart_status (uint8_t instance)
|
||||
while(details) {
|
||||
uint_fast8_t idx;
|
||||
for(idx = 0; idx < details->n_streams; idx++) {
|
||||
if(details->streams[idx].type == StreamType_Serial && details->streams[idx].instance == instance) {
|
||||
if(details->streams[idx].instance == instance &&
|
||||
stream_is_uart(details->streams[idx].type)) {
|
||||
if(details->streams[idx].get_status)
|
||||
status = details->streams[idx].get_status(instance);
|
||||
break;
|
||||
@@ -439,33 +440,38 @@ bool stream_connect (const io_stream_t *stream)
|
||||
{
|
||||
bool ok;
|
||||
|
||||
if((ok = stream_select(stream, true)))
|
||||
if((ok = stream && stream_select(stream, true)))
|
||||
stream_set_description(stream, "Primary UART");
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static struct {
|
||||
typedef struct {
|
||||
uint8_t instance;
|
||||
uint32_t baud_rate;
|
||||
io_stream_t const *stream;
|
||||
} connection;
|
||||
} connection_t;
|
||||
|
||||
static bool _open_instance (io_stream_properties_t const *stream)
|
||||
static bool _open_instance (io_stream_properties_t const *stream, void *data)
|
||||
{
|
||||
if(stream->type == StreamType_Serial && (connection.instance == 255 || stream->instance == connection.instance) && stream->flags.claimable && !stream->flags.claimed)
|
||||
connection.stream = stream->claim(connection.baud_rate);
|
||||
connection_t *connection = (connection_t *)data;
|
||||
|
||||
return connection.stream != NULL;
|
||||
if(stream_is_uart(stream->type) &&
|
||||
(connection->instance == 255 || stream->instance == connection->instance) &&
|
||||
stream->flags.claimable && !stream->flags.claimed)
|
||||
connection->stream = stream->claim(connection->baud_rate);
|
||||
|
||||
return connection->stream != NULL;
|
||||
}
|
||||
|
||||
bool stream_connect_instance (uint8_t instance, uint32_t baud_rate)
|
||||
{
|
||||
connection.instance = instance;
|
||||
connection.baud_rate = baud_rate;
|
||||
connection.stream = NULL;
|
||||
connection_t connection = {
|
||||
.instance = instance,
|
||||
.baud_rate = baud_rate
|
||||
};
|
||||
|
||||
return stream_enumerate_streams(_open_instance) && stream_connect(connection.stream);
|
||||
return stream_enumerate_streams(_open_instance, &connection) && stream_connect(connection.stream);
|
||||
}
|
||||
|
||||
void stream_disconnect (const io_stream_t *stream)
|
||||
@@ -476,11 +482,12 @@ void stream_disconnect (const io_stream_t *stream)
|
||||
|
||||
io_stream_t const *stream_open_instance (uint8_t instance, uint32_t baud_rate, stream_write_char_ptr rx_handler, const char *description)
|
||||
{
|
||||
connection.instance = instance;
|
||||
connection.baud_rate = baud_rate;
|
||||
connection.stream = NULL;
|
||||
connection_t connection = {
|
||||
.instance = instance,
|
||||
.baud_rate = baud_rate
|
||||
};
|
||||
|
||||
if(stream_enumerate_streams(_open_instance)) {
|
||||
if(stream_enumerate_streams(_open_instance, &connection)) {
|
||||
connection.stream->set_enqueue_rt_handler(rx_handler);
|
||||
if(description)
|
||||
stream_set_description(connection.stream, description);
|
||||
@@ -539,7 +546,7 @@ void stream_mpg_set_mode (void *data)
|
||||
stream_mpg_enable(data != NULL);
|
||||
}
|
||||
|
||||
ISR_CODE bool ISR_FUNC(stream_mpg_check_enable)(char c)
|
||||
ISR_CODE bool ISR_FUNC(stream_mpg_check_enable)(uint8_t c)
|
||||
{
|
||||
if(c == CMD_MPG_MODE_TOGGLE)
|
||||
task_add_immediate(stream_mpg_set_mode, (void *)1);
|
||||
@@ -554,7 +561,7 @@ ISR_CODE bool ISR_FUNC(stream_mpg_check_enable)(char c)
|
||||
|
||||
bool stream_mpg_register (const io_stream_t *stream, bool rx_only, stream_write_char_ptr write_char)
|
||||
{
|
||||
if(stream == NULL || stream->type != StreamType_Serial || stream->disable_rx == NULL)
|
||||
if(stream == NULL || !stream_is_uart(stream->type) || stream->disable_rx == NULL)
|
||||
return false;
|
||||
|
||||
// base.flags.is_up = On;
|
||||
@@ -630,8 +637,11 @@ bool stream_mpg_enable (bool on)
|
||||
hal.stream.read = mpg.stream.read;
|
||||
mpg.stream.disable_rx(false);
|
||||
mpg.stream.set_enqueue_rt_handler(hal.stream.set_enqueue_rt_handler(NULL));
|
||||
if(mpg.flags.is_mpg_tx)
|
||||
if(mpg.flags.is_mpg_tx) {
|
||||
hal.stream.write = mpg.stream.write;
|
||||
hal.stream.write_n = mpg.stream.write_n;
|
||||
hal.stream.write_char = mpg.stream.write_char;
|
||||
}
|
||||
hal.stream.get_rx_buffer_free = mpg.stream.get_rx_buffer_free;
|
||||
hal.stream.cancel_read_buffer = mpg.stream.cancel_read_buffer;
|
||||
hal.stream.reset_read_buffer = mpg.stream.reset_read_buffer;
|
||||
|
||||
19
stream.h
19
stream.h
@@ -131,8 +131,10 @@ typedef union {
|
||||
uint8_t value;
|
||||
struct {
|
||||
uint8_t dtr :1,
|
||||
dsr :1,
|
||||
rts :1,
|
||||
unused :6;
|
||||
cts :1,
|
||||
unused :4;
|
||||
};
|
||||
} serial_linestate_t;
|
||||
|
||||
@@ -282,7 +284,9 @@ typedef union {
|
||||
is_usb :1,
|
||||
linestate_event :1, //!< Set when driver supports on_linestate_changed event.
|
||||
passthru :1, //!< Set when stream is in passthru mode.
|
||||
unused :4;
|
||||
utf8 :1, //!< Set when stream is in UTF8 mode.
|
||||
eof :1, //!< Set when a file stream reaches end-of-file.
|
||||
unused :2;
|
||||
};
|
||||
} io_stream_state_t;
|
||||
|
||||
@@ -334,7 +338,7 @@ typedef struct {
|
||||
stream_get_status_ptr get_status; //!< Optional handler for getting stream status, for UART streams only
|
||||
} io_stream_properties_t;
|
||||
|
||||
typedef bool (*stream_enumerate_callback_ptr)(io_stream_properties_t const *properties);
|
||||
typedef bool (*stream_enumerate_callback_ptr)(io_stream_properties_t const *properties, void *data);
|
||||
|
||||
typedef struct io_stream_details {
|
||||
uint8_t n_streams;
|
||||
@@ -380,6 +384,11 @@ typedef struct {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline bool stream_is_uart (stream_type_t type)
|
||||
{
|
||||
return type == StreamType_Serial || type == StreamType_Bluetooth;
|
||||
}
|
||||
|
||||
/*! \brief Dummy function for reading data from a virtual empty input buffer.
|
||||
\returns always -1 as there is no data available.
|
||||
*/
|
||||
@@ -404,7 +413,7 @@ bool stream_mpg_enable (bool on);
|
||||
|
||||
void stream_mpg_set_mode (void *data);
|
||||
|
||||
bool stream_mpg_check_enable (char c);
|
||||
bool stream_mpg_check_enable (uint8_t c);
|
||||
|
||||
bool stream_buffer_all (uint8_t c);
|
||||
|
||||
@@ -414,7 +423,7 @@ bool stream_enqueue_realtime_command (uint8_t c);
|
||||
|
||||
void stream_register_streams (io_stream_details_t *details);
|
||||
|
||||
bool stream_enumerate_streams (stream_enumerate_callback_ptr callback);
|
||||
bool stream_enumerate_streams (stream_enumerate_callback_ptr callback, void *data);
|
||||
|
||||
bool stream_connect (const io_stream_t *stream);
|
||||
|
||||
|
||||
7
system.c
7
system.c
@@ -92,6 +92,7 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
|
||||
} else {
|
||||
#ifndef NO_SAFETY_DOOR_SUPPORT
|
||||
if(signals.safety_door_ajar && hal.signals_cap.safety_door_ajar && !gc_state.tool_change) {
|
||||
sys.flags.is_parking = false;
|
||||
if(settings.safety_door.flags.ignore_when_idle) {
|
||||
// Only stop the spindle (laser off) when idle or jogging,
|
||||
// this to allow positioning the controlled point (spindle) when door is open.
|
||||
@@ -1254,11 +1255,7 @@ void system_raise_alarm (alarm_code_t alarm)
|
||||
system_set_exec_alarm(alarm);
|
||||
else if(sys.alarm != alarm) {
|
||||
sys.alarm = alarm;
|
||||
sys.blocking_event = sys.alarm == Alarm_HardLimit ||
|
||||
sys.alarm == Alarm_SoftLimit ||
|
||||
sys.alarm == Alarm_EStop ||
|
||||
sys.alarm == Alarm_MotorFault;
|
||||
state_set(alarm == Alarm_EStop ? STATE_ESTOP : STATE_ALARM);
|
||||
sys.blocking_event = alarm_is_critical(sys.alarm);
|
||||
if(sys.driver_started || sys.alarm == Alarm_SelftestFailed)
|
||||
grbl.report.alarm_message(alarm);
|
||||
}
|
||||
|
||||
4
system.h
4
system.h
@@ -274,7 +274,8 @@ typedef union {
|
||||
auto_reporting :1, //!< Set to true when auto real time reporting is enabled.
|
||||
travel_changed :1, //!< Set to true when maximum travel settings has changed.
|
||||
is_homing :1,
|
||||
unused :4;
|
||||
is_parking :1, //!< Set to true when CMD_SAFETY_DOOR is received.
|
||||
unused :3;
|
||||
};
|
||||
} system_flags_t;
|
||||
|
||||
@@ -331,6 +332,7 @@ typedef struct system {
|
||||
bool cold_start; //!< Set to true on boot, is false on subsequent soft resets.
|
||||
bool ioinit_pending;
|
||||
bool driver_started; //!< Set to true when driver initialization is completed.
|
||||
bool steppers_enabled; //!< Set to true when all steppers are enabled.
|
||||
bool mpg_mode; //!< To be moved to system_flags_t
|
||||
signal_event_t last_event; //!< Last signal events (control and limits signal).
|
||||
int32_t position[N_AXIS]; //!< Real-time machine (aka home) position vector in steps.
|
||||
|
||||
148
utf8.c
Normal file
148
utf8.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
utf8.c - An embedded CNC Controller with rs274/ngc (g-code) support
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2025 Terje Io
|
||||
|
||||
utf32_to_utf8() is Copyright 2025 Kang-Che Sung, see license below.
|
||||
|
||||
grblHAL is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
grblHAL is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
static enqueue_realtime_command_ptr utf8_base_handler = NULL;
|
||||
|
||||
int32_t utf8_decode (const io_stream_t *stream)
|
||||
{
|
||||
static int32_t count = 0, utf8_c = SERIAL_NO_DATA;
|
||||
|
||||
if((count && (stream->get_rx_buffer_count()) < count) || (utf8_c = stream->read()) == SERIAL_NO_DATA)
|
||||
return SERIAL_NO_DATA;
|
||||
|
||||
if(utf8_c & 0b11100000) {
|
||||
count = (c & 0b11100000) == 0b11100000 ? (c & 0b00110000) >> 4 : 1;
|
||||
if(c & (0b01000000 >> count)) {
|
||||
count = 0;
|
||||
utf8_c = 0xFFFD;
|
||||
} else
|
||||
utf8_c = c & (0b00111111 >> count);
|
||||
}
|
||||
|
||||
if(count) do {
|
||||
|
||||
int32_t c;
|
||||
|
||||
if(((c = stream->read())& 0b11000000) != 0b10000000) {
|
||||
count = 1;
|
||||
utf8_c = 0xFFFD;
|
||||
} else {
|
||||
utf8_c = (utf8_c << 6) | (c & 0b00111111);
|
||||
}
|
||||
} while(--count);
|
||||
|
||||
return utf8_c;
|
||||
}
|
||||
|
||||
ISR_CODE bool ISR_FUNC(utf8_insert)(uint8_t c)
|
||||
{
|
||||
static int32_t count = 0, utf8_c = 0;
|
||||
|
||||
if((c & 0b11000000) == 0b11000000)
|
||||
count = (utf8_c & 0b11100000) == 0b11100000 ? (utf8_c & 0b00110000) >> 4 : 1;
|
||||
else if(count)
|
||||
count--;
|
||||
|
||||
return count ? false : utf8_base_handler(c);
|
||||
}
|
||||
|
||||
bool stream_utf8_enable (const io_stream_t *stream, bool enable)
|
||||
{
|
||||
if(enable) {
|
||||
if(utf8_base_handler == NULL)
|
||||
utf8_base_handler = hal.stream.set_enqueue_rt_handler(utf8_insert);
|
||||
} else {
|
||||
if(utf8_base_handler) {
|
||||
hal.stream.set_enqueue_rt_handler(utf8_base_handler);
|
||||
utf8_base_handler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
<https://gitlab.com/-/snippets/3718423>
|
||||
|
||||
Copyright 2025 Kang-Che Sung <explorer09 @ gmail.com>
|
||||
|
||||
MIT License (MIT/Expat)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
uint16_t utf32_to_utf8 (uint8_t *buffer, uint32_t code_point)
|
||||
{
|
||||
// assert(code_point <= 0x10FFFF);
|
||||
// assert(code_point < 0xD800 || code_point > 0xDFFF);
|
||||
|
||||
if(code_point > 0x10FFFF)
|
||||
return 0;
|
||||
|
||||
uint16_t idx, length = 1;
|
||||
uint32_t first_byte = code_point, mask;
|
||||
|
||||
if(code_point <= 0x7F) {
|
||||
mask = 0b0111111; // We assume ASCII characters appear most frequently.
|
||||
} else {
|
||||
// Find out how many bytes are needed.
|
||||
mask = 0b00111111;
|
||||
do {
|
||||
length++;
|
||||
first_byte >>= 6;
|
||||
mask >>= 1;
|
||||
} while(first_byte > mask);
|
||||
}
|
||||
|
||||
if(length <= 4) {
|
||||
buffer[0] = (uint8_t)(first_byte + (~mask << 1));
|
||||
for(idx = length - 1; idx > 0; idx--) {
|
||||
buffer[idx] = (code_point & 0b00111111) | 0b10000000;
|
||||
code_point >>= 6;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
24
utf8.h
Normal file
24
utf8.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
utf8.c - An embedded CNC Controller with rs274/ngc (g-code) support
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2025 Terje Io
|
||||
|
||||
utf32_to_utf8() is Copyright 2025 Kang-Che Sung, see license in utf8.c.
|
||||
|
||||
grblHAL is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
grblHAL is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
uint16_t utf32_to_utf8 (uint8_t *buffer, uint32_t code_point);
|
||||
Reference in New Issue
Block a user