Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧑‍💻 General and Axis-based bitfield flags #23989

Merged
merged 2 commits into from
Apr 3, 2022
Merged
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
53 changes: 53 additions & 0 deletions Marlin/src/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,59 @@ struct IF<true, L, R> { typedef L type; };

#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L || AXIS7_NAME == L || AXIS8_NAME == L || AXIS9_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 @@ -514,7 +514,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 @@ -61,7 +61,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 @@ -147,7 +147,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 NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
typedef struct { uint32_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_hybrid_threshold_t;
typedef struct { int16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
typedef struct { bool NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stealth_enabled_t;
typedef struct { uint16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
typedef struct { uint32_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
typedef struct { int16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t;
typedef struct { bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W: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 X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
tmc_sgt_t tmc_sgt; // M914 X Y Z X2 Y2 Z2 Z3 Z4
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
per_stepper_uint16_t tmc_stepper_current; // M906 X Y Z I J K U V W X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
per_stepper_uint32_t tmc_hybrid_threshold; // M913 X Y Z I J K U V W X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
mot_stepper_int16_t tmc_sgt; // M914 X Y Z I J K U V W X2 Y2 Z2 Z3 Z4
per_stepper_bool_t tmc_stealth_enabled; // M569 X Y Z I J K U V W X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5

//
// LIN_ADVANCE
Expand Down Expand Up @@ -1220,7 +1221,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 @@ -1300,7 +1301,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 @@ -1325,7 +1326,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 = {
NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3),
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
REPEAT(E_STEPPERS, _EN_ITEM)
Expand All @@ -1339,7 +1340,7 @@ void MarlinSettings::postprocess() {
// TMC StallGuard threshold
//
{
tmc_sgt_t tmc_sgt{0};
mot_stepper_int16_t tmc_sgt{0};
#if USE_SENSORLESS
NUM_AXIS_CODE(
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
Expand Down Expand Up @@ -1367,7 +1368,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 @@ -2168,7 +2169,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 @@ -2247,7 +2248,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 @@ -2283,7 +2284,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 Down Expand Up @@ -2312,7 +2313,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 @@ -261,7 +261,7 @@ typedef struct {
};
constexpr ena_mask_t linear_bits() { return _BV(NUM_AXES) - 1; }
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << NUM_AXES; }
} axis_flags_t;
} stepper_flags_t;

// All the stepper enable pins
constexpr pin_t ena_pins[] = {
Expand Down Expand Up @@ -596,7 +596,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 @@ -1283,7 +1283,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 @@ -1293,17 +1293,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 = PID_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