Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ custom_filesystem_start=0x670000
extra_scripts = ./build_merged.py
build_src_filter = ${common.build_src_filter} +<SystemArduino.cpp> +<HardwareM5Dial.cpp>

# Diagnostic build: m5dial plus USB debug output and FluidNC wire tracing.
# NOTE: FNC_RX_TRACE alone prints nothing on m5dial -- dbg_print/dbg_write are
# compiled out unless DEBUG_TO_USB is also defined (see SystemArduino.cpp).
# pio run -e m5dial_trace -t upload && pio device monitor -e m5dial_trace
[env:m5dial_trace]
extends = env:m5dial
build_flags =
${env:m5dial.build_flags}
-DDEBUG_TO_USB
-DFNC_RX_TRACE

[env:cyd_base]
; Pendant based on a 2432S028 "Cheap Yellow Display" and a hand wheel pulse encoder
; http://wiki.fluidnc.com/en/hardware/official/CYD_Dial_Pendant
Expand Down
59 changes: 55 additions & 4 deletions src/ConfigItem.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
#include "ConfigItem.h"
#include "Scene.h"
#include "System.h"
#include "FileParser.h" // json_in_progress()

std::vector<ConfigItem*> configRequests;

static constexpr uint32_t CONFIG_REQUEST_RETRY_MS = 500;
static uint32_t configRequestSentMs = 0;

// Bound the retries. FluidNC rejects a setting it doesn't have (an axis that
// isn't configured, a key this firmware build lacks) with a bare "error:3",
// which never matches parse_dollar(), so the item never leaves the queue. An
// unbounded retry loop then re-sends it every 500 ms forever. That floods the
// link, blocks every request queued behind it (we only ever send front()), and
// splices error responses into an in-flight $File/SendJSON document -- which is
// what empties the macro list. Give up on the item instead and move on.
static constexpr int CONFIG_REQUEST_MAX_TRIES = 4;

static uint32_t configRequestSentMs = 0;
static int configRequestTries = 0;

static bool can_send_config_request() {
// ensure config requests are sent only when a job is not running - as it won't be processed otherwise
return state == Idle || state == Alarm;
}

static void send_next_config_request() {
static void send_config_request() {
if (configRequests.empty() || !can_send_config_request()) {
return;
}
configRequests.front()->send_request();
configRequestSentMs = millis();
++configRequestTries;
}

// Move on to a different request. The try budget is per item, so reset it.
static void send_next_config_request() {
configRequestTries = 0;
send_config_request();
}

void ConfigItem::init() {
Expand All @@ -40,13 +59,45 @@ void ConfigItem::init() {
void clear_config_requests() {
configRequests.clear();
configRequestSentMs = 0;
configRequestTries = 0;
}

void service_config_requests() {
if (!configRequests.empty() &&
(uint32_t)(millis() - configRequestSentMs) >= CONFIG_REQUEST_RETRY_MS) {
if (configRequests.empty()) {
return;
}
if ((uint32_t)(millis() - configRequestSentMs) < CONFIG_REQUEST_RETRY_MS) {
return;
}
// Never transmit while a JSON document is streaming in. FluidNC answers on
// the same link, so the reply (or its error) lands in the middle of the
// document and derails the parser mid-object.
if (json_in_progress()) {
return;
}
if (configRequestTries >= CONFIG_REQUEST_MAX_TRIES) {
// FluidNC is never going to answer this one. Drop it -- it stays
// !known(), which callers already handle -- so the rest of the queue
// can drain instead of being stuck behind it.
configRequests.erase(configRequests.begin());
send_next_config_request();
return;
}
send_config_request();
}

// Called from show_error() when FluidNC rejects a command and no JSON document
// is in flight. If a config query is outstanding, that error is almost certainly
// its answer: the setting doesn't exist on this machine (an axis that isn't
// configured, a key this firmware lacks). Retrying cannot change that, so drop
// it now rather than burning the whole retry budget at 500 ms a go -- twelve
// homing items would otherwise spend ~24 s flooding the link with error:3.
void config_request_failed() {
if (configRequests.empty() || configRequestTries == 0) {
return; // nothing outstanding, so the error belongs to someone else
}
configRequests.erase(configRequests.begin());
send_next_config_request();
}

void parse_dollar(const char* line) {
Expand Down
1 change: 1 addition & 0 deletions src/ConfigItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
class ConfigItem;
extern std::vector<ConfigItem*> configRequests;
void service_config_requests();
void config_request_failed();
void clear_config_requests();

class ConfigItem {
Expand Down
Loading