Skip to content

Commit

Permalink
πŸ§‘β€πŸ’» General and Axis-based bitfield flags (MarlinFirmware#23989)
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead authored and Omkar Dhekne committed Mar 25, 2024
1 parent 0ad1239 commit 38443cb
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 51 deletions.
53 changes: 53 additions & 0 deletions Marlin/src/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,59 @@ struct IF<true, L, R> { typedef L type; };

#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L)

// General Flags for some number of states
template<size_t N>
struct Flags {
typedef typename IF<(N>8), uint16_t, uint8_t>::type bits_t;
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8;
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1; } N16;
union {
bits_t b;
typename IF<(N>8), N16, N8>::type flag;
};
void reset() { b = 0; }
void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); }
void set(const int n) { b |= (bits_t)_BV(n); }
void clear(const int n) { b &= ~(bits_t)_BV(n); }
bool test(const int n) const { return TEST(b, n); }
bool operator[](const int n) { return test(n); }
const bool operator[](const int n) const { return test(n); }
const int size() const { return sizeof(b); }
};

// Specialization for a single bool flag
template<>
struct Flags<1> {
bool b;
void reset() { b = false; }
void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); }
void set(const int) { b = true; }
void clear(const int) { b = false; }
bool test(const int) const { return b; }
bool operator[](const int) { return b; }
const bool operator[](const int) const { return b; }
const int size() const { return sizeof(b); }
};

typedef Flags<8> flags_8_t;
typedef Flags<16> flags_16_t;

// Flags for some axis states, with per-axis aliases xyzijkuvwe
typedef struct AxisFlags {
union {
struct Flags<LOGICAL_AXES> flags;
struct { bool LOGICAL_AXIS_LIST(e:1, x:1, y:1, z:1, i:1, j:1, k:1, u:1, v:1, w:1); };
};
void reset() { flags.reset(); }
void set(const int n) { flags.set(n); }
void set(const int n, const bool onoff) { flags.set(n, onoff); }
void clear(const int n) { flags.clear(n); }
bool test(const int n) const { return flags.test(n); }
bool operator[](const int n) { return flags[n]; }
const bool operator[](const int n) const { return flags[n]; }
const int size() const { return sizeof(flags); }
} axis_flags_t;

//
// Enumerated axis indices
//
Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/feature/fancheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 && DISABLED(FOURWIRES_FANS)
bool FanCheck::measuring = false;
#endif
bool FanCheck::tacho_state[TACHO_COUNT];
Flags<TACHO_COUNT> FanCheck::tacho_state;
uint16_t FanCheck::edge_counter[TACHO_COUNT];
uint8_t FanCheck::rps[TACHO_COUNT];
FanCheck::TachoError FanCheck::error = FanCheck::TachoError::NONE;
Expand Down Expand Up @@ -103,7 +103,7 @@ void FanCheck::update_tachometers() {

if (status != tacho_state[f]) {
if (measuring) ++edge_counter[f];
tacho_state[f] = status;
tacho_state.set(f, status);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/feature/fancheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class FanCheck {
#else
static constexpr bool measuring = true;
#endif
static bool tacho_state[TACHO_COUNT];
static Flags<TACHO_COUNT> tacho_state;
static uint16_t edge_counter[TACHO_COUNT];
static uint8_t rps[TACHO_COUNT];
static TachoError error;
Expand Down
12 changes: 6 additions & 6 deletions Marlin/src/feature/fwretract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ FWRetract fwretract; // Single instance - this calls the constructor
// private:

#if HAS_MULTI_EXTRUDER
bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
Flags<EXTRUDERS> FWRetract::retracted_swap; // Which extruders are swap-retracted
#endif

// public:
Expand All @@ -56,7 +56,7 @@ fwretract_settings_t FWRetract::settings; // M207 S F Z W, M208 S F
bool FWRetract::autoretract_enabled; // M209 S - Autoretract switch
#endif

bool FWRetract::retracted[EXTRUDERS]; // Which extruders are currently retracted
Flags<EXTRUDERS> FWRetract::retracted; // Which extruders are currently retracted

float FWRetract::current_retract[EXTRUDERS], // Retract value used by planner
FWRetract::current_hop;
Expand All @@ -73,9 +73,9 @@ void FWRetract::reset() {
settings.swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
current_hop = 0.0;

retracted.reset();
EXTRUDER_LOOP() {
retracted[e] = false;
E_TERN_(retracted_swap[e] = false);
E_TERN_(retracted_swap.clear(e));
current_retract[e] = 0.0;
}
}
Expand Down Expand Up @@ -173,11 +173,11 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))

TERN_(RETRACT_SYNC_MIXING, mixer.T(old_mixing_tool)); // Restore original mixing tool

retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
retracted.set(active_extruder, retracting); // Active extruder now retracted / recovered

// If swap retract/recover update the retracted_swap flag too
#if HAS_MULTI_EXTRUDER
if (swapping) retracted_swap[active_extruder] = retracting;
if (swapping) retracted_swap.set(active_extruder, retracting);
#endif

/* // debugging
Expand Down
8 changes: 3 additions & 5 deletions Marlin/src/feature/fwretract.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef struct {
class FWRetract {
private:
#if HAS_MULTI_EXTRUDER
static bool retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
static Flags<EXTRUDERS> retracted_swap; // Which extruders are swap-retracted
#endif

public:
Expand All @@ -55,17 +55,15 @@ class FWRetract {
static constexpr bool autoretract_enabled = false;
#endif

static bool retracted[EXTRUDERS]; // Which extruders are currently retracted
static Flags<EXTRUDERS> retracted; // Which extruders are currently retracted
static float current_retract[EXTRUDERS], // Retract value used by planner
current_hop; // Hop value used by planner

FWRetract() { reset(); }

static void reset();

static void refresh_autoretract() {
EXTRUDER_LOOP() retracted[e] = false;
}
static void refresh_autoretract() { retracted.reset(); }

static void enable_autoretract(const bool enable) {
#if ENABLED(FWRETRACT_AUTORETRACT)
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/feature/powerloss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ void PrintJobRecovery::resume() {
EXTRUDER_LOOP() {
if (info.retract[e] != 0.0) {
fwretract.current_retract[e] = info.retract[e];
fwretract.retracted[e] = true;
fwretract.retracted.set(e);
}
}
fwretract.current_hop = info.retract_hop;
Expand Down
8 changes: 4 additions & 4 deletions Marlin/src/gcode/control/M17_M18_M84.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
#include "../../core/debug_out.h"
#include "../../libs/hex_print.h"

inline axis_flags_t selected_axis_bits() {
axis_flags_t selected{0};
inline stepper_flags_t selected_axis_bits() {
stepper_flags_t selected{0};
#if HAS_EXTRUDERS
if (parser.seen('E')) {
if (E_TERN0(parser.has_value())) {
Expand All @@ -58,7 +58,7 @@ inline axis_flags_t selected_axis_bits() {
}

// Enable specified axes and warn about other affected axes
void do_enable(const axis_flags_t to_enable) {
void do_enable(const stepper_flags_t to_enable) {
const ena_mask_t was_enabled = stepper.axis_enabled.bits,
shall_enable = to_enable.bits & ~was_enabled;

Expand Down Expand Up @@ -141,7 +141,7 @@ void GcodeSuite::M17() {
}
}

void try_to_disable(const axis_flags_t to_disable) {
void try_to_disable(const stepper_flags_t to_disable) {
ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;

DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled));
Expand Down
9 changes: 6 additions & 3 deletions Marlin/src/lcd/menu/menu_tramming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#include "../../core/debug_out.h"

static float z_measured[G35_PROBE_COUNT];
static bool z_isvalid[G35_PROBE_COUNT];
static Flags<G35_PROBE_COUNT> z_isvalid;
static uint8_t tram_index = 0;
static int8_t reference_index; // = 0

Expand All @@ -61,7 +61,10 @@ static bool probe_single_point() {
move_to_tramming_wait_pos();

DEBUG_ECHOLNPGM("probe_single_point(", tram_index, ") = ", z_probed_height, "mm");
return (z_isvalid[tram_index] = !isnan(z_probed_height));

const bool v = !isnan(z_probed_height);
z_isvalid.set(tram_index, v);
return v;
}

static void _menu_single_probe() {
Expand Down Expand Up @@ -95,7 +98,7 @@ void goto_tramming_wizard() {
ui.defer_status_screen();

// Initialize measured point flags
ZERO(z_isvalid);
z_isvalid.reset();
reference_index = -1;

// Inject G28, wait for homing to complete,
Expand Down
35 changes: 18 additions & 17 deletions Marlin/src/module/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,12 @@
#endif

#define _EN_ITEM(N) , E##N
#define _EN1_ITEM(N) , E##N:1

typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_hybrid_threshold_t;
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
typedef struct { bool LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stealth_enabled_t;
typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t;
typedef struct { bool LINEAR_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1), X2:1, Y2:1, Z2:1, Z3:1, Z4:1 REPEAT(E_STEPPERS, _EN1_ITEM); } per_stepper_bool_t;

#undef _EN_ITEM

Expand Down Expand Up @@ -430,10 +431,10 @@ typedef struct SettingsDataStruct {
//
// HAS_TRINAMIC_CONFIG
//
tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z...
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z...
tmc_sgt_t tmc_sgt; // M914 X Y Z...
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z...
per_stepper_uint16_t tmc_stepper_current; // M906 X Y Z...
per_stepper_uint32_t tmc_hybrid_threshold; // M913 X Y Z...
mot_stepper_int16_t tmc_sgt; // M914 X Y Z...
per_stepper_bool_t tmc_stealth_enabled; // M569 X Y Z...

//
// LIN_ADVANCE
Expand Down Expand Up @@ -1213,7 +1214,7 @@ void MarlinSettings::postprocess() {
{
_FIELD_TEST(tmc_stepper_current);

tmc_stepper_current_t tmc_stepper_current{0};
per_stepper_uint16_t tmc_stepper_current{0};

#if HAS_TRINAMIC_CONFIG
#if AXIS_IS_TMC(X)
Expand Down Expand Up @@ -1284,7 +1285,7 @@ void MarlinSettings::postprocess() {
_FIELD_TEST(tmc_hybrid_threshold);

#if ENABLED(HYBRID_THRESHOLD)
tmc_hybrid_threshold_t tmc_hybrid_threshold{0};
per_stepper_uint32_t tmc_hybrid_threshold{0};
TERN_(X_HAS_STEALTHCHOP, tmc_hybrid_threshold.X = stepperX.get_pwm_thrs());
TERN_(Y_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y = stepperY.get_pwm_thrs());
TERN_(Z_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z = stepperZ.get_pwm_thrs());
Expand All @@ -1306,7 +1307,7 @@ void MarlinSettings::postprocess() {
TERN_(E7_HAS_STEALTHCHOP, tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs());
#else
#define _EN_ITEM(N) , .E##N = 30
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
const per_stepper_uint32_t tmc_hybrid_threshold = {
LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3),
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
REPEAT(E_STEPPERS, _EN_ITEM)
Expand All @@ -1320,7 +1321,7 @@ void MarlinSettings::postprocess() {
// TMC StallGuard threshold
//
{
tmc_sgt_t tmc_sgt{0};
mot_stepper_int16_t tmc_sgt{0};
#if USE_SENSORLESS
LINEAR_AXIS_CODE(
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
Expand All @@ -1345,7 +1346,7 @@ void MarlinSettings::postprocess() {
{
_FIELD_TEST(tmc_stealth_enabled);

tmc_stealth_enabled_t tmc_stealth_enabled = { false };
per_stepper_bool_t tmc_stealth_enabled = { false };
TERN_(X_HAS_STEALTHCHOP, tmc_stealth_enabled.X = stepperX.get_stored_stealthChop());
TERN_(Y_HAS_STEALTHCHOP, tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop());
TERN_(Z_HAS_STEALTHCHOP, tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop());
Expand Down Expand Up @@ -2135,7 +2136,7 @@ void MarlinSettings::postprocess() {
{
_FIELD_TEST(tmc_stepper_current);

tmc_stepper_current_t currents;
per_stepper_uint16_t currents;
EEPROM_READ(currents);

#if HAS_TRINAMIC_CONFIG
Expand Down Expand Up @@ -2205,7 +2206,7 @@ void MarlinSettings::postprocess() {

// TMC Hybrid Threshold
{
tmc_hybrid_threshold_t tmc_hybrid_threshold;
per_stepper_uint32_t tmc_hybrid_threshold;
_FIELD_TEST(tmc_hybrid_threshold);
EEPROM_READ(tmc_hybrid_threshold);

Expand Down Expand Up @@ -2238,7 +2239,7 @@ void MarlinSettings::postprocess() {
// TMC StallGuard threshold.
//
{
tmc_sgt_t tmc_sgt;
mot_stepper_int16_t tmc_sgt;
_FIELD_TEST(tmc_sgt);
EEPROM_READ(tmc_sgt);
#if USE_SENSORLESS
Expand All @@ -2264,7 +2265,7 @@ void MarlinSettings::postprocess() {
{
_FIELD_TEST(tmc_stealth_enabled);

tmc_stealth_enabled_t tmc_stealth_enabled;
per_stepper_bool_t tmc_stealth_enabled;
EEPROM_READ(tmc_stealth_enabled);

#if HAS_TRINAMIC_CONFIG
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/module/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Stepper stepper; // Singleton
#endif
#endif

axis_flags_t Stepper::axis_enabled; // {0}
stepper_flags_t Stepper::axis_enabled; // {0}

// private:

Expand Down
4 changes: 2 additions & 2 deletions Marlin/src/module/stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ typedef struct {
};
constexpr ena_mask_t linear_bits() { return _BV(LINEAR_AXES) - 1; }
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << LINEAR_AXES; }
} axis_flags_t;
} stepper_flags_t;

// All the stepper enable pins
constexpr pin_t ena_pins[] = {
Expand Down Expand Up @@ -587,7 +587,7 @@ class Stepper {
static void refresh_motor_power();
#endif

static axis_flags_t axis_enabled; // Axis stepper(s) ENABLED states
static stepper_flags_t axis_enabled; // Axis stepper(s) ENABLED states

static bool axis_is_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
return TEST(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));
Expand Down
8 changes: 4 additions & 4 deletions Marlin/src/module/temperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
static hotend_pid_t work_pid[HOTENDS];
static float temp_iState[HOTENDS] = { 0 },
temp_dState[HOTENDS] = { 0 };
static bool pid_reset[HOTENDS] = { false };
static Flags<HOTENDS> pid_reset;
const float pid_error = temp_hotend[ee].target - temp_hotend[ee].celsius;

float pid_output;
Expand All @@ -1102,17 +1102,17 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
|| TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out)
) {
pid_output = 0;
pid_reset[ee] = true;
pid_reset.set(ee);
}
else if (pid_error > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX;
pid_reset[ee] = true;
pid_reset.set(ee);
}
else {
if (pid_reset[ee]) {
temp_iState[ee] = 0.0;
work_pid[ee].Kd = 0.0;
pid_reset[ee] = false;
pid_reset.clear(ee);
}

work_pid[ee].Kd = work_pid[ee].Kd + PID_K2 * (PID_PARAM(Kd, ee) * (temp_dState[ee] - temp_hotend[ee].celsius) - work_pid[ee].Kd);
Expand Down
Loading

0 comments on commit 38443cb

Please sign in to comment.