mirror of
https://github.com/grblHAL/core.git
synced 2026-08-17 16:41:45 +08:00
No longer retries Modbus commands if there is a pending reset.
Added $MODBUSSTATS and $MODBUSSTATS=R commands, outputs communication statistics such as number of sent commands, retries etc. $MODBUSSTATS=R clears the statistics after outputting it. Ref. issue #753.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## grblHAL ##
|
||||
|
||||
Latest build date is 20250530, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20250604, 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.
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20250604">Build 20250604
|
||||
|
||||
Core:
|
||||
|
||||
* No longer retries Modbus commands if there is a pending reset.
|
||||
|
||||
* Added `$MODBUSSTATS` and `$MODBUSSTATS=R` commands, outputs communication statistics such as number of sent commands, retries etc.
|
||||
`$MODBUSSTATS=R` clears the statistics after outputting it. Ref. issue [#753](https://github.com/grblHAL/core/issues/753).
|
||||
|
||||
Drivers:
|
||||
|
||||
* STM32Fxxx: bug fix - moved code for assigning IRQs for auxiliary inputs from the core to the drivers.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Spindle: "hardened" code for Huanyang VFD drivers to prevent hardfaults. Updated some VFD drivers to delay reading data from the VFD till after a pending soft reset has been executed.
|
||||
|
||||
---
|
||||
|
||||
<a name="20250530">Build 20250530
|
||||
|
||||
Core:
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20250530
|
||||
#define GRBL_BUILD 20250604
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
+46
-2
@@ -21,9 +21,11 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "platform.h"
|
||||
#include "protocol.h"
|
||||
#include "settings.h"
|
||||
#include "crc.h"
|
||||
@@ -89,6 +91,14 @@ static volatile queue_entry_t *tail, *head, *packet = NULL;
|
||||
static volatile modbus_state_t state = ModBus_Idle;
|
||||
static uint8_t dir_port = IOPORT_UNASSIGNED;
|
||||
|
||||
static struct {
|
||||
uint32_t tx_count;
|
||||
uint32_t retries;
|
||||
uint32_t timeouts;
|
||||
uint32_t crc_errors;
|
||||
uint32_t rx_exceptions;
|
||||
} stats = {};
|
||||
|
||||
static driver_reset_ptr driver_reset;
|
||||
static on_report_options_ptr on_report_options;
|
||||
static nvs_address_t nvs_address;
|
||||
@@ -107,16 +117,19 @@ static void retry_exception (uint8_t code, void *context)
|
||||
if(packet && packet->callbacks.retries) {
|
||||
state = ModBus_Retry;
|
||||
silence_until = hal.get_elapsed_ticks() + silence_timeout + packet->callbacks.retry_delay;
|
||||
stats.retries++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline queue_entry_t *add_message (queue_entry_t *packet, modbus_message_t *msg, bool async, const modbus_callbacks_t *callbacks)
|
||||
{
|
||||
stats.tx_count++;
|
||||
|
||||
memcpy(&packet->msg, msg, sizeof(modbus_message_t));
|
||||
|
||||
packet->async = async;
|
||||
|
||||
if(callbacks) {
|
||||
if(callbacks && !sys.reset_pending) {
|
||||
memcpy(&packet->callbacks, callbacks, sizeof(modbus_callbacks_t));
|
||||
if(!packet->async && packet->callbacks.retries)
|
||||
packet->callbacks.on_rx_exception = retry_exception;
|
||||
@@ -184,6 +197,9 @@ static void modbus_poll (void *data)
|
||||
|
||||
case ModBus_AwaitReply:
|
||||
if(rx_timeout && --rx_timeout == 0) {
|
||||
|
||||
stats.timeouts++;
|
||||
|
||||
if(packet->async) {
|
||||
state = ModBus_Silent;
|
||||
if(packet->callbacks.on_rx_exception)
|
||||
@@ -192,8 +208,10 @@ static void modbus_poll (void *data)
|
||||
} else if(stream.read() == packet->msg.adu[0] && (stream.read() & 0x80)) {
|
||||
exception_code = stream.read();
|
||||
state = ModBus_Exception;
|
||||
stats.rx_exceptions++;
|
||||
} else
|
||||
state = ModBus_Timeout;
|
||||
|
||||
spin_lock = false;
|
||||
if(state != ModBus_AwaitReply)
|
||||
silence_until = hal.get_elapsed_ticks() + silence_timeout;
|
||||
@@ -210,10 +228,11 @@ static void modbus_poll (void *data)
|
||||
} while(--packet->msg.rx_length);
|
||||
|
||||
if(packet->msg.crc_check) {
|
||||
uint_fast16_t crc = modbus_crc16x(((queue_entry_t *)packet)->msg.adu, rx_len - 2);
|
||||
|
||||
uint_fast16_t crc = modbus_crc16x(((queue_entry_t *)packet)->msg.adu, rx_len - 2);
|
||||
if(packet->msg.adu[rx_len - 2] != (crc & 0xFF) || packet->msg.adu[rx_len - 1] != (crc >> 8)) {
|
||||
// CRC check error
|
||||
stats.crc_errors++;
|
||||
if((state = packet->async ? ModBus_Silent : ModBus_Exception) == ModBus_Silent) {
|
||||
if(packet->callbacks.on_rx_exception)
|
||||
packet->callbacks.on_rx_exception(0, packet->msg.context);
|
||||
@@ -499,6 +518,20 @@ static bool claim_stream (io_stream_properties_t const *sstream)
|
||||
|
||||
return claimed != NULL;
|
||||
}
|
||||
static status_code_t report_stats (sys_state_t state, char *args)
|
||||
{
|
||||
char buf[110];
|
||||
|
||||
snprintf(buf, sizeof(buf) - 1, "TX: " UINT32FMT ", retries: " UINT32FMT ", timeouts: " UINT32FMT ", RX exceptions: " UINT32FMT ", CRC errors: " UINT32FMT,
|
||||
stats.tx_count, stats.retries, stats.timeouts, stats.rx_exceptions, stats.crc_errors);
|
||||
|
||||
report_message(buf, Message_Info);
|
||||
|
||||
if(args && (*args == 'r' || *args == 'R'))
|
||||
stats.tx_count = stats.retries = stats.timeouts = stats.rx_exceptions = stats.crc_errors = 0;
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
void modbus_rtu_init (int8_t stream, int8_t dir_aux)
|
||||
{
|
||||
@@ -520,6 +553,15 @@ void modbus_rtu_init (int8_t stream, int8_t dir_aux)
|
||||
.restore = modbus_settings_restore
|
||||
};
|
||||
|
||||
static const sys_command_t command_list[] = {
|
||||
{"MODBUSSTATS", report_stats, { .allow_blocking = On }, { .str = "output Modbus RTU statistics" } },
|
||||
};
|
||||
|
||||
static sys_commands_t commands = {
|
||||
.n_commands = sizeof(command_list) / sizeof(sys_command_t),
|
||||
.commands = command_list
|
||||
};
|
||||
|
||||
if(dir_aux != -2) {
|
||||
|
||||
int8_t n_out = ioports_available(Port_Digital, Port_Output);
|
||||
@@ -557,6 +599,8 @@ void modbus_rtu_init (int8_t stream, int8_t dir_aux)
|
||||
|
||||
modbus_register_api(&api);
|
||||
|
||||
system_register_commands(&commands);
|
||||
|
||||
modbus_set_silence(NULL);
|
||||
|
||||
} else {
|
||||
|
||||
+107
-89
@@ -112,147 +112,153 @@
|
||||
#endif
|
||||
|
||||
static aux_ctrl_t aux_ctrl[] = {
|
||||
// The following pins are bound explicitly to aux input pins
|
||||
// The following pins are bound explicitly to aux input pins.
|
||||
#if (CONTROL_ENABLE & CONTROL_ESTOP) && defined(RESET_PIN)
|
||||
#ifndef RESET_PORT
|
||||
#define RESET_PORT 0
|
||||
#endif
|
||||
{ .function = Input_EStop, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .e_stop = On }, .pin = RESET_PIN, .port = (void *)RESET_PORT },
|
||||
{ .function = Input_EStop, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .e_stop = On }, .pin = RESET_PIN, .port = (void *)RESET_PORT },
|
||||
#elif (CONTROL_ENABLE & CONTROL_RESET) && defined(RESET_PIN)
|
||||
#ifndef RESET_PORT
|
||||
#define RESET_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Reset, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .reset = On }, .pin = RESET_PIN, .port = (void *)RESET_PORT },
|
||||
{ .function = Input_Reset, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .reset = On }, .pin = RESET_PIN, .port = (void *)RESET_PORT },
|
||||
#endif
|
||||
#if (CONTROL_ENABLE & CONTROL_FEED_HOLD) && defined(FEED_HOLD_PIN)
|
||||
#ifndef FEED_HOLD_PORT
|
||||
#define FEED_HOLD_PORT 0
|
||||
#endif
|
||||
{ .function = Input_FeedHold, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .feed_hold = On }, .pin = FEED_HOLD_PIN, .port = (void *)FEED_HOLD_PORT },
|
||||
{ .function = Input_FeedHold, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .feed_hold = On }, .pin = FEED_HOLD_PIN, .port = (void *)FEED_HOLD_PORT },
|
||||
#endif
|
||||
#if (CONTROL_ENABLE & CONTROL_CYCLE_START) && defined(CYCLE_START_PIN)
|
||||
#ifndef CYCLE_START_PORT
|
||||
#define CYCLE_START_PORT 0
|
||||
#endif
|
||||
{ .function = Input_CycleStart, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .cycle_start = On }, .pin = CYCLE_START_PIN, .port = (void *)CYCLE_START_PORT },
|
||||
{ .function = Input_CycleStart, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .cycle_start = On }, .pin = CYCLE_START_PIN, .port = (void *)CYCLE_START_PORT },
|
||||
#endif
|
||||
#if SAFETY_DOOR_ENABLE && defined(SAFETY_DOOR_PIN)
|
||||
#ifndef SAFETY_DOOR_PORT
|
||||
#define SAFETY_DOOR_PORT 0
|
||||
#endif
|
||||
{ .function = Input_SafetyDoor, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .safety_door_ajar = On }, .pin = SAFETY_DOOR_PIN, .port = (void *)SAFETY_DOOR_PORT },
|
||||
{ .function = Input_SafetyDoor, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .safety_door_ajar = On }, .pin = SAFETY_DOOR_PIN, .port = (void *)SAFETY_DOOR_PORT },
|
||||
#endif
|
||||
#if MOTOR_FAULT_ENABLE && defined(MOTOR_FAULT_PIN)
|
||||
#ifndef MOTOR_FAULT_PORT
|
||||
#define MOTOR_FAULT_PORT 0
|
||||
#endif
|
||||
{ .function = Input_MotorFault, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .motor_fault = On }, .pin = MOTOR_FAULT_PIN, .port = (void *)MOTOR_FAULT_PORT },
|
||||
{ .function = Input_MotorFault, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .motor_fault = On }, .pin = MOTOR_FAULT_PIN, .port = (void *)MOTOR_FAULT_PORT },
|
||||
#endif
|
||||
#if MOTOR_WARNING_ENABLE && defined(MOTOR_WARNING_PIN)
|
||||
#ifndef MOTOR_WARNING_PORT
|
||||
#define MOTOR_WARNING_PORT 0
|
||||
#endif
|
||||
{ .function = Input_MotorWarning, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .motor_fault = On }, .pin = MOTOR_WARNING_PIN, .port = (void *)MOTOR_WARNING_PORT },
|
||||
#endif
|
||||
|
||||
#if PROBE_ENABLE && defined(PROBE_PIN)
|
||||
#ifndef PROBE_PORT
|
||||
#define PROBE_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Probe, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = PROBE_PIN, .port = (void *)PROBE_PORT },
|
||||
#endif
|
||||
#if PROBE2_ENABLE && defined(PROBE2_PIN)
|
||||
#ifndef PROBE2_PORT
|
||||
#define PROBE2_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Probe2, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = PROBE2_PIN, .port = (void *)PROBE2_PORT },
|
||||
#endif
|
||||
#if TOOLSETTER_ENABLE && defined(TOOLSETTER_PIN)
|
||||
#ifndef TOOLSETTER_PORT
|
||||
#define TOOLSETTER_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Toolsetter, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = TOOLSETTER_PIN, .port = (void *)TOOLSETTER_PORT },
|
||||
{ .function = Input_MotorWarning, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .motor_fault = On }, .pin = MOTOR_WARNING_PIN, .port = (void *)MOTOR_WARNING_PORT },
|
||||
#endif
|
||||
|
||||
#if I2C_STROBE_ENABLE && defined(I2C_STROBE_PIN)
|
||||
#ifndef I2C_STROBE_PORT
|
||||
#define I2C_STROBE_PORT 0
|
||||
#endif
|
||||
{ .function = Input_I2CStrobe, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .value = 0 }, .pin = I2C_STROBE_PIN, .port = (void *)I2C_STROBE_PORT },
|
||||
{ .function = Input_I2CStrobe, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_Change, .cap = { .value = 0 }, .pin = I2C_STROBE_PIN, .port = (void *)I2C_STROBE_PORT },
|
||||
#endif
|
||||
#if MPG_ENABLE == 1 && defined(MPG_MODE_PIN)
|
||||
#ifndef MPG_MODE_PORT
|
||||
#define MPG_MODE_PORT 0
|
||||
#endif
|
||||
{ .function = Input_MPGSelect, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .value = 0 }, .pin = MPG_MODE_PIN, .port = (void *)MPG_MODE_PORT },
|
||||
{ .function = Input_MPGSelect, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_Change, .cap = { .value = 0 }, .pin = MPG_MODE_PIN, .port = (void *)MPG_MODE_PORT },
|
||||
#endif
|
||||
#if QEI_SELECT_ENABLE && defined(QEI_SELECT_PIN)
|
||||
#ifndef QEI_SELECT_PORT
|
||||
#define QEI_SELECT_PORT 0
|
||||
#endif
|
||||
{ .function = Input_QEI_Select, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = QEI_SELECT_PIN, .port = (void *)QEI_SELECT_PORT },
|
||||
{ .function = Input_QEI_Select, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = QEI_SELECT_PIN, .port = (void *)QEI_SELECT_PORT },
|
||||
#endif
|
||||
|
||||
// Probe pins can be bound explicitly and can be "degraded" to not interrupt capable.
|
||||
#if PROBE_ENABLE && defined(PROBE_PIN)
|
||||
#ifndef PROBE_PORT
|
||||
#define PROBE_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Probe, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = PROBE_PIN, .port = (void *)PROBE_PORT },
|
||||
#endif
|
||||
#if PROBE2_ENABLE && defined(PROBE2_PIN)
|
||||
#ifndef PROBE2_PORT
|
||||
#define PROBE2_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Probe2, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = PROBE2_PIN, .port = (void *)PROBE2_PORT },
|
||||
#endif
|
||||
#if TOOLSETTER_ENABLE && defined(TOOLSETTER_PIN)
|
||||
#ifndef TOOLSETTER_PORT
|
||||
#define TOOLSETTER_PORT 0
|
||||
#endif
|
||||
{ .function = Input_Toolsetter, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = TOOLSETTER_PIN, .port = (void *)TOOLSETTER_PORT },
|
||||
#endif
|
||||
|
||||
// The following pins are allocated from remaining aux inputs pool
|
||||
#if TOOLSETTER_ENABLE && !defined(TOOLSETTER_PIN)
|
||||
{ .function = Input_Toolsetter, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = 0xFE, .port = NULL },
|
||||
{ .function = Input_Toolsetter, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = 0xFE, .port = NULL },
|
||||
#endif
|
||||
#if PROBE2_ENABLE && !defined(PROBE2_PIN)
|
||||
{ .function = Input_Probe2, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = 0xFE, .port = NULL },
|
||||
{ .function = Input_Probe2, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .value = 0 }, .pin = 0xFE, .port = NULL },
|
||||
#endif
|
||||
#if LIMITS_OVERRIDE_ENABLE
|
||||
{ .function = Input_LimitsOverride, .aux_port = 0xFF, .irq_mode = IRQ_Mode_None, .cap = { .limits_override = On }, .pin = 0xFF, .port = NULL },
|
||||
{ .function = Input_LimitsOverride, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_None, .cap = { .limits_override = On }, .pin = 0xFF, .port = NULL },
|
||||
#endif
|
||||
#if STOP_DISABLE_ENABLE
|
||||
{ .function = Input_StopDisable, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .stop_disable = On }, .pin = 0xFF, .port = NULL },
|
||||
{ .function = Input_StopDisable, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_Change, .cap = { .stop_disable = On }, .pin = 0xFF, .port = NULL },
|
||||
#endif
|
||||
#if BLOCK_DELETE_ENABLE
|
||||
{ .function = Input_BlockDelete, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .block_delete = On }, .pin = 0xFF, .port = NULL },
|
||||
{ .function = Input_BlockDelete, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_Change, .cap = { .block_delete = On }, .pin = 0xFF, .port = NULL },
|
||||
#endif
|
||||
#if SINGLE_BLOCK_ENABLE
|
||||
{ .function = Input_SingleBlock, .aux_port = 0xFF, .irq_mode = IRQ_Mode_Change, .cap = { .single_block = On }, .pin = 0xFF, .port = NULL },
|
||||
{ .function = Input_SingleBlock, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_Change, .cap = { .single_block = On }, .pin = 0xFF, .port = NULL },
|
||||
#endif
|
||||
#if PROBE_DISCONNECT_ENABLE
|
||||
{ .function = Input_ProbeDisconnect, .aux_port = 0xFF, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .probe_disconnected = On }, .pin = 0xFF, .port = NULL },
|
||||
{ .function = Input_ProbeDisconnect, .aux_port = IOPORT_UNASSIGNED, .irq_mode = IRQ_Mode_RisingFalling, .cap = { .probe_disconnected = On }, .pin = 0xFF, .port = NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline bool aux_ctrl_is_probe (pin_function_t function)
|
||||
{
|
||||
return function == Input_Probe || function == Input_Probe2 || function == Input_Toolsetter;
|
||||
}
|
||||
|
||||
#ifdef STM32_PLATFORM
|
||||
|
||||
static inline aux_ctrl_t *aux_ctrl_get_fn (void *port, uint8_t pin)
|
||||
{
|
||||
aux_ctrl_t *ctrl_pin = NULL;
|
||||
|
||||
if(sizeof(aux_ctrl) / sizeof(aux_ctrl_t)) {
|
||||
uint_fast8_t idx;
|
||||
for(idx = 0; ctrl_pin == NULL && aux_ctrl[idx].pin != 0xFF && idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) {
|
||||
if(aux_ctrl[idx].pin == pin && aux_ctrl[idx].port == port)
|
||||
ctrl_pin = &aux_ctrl[idx];
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl_pin;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline aux_ctrl_t *aux_ctrl_remap_explicit (void *port, uint8_t pin, uint8_t aux_port, void *input)
|
||||
{
|
||||
aux_ctrl_t *ctrl_pin = NULL;
|
||||
|
||||
uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
|
||||
if(sizeof(aux_ctrl) / sizeof(aux_ctrl_t)) {
|
||||
|
||||
if(idx) do {
|
||||
idx--;
|
||||
if(aux_ctrl[idx].port == port && aux_ctrl[idx].pin == pin) {
|
||||
ctrl_pin = &aux_ctrl[idx];
|
||||
ctrl_pin->aux_port = aux_port;
|
||||
ctrl_pin->input = input;
|
||||
}
|
||||
} while(idx && ctrl_pin == NULL);
|
||||
uint_fast8_t idx;
|
||||
|
||||
#ifdef STM32_PLATFORM
|
||||
|
||||
// "Hack" to downgrade pin IRQ mode if multiple pins are defined for the same IRQ.
|
||||
|
||||
if(ctrl_pin) {
|
||||
|
||||
idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t);
|
||||
const control_signals_t main_signals = { .reset = On, .e_stop = On, .feed_hold = On, .cycle_start = On };
|
||||
|
||||
do {
|
||||
if(aux_ctrl[--idx].pin == ctrl_pin->pin) {
|
||||
if(ctrl_pin != &aux_ctrl[idx]) {
|
||||
if((aux_ctrl[idx].cap.bits & main_signals.bits) || (aux_ctrl[idx].cap.bits && !ctrl_pin->cap.bits))
|
||||
ctrl_pin->irq_mode = IRQ_Mode_None;
|
||||
} else if(ctrl_pin->cap.bits && !(aux_ctrl[idx].cap.bits & main_signals.bits))
|
||||
aux_ctrl[idx].irq_mode = IRQ_Mode_None;
|
||||
for(idx = 0; ctrl_pin == NULL && aux_ctrl[idx].pin != 0xFF && idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) {
|
||||
if(aux_ctrl[idx].pin == pin && aux_ctrl[idx].port == port) {
|
||||
ctrl_pin = &aux_ctrl[idx];
|
||||
ctrl_pin->aux_port = aux_port;
|
||||
ctrl_pin->input = input;
|
||||
}
|
||||
} while(idx);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // STM32_PLATFORM
|
||||
|
||||
return ctrl_pin;
|
||||
}
|
||||
|
||||
@@ -276,7 +282,7 @@ static inline void aux_ctrl_irq_enable (settings_t *settings, ioport_interrupt_c
|
||||
|
||||
if(idx) do {
|
||||
if(aux_ctrl[--idx].aux_port != 0xFF && aux_ctrl[idx].irq_mode != IRQ_Mode_None) {
|
||||
if(!(aux_ctrl[idx].function == Input_Probe || aux_ctrl[idx].function == Input_Probe2 || aux_ctrl[idx].function == Input_Toolsetter)) {
|
||||
if(!aux_ctrl_is_probe(aux_ctrl[idx].function)) {
|
||||
pin_irq_mode_t irq_mode;
|
||||
if((irq_mode = aux_ctrl[idx].irq_mode) & IRQ_Mode_RisingFalling)
|
||||
irq_mode = (settings->control_invert.mask & aux_ctrl[idx].cap.mask) ? IRQ_Mode_Falling : IRQ_Mode_Rising;
|
||||
@@ -293,7 +299,7 @@ static bool aux_ctrl_claim_port (xbar_t *properties, uint8_t port, void *data)
|
||||
if(ioport_claim(Port_Digital, Port_Input, &port, xbar_fn_to_pinname(((aux_ctrl_t *)data)->function)))
|
||||
((aux_ctrl_t *)data)->aux_port = port;
|
||||
|
||||
return ((aux_ctrl_t *)data)->aux_port != 0xFF;
|
||||
return ((aux_ctrl_t *)data)->aux_port != IOPORT_UNASSIGNED;
|
||||
}
|
||||
|
||||
static bool aux_ctrl_find_port (xbar_t *properties, uint8_t port, void *data)
|
||||
@@ -323,7 +329,7 @@ static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explic
|
||||
if(aux_ctrl[idx].pin == 0xFF) {
|
||||
if(ioports_enumerate(Port_Digital, Port_Input, cap, aux_claim, (void *)&aux_ctrl[idx]))
|
||||
hal.signals_cap.mask |= aux_ctrl[idx].cap.mask;
|
||||
} else if(aux_ctrl[idx].aux_port != 0xFF)
|
||||
} else if(aux_ctrl[idx].aux_port != IOPORT_UNASSIGNED)
|
||||
aux_claim_explicit(&aux_ctrl[idx]);
|
||||
}
|
||||
}
|
||||
@@ -337,7 +343,7 @@ static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals)
|
||||
if(idx) do {
|
||||
if(aux_ctrl[--idx].pin != 0xFF)
|
||||
break;
|
||||
if(aux_ctrl[idx].aux_port != 0xFF) {
|
||||
if(aux_ctrl[idx].aux_port != IOPORT_UNASSIGNED) {
|
||||
signals.mask &= ~aux_ctrl[idx].cap.mask;
|
||||
#ifdef GRBL_ESP32 // Snowflake guru workaround
|
||||
if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].aux_port, WaitMode_Immediate, FZERO) == 1)
|
||||
@@ -358,99 +364,111 @@ static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals)
|
||||
static aux_ctrl_out_t aux_ctrl_out[] = {
|
||||
#if defined(ESP_PLATFORM) || defined(RP2040) // for now
|
||||
#if defined(STEPPERS_ENABLE_PIN) && STEPPERS_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnable, .aux_port = 0xFF, .pin = STEPPERS_ENABLE_PIN, .port = (void *)STEPPERS_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnable, .aux_port = IOPORT_UNASSIGNED, .pin = STEPPERS_ENABLE_PIN, .port = (void *)STEPPERS_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(X_ENABLE_PIN) && X_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableX, .aux_port = 0xFF, .pin = X_ENABLE_PIN, .port = (void *)X_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableX, .aux_port = IOPORT_UNASSIGNED, .pin = X_ENABLE_PIN, .port = (void *)X_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(X2_ENABLE_PIN) && X2_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableX2, .aux_port = 0xFF, .pin = X2_ENABLE_PIN, .port = (void *)X2_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableX2, .aux_port = IOPORT_UNASSIGNED, .pin = X2_ENABLE_PIN, .port = (void *)X2_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(Y_ENABLE_PIN) && Y_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableY, .aux_port = 0xFF, .pin = Y_ENABLE_PIN, .port = (void *)Y_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableY, .aux_port = IOPORT_UNASSIGNED, .pin = Y_ENABLE_PIN, .port = (void *)Y_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(Y2_ENABLE_PIN) && Y2_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableY2, .aux_port = 0xFF, .pin = Y2_ENABLE_PIN, .port = (void *)Y2_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableY2, .aux_port = IOPORT_UNASSIGNED, .pin = Y2_ENABLE_PIN, .port = (void *)Y2_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(XY_ENABLE_PIN) && XY_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableXY, .aux_port = 0xFF, .pin = XY_ENABLE_PIN, .port = (void *)XY_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableXY, .aux_port = IOPORT_UNASSIGNED, .pin = XY_ENABLE_PIN, .port = (void *)XY_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(Z_ENABLE_PIN) && Z_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableZ, .aux_port = 0xFF, .pin = Z_ENABLE_PIN, .port = (void *)Z_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableZ, .aux_port = IOPORT_UNASSIGNED, .pin = Z_ENABLE_PIN, .port = (void *)Z_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(Z2_ENABLE_PIN) && Z2_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableZ2, .aux_port = 0xFF, .pin = Z2_ENABLE_PIN, .port = (void *)Z2_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableZ2, .aux_port = IOPORT_UNASSIGNED, .pin = Z2_ENABLE_PIN, .port = (void *)Z2_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(A_ENABLE_PIN) && A_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableA, .aux_port = 0xFF, .pin = A_ENABLE_PIN, .port = (void *)A_ENABLE_PORT },
|
||||
{ .function = Output_StepperEnableA, .aux_port = IOPORT_UNASSIGNED, .pin = A_ENABLE_PIN, .port = (void *)A_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(B_ENABLE_PIN) && B_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableB, .aux_port = IOPORT_UNASSIGNED, .pin = B_ENABLE_PIN, .port = (void *)B_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(C_ENABLE_PIN) && C_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableC, .aux_port = IOPORT_UNASSIGNED, .pin = C_ENABLE_PIN, .port = (void *)C_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(U_ENABLE_PIN) && U_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableU, .aux_port = IOPORT_UNASSIGNED, .pin = U_ENABLE_PIN, .port = (void *)U_ENABLE_PORT },
|
||||
#endif
|
||||
#if defined(V_ENABLE_PIN) && AV_ENABLE_PORT == EXPANDER_PORT
|
||||
{ .function = Output_StepperEnableV, .aux_port = IOPORT_UNASSIGNED, .pin = V_ENABLE_PIN, .port = (void *)V_ENABLE_PORT },
|
||||
#endif
|
||||
#endif //
|
||||
#ifdef SPINDLE_ENABLE_PIN
|
||||
#ifndef SPINDLE_ENABLE_PORT
|
||||
#define SPINDLE_ENABLE_PORT 0
|
||||
#endif
|
||||
{ .function = Output_SpindleOn, .aux_port = 0xFF, .pin = SPINDLE_ENABLE_PIN, .port = (void *)SPINDLE_ENABLE_PORT },
|
||||
{ .function = Output_SpindleOn, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE_ENABLE_PIN, .port = (void *)SPINDLE_ENABLE_PORT },
|
||||
#endif
|
||||
#ifdef SPINDLE_PWM_PIN
|
||||
#ifndef SPINDLE_PWM_PORT
|
||||
#define SPINDLE_PWM_PORT 0
|
||||
#endif
|
||||
{ .function = Output_SpindlePWM, .aux_port = 0xFF, .pin = SPINDLE_PWM_PIN, .port = (void *)SPINDLE_PWM_PORT },
|
||||
{ .function = Output_SpindlePWM, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE_PWM_PIN, .port = (void *)SPINDLE_PWM_PORT },
|
||||
#endif
|
||||
#ifdef SPINDLE_DIRECTION_PIN
|
||||
#ifndef SPINDLE_DIRECTION_PORT
|
||||
#define SPINDLE_DIRECTION_PORT 0
|
||||
#endif
|
||||
{ .function = Output_SpindleDir, .aux_port = 0xFF, .pin = SPINDLE_DIRECTION_PIN, .port = (void *)SPINDLE_DIRECTION_PORT },
|
||||
{ .function = Output_SpindleDir, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE_DIRECTION_PIN, .port = (void *)SPINDLE_DIRECTION_PORT },
|
||||
#endif
|
||||
|
||||
#ifdef SPINDLE1_ENABLE_PIN
|
||||
#ifndef SPINDLE1_ENABLE_PORT
|
||||
#define SPINDLE1_ENABLE_PORT 0
|
||||
#endif
|
||||
{ .function = Output_Spindle1On, .aux_port = 0xFF, .pin = SPINDLE1_ENABLE_PIN, .port = (void *)SPINDLE1_ENABLE_PORT },
|
||||
{ .function = Output_Spindle1On, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE1_ENABLE_PIN, .port = (void *)SPINDLE1_ENABLE_PORT },
|
||||
#endif
|
||||
#ifdef SPINDLE1_PWM_PIN
|
||||
#ifndef SPINDLE1_PWM_PORT
|
||||
#define SPINDLE1_PWM_PORT 0
|
||||
#endif
|
||||
{ .function = Output_Spindle1PWM, .aux_port = 0xFF, .pin = SPINDLE1_PWM_PIN, .port = (void *)SPINDLE1_PWM_PORT },
|
||||
{ .function = Output_Spindle1PWM, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE1_PWM_PIN, .port = (void *)SPINDLE1_PWM_PORT },
|
||||
#endif
|
||||
#ifdef SPINDLE1_DIRECTION_PIN
|
||||
#ifndef SPINDLE1_DIRECTION_PORT
|
||||
#define SPINDLE1_DIRECTION_PORT 0
|
||||
#endif
|
||||
{ .function = Output_Spindle1Dir, .aux_port = 0xFF, .pin = SPINDLE1_DIRECTION_PIN, .port = (void *)SPINDLE1_DIRECTION_PORT },
|
||||
{ .function = Output_Spindle1Dir, .aux_port = IOPORT_UNASSIGNED, .pin = SPINDLE1_DIRECTION_PIN, .port = (void *)SPINDLE1_DIRECTION_PORT },
|
||||
#endif
|
||||
|
||||
#ifdef COOLANT_FLOOD_PIN
|
||||
#ifndef COOLANT_FLOOD_PORT
|
||||
#define COOLANT_FLOOD_PORT 0
|
||||
#endif
|
||||
{ .function = Output_CoolantFlood, .aux_port = 0xFF, .pin = COOLANT_FLOOD_PIN, .port = (void *)COOLANT_FLOOD_PORT },
|
||||
{ .function = Output_CoolantFlood, .aux_port = IOPORT_UNASSIGNED, .pin = COOLANT_FLOOD_PIN, .port = (void *)COOLANT_FLOOD_PORT },
|
||||
#endif
|
||||
#ifdef COOLANT_MIST_PIN
|
||||
#ifndef COOLANT_MIST_PORT
|
||||
#define COOLANT_MIST_PORT 0
|
||||
#endif
|
||||
{ .function = Output_CoolantMist, .aux_port = 0xFF, .pin = COOLANT_MIST_PIN, .port = (void *)COOLANT_MIST_PORT },
|
||||
{ .function = Output_CoolantMist, .aux_port = IOPORT_UNASSIGNED, .pin = COOLANT_MIST_PIN, .port = (void *)COOLANT_MIST_PORT },
|
||||
#endif
|
||||
|
||||
#ifdef COPROC_RESET_PIN
|
||||
#ifndef COPROC_RESET_PORT
|
||||
#define COPROC_RESET_PORT 0
|
||||
#endif
|
||||
{ .function = Output_CoProc_Reset, .aux_port = 0xFF, .pin = COPROC_RESET_PIN, .port = (void *)COPROC_RESET_PORT },
|
||||
{ .function = Output_CoProc_Reset, .aux_port = IOPORT_UNASSIGNED, .pin = COPROC_RESET_PIN, .port = (void *)COPROC_RESET_PORT },
|
||||
#endif
|
||||
#ifdef COPROC_BOOT0_PIN
|
||||
#ifndef COPROC_BOOT0_PORT
|
||||
#define COPROC_BOOT0_PORT 0
|
||||
#endif
|
||||
{ .function = Output_CoProc_Boot0, .aux_port = 0xFF, .pin = COPROC_BOOT0_PIN, .port = (void *)COPROC_BOOT0_PORT },
|
||||
{ .function = Output_CoProc_Boot0, .aux_port = IOPORT_UNASSIGNED, .pin = COPROC_BOOT0_PIN, .port = (void *)COPROC_BOOT0_PORT },
|
||||
#endif
|
||||
#if defined(SPI_RST_PIN) && defined(RP2040)
|
||||
#if SPI_RST_PORT == EXPANDER_PORT
|
||||
{ .function = Output_SPIRST, .aux_port = 0xFF, .pin = SPI_RST_PIN, .port = (void *)SPI_RST_PORT },
|
||||
{ .function = Output_SPIRST, .aux_port = IOPORT_UNASSIGNED, .pin = SPI_RST_PIN, .port = (void *)SPI_RST_PORT },
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user