Skip to content

Commit 7d22a7c

Browse files
thinkyheadLCh-77
authored andcommitted
πŸ§‘β€πŸ’» General and Axis-based bitfield flags (MarlinFirmware#23989)
1 parent bd4cc3a commit 7d22a7c

14 files changed

+106
-51
lines changed

β€ŽMarlin/src/core/types.h

+53
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,59 @@ struct IF<true, L, R> { typedef L type; };
7676

7777
#define AXIS_COLLISION(L) (AXIS4_NAME == L || AXIS5_NAME == L || AXIS6_NAME == L || AXIS7_NAME == L || AXIS8_NAME == L || AXIS9_NAME == L)
7878

79+
// General Flags for some number of states
80+
template<size_t N>
81+
struct Flags {
82+
typedef typename IF<(N>8), uint16_t, uint8_t>::type bits_t;
83+
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8;
84+
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;
85+
union {
86+
bits_t b;
87+
typename IF<(N>8), N16, N8>::type flag;
88+
};
89+
void reset() { b = 0; }
90+
void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); }
91+
void set(const int n) { b |= (bits_t)_BV(n); }
92+
void clear(const int n) { b &= ~(bits_t)_BV(n); }
93+
bool test(const int n) const { return TEST(b, n); }
94+
bool operator[](const int n) { return test(n); }
95+
const bool operator[](const int n) const { return test(n); }
96+
const int size() const { return sizeof(b); }
97+
};
98+
99+
// Specialization for a single bool flag
100+
template<>
101+
struct Flags<1> {
102+
bool b;
103+
void reset() { b = false; }
104+
void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); }
105+
void set(const int) { b = true; }
106+
void clear(const int) { b = false; }
107+
bool test(const int) const { return b; }
108+
bool operator[](const int) { return b; }
109+
const bool operator[](const int) const { return b; }
110+
const int size() const { return sizeof(b); }
111+
};
112+
113+
typedef Flags<8> flags_8_t;
114+
typedef Flags<16> flags_16_t;
115+
116+
// Flags for some axis states, with per-axis aliases xyzijkuvwe
117+
typedef struct AxisFlags {
118+
union {
119+
struct Flags<LOGICAL_AXES> flags;
120+
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); };
121+
};
122+
void reset() { flags.reset(); }
123+
void set(const int n) { flags.set(n); }
124+
void set(const int n, const bool onoff) { flags.set(n, onoff); }
125+
void clear(const int n) { flags.clear(n); }
126+
bool test(const int n) const { return flags.test(n); }
127+
bool operator[](const int n) { return flags[n]; }
128+
const bool operator[](const int n) const { return flags[n]; }
129+
const int size() const { return sizeof(flags); }
130+
} axis_flags_t;
131+
79132
//
80133
// Enumerated axis indices
81134
//

β€ŽMarlin/src/feature/fancheck.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#if HAS_AUTO_FAN && EXTRUDER_AUTO_FAN_SPEED != 255 && DISABLED(FOURWIRES_FANS)
3535
bool FanCheck::measuring = false;
3636
#endif
37-
bool FanCheck::tacho_state[TACHO_COUNT];
37+
Flags<TACHO_COUNT> FanCheck::tacho_state;
3838
uint16_t FanCheck::edge_counter[TACHO_COUNT];
3939
uint8_t FanCheck::rps[TACHO_COUNT];
4040
FanCheck::TachoError FanCheck::error = FanCheck::TachoError::NONE;
@@ -103,7 +103,7 @@ void FanCheck::update_tachometers() {
103103

104104
if (status != tacho_state[f]) {
105105
if (measuring) ++edge_counter[f];
106-
tacho_state[f] = status;
106+
tacho_state.set(f, status);
107107
}
108108
}
109109
}

β€ŽMarlin/src/feature/fancheck.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class FanCheck {
5151
#else
5252
static constexpr bool measuring = true;
5353
#endif
54-
static bool tacho_state[TACHO_COUNT];
54+
static Flags<TACHO_COUNT> tacho_state;
5555
static uint16_t edge_counter[TACHO_COUNT];
5656
static uint8_t rps[TACHO_COUNT];
5757
static TachoError error;

β€ŽMarlin/src/feature/fwretract.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ FWRetract fwretract; // Single instance - this calls the constructor
4545
// private:
4646

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

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

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

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

76+
retracted.reset();
7677
EXTRUDER_LOOP() {
77-
retracted[e] = false;
78-
E_TERN_(retracted_swap[e] = false);
78+
E_TERN_(retracted_swap.clear(e));
7979
current_retract[e] = 0.0;
8080
}
8181
}
@@ -173,11 +173,11 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
173173

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

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

178178
// If swap retract/recover update the retracted_swap flag too
179179
#if HAS_MULTI_EXTRUDER
180-
if (swapping) retracted_swap[active_extruder] = retracting;
180+
if (swapping) retracted_swap.set(active_extruder, retracting);
181181
#endif
182182

183183
/* // debugging

β€ŽMarlin/src/feature/fwretract.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef struct {
4343
class FWRetract {
4444
private:
4545
#if HAS_MULTI_EXTRUDER
46-
static bool retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
46+
static Flags<EXTRUDERS> retracted_swap; // Which extruders are swap-retracted
4747
#endif
4848

4949
public:
@@ -55,17 +55,15 @@ class FWRetract {
5555
static constexpr bool autoretract_enabled = false;
5656
#endif
5757

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

6262
FWRetract() { reset(); }
6363

6464
static void reset();
6565

66-
static void refresh_autoretract() {
67-
EXTRUDER_LOOP() retracted[e] = false;
68-
}
66+
static void refresh_autoretract() { retracted.reset(); }
6967

7068
static void enable_autoretract(const bool enable) {
7169
#if ENABLED(FWRETRACT_AUTORETRACT)

β€ŽMarlin/src/feature/powerloss.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ void PrintJobRecovery::resume() {
514514
EXTRUDER_LOOP() {
515515
if (info.retract[e] != 0.0) {
516516
fwretract.current_retract[e] = info.retract[e];
517-
fwretract.retracted[e] = true;
517+
fwretract.retracted.set(e);
518518
}
519519
}
520520
fwretract.current_hop = info.retract_hop;

β€ŽMarlin/src/gcode/control/M17_M18_M84.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
#include "../../core/debug_out.h"
3434
#include "../../libs/hex_print.h"
3535

36-
inline axis_flags_t selected_axis_bits() {
37-
axis_flags_t selected{0};
36+
inline stepper_flags_t selected_axis_bits() {
37+
stepper_flags_t selected{0};
3838
#if HAS_EXTRUDERS
3939
if (parser.seen('E')) {
4040
if (E_TERN0(parser.has_value())) {
@@ -61,7 +61,7 @@ inline axis_flags_t selected_axis_bits() {
6161
}
6262

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

@@ -147,7 +147,7 @@ void GcodeSuite::M17() {
147147
}
148148
}
149149

150-
void try_to_disable(const axis_flags_t to_disable) {
150+
void try_to_disable(const stepper_flags_t to_disable) {
151151
ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;
152152

153153
DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled));

β€ŽMarlin/src/lcd/menu/menu_tramming.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
#include "../../core/debug_out.h"
4545

4646
static float z_measured[G35_PROBE_COUNT];
47-
static bool z_isvalid[G35_PROBE_COUNT];
47+
static Flags<G35_PROBE_COUNT> z_isvalid;
4848
static uint8_t tram_index = 0;
4949
static int8_t reference_index; // = 0
5050

@@ -61,7 +61,10 @@ static bool probe_single_point() {
6161
move_to_tramming_wait_pos();
6262

6363
DEBUG_ECHOLNPGM("probe_single_point(", tram_index, ") = ", z_probed_height, "mm");
64-
return (z_isvalid[tram_index] = !isnan(z_probed_height));
64+
65+
const bool v = !isnan(z_probed_height);
66+
z_isvalid.set(tram_index, v);
67+
return v;
6568
}
6669

6770
static void _menu_single_probe() {
@@ -95,7 +98,7 @@ void goto_tramming_wizard() {
9598
ui.defer_status_screen();
9699

97100
// Initialize measured point flags
98-
ZERO(z_isvalid);
101+
z_isvalid.reset();
99102
reference_index = -1;
100103

101104
// Inject G28, wait for homing to complete,

β€ŽMarlin/src/module/settings.cpp

+18-17
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,12 @@
178178
#endif
179179

180180
#define _EN_ITEM(N) , E##N
181+
#define _EN1_ITEM(N) , E##N:1
181182

182-
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;
183-
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;
184-
typedef struct { int16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
185-
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;
183+
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;
184+
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;
185+
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;
186+
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;
186187

187188
#undef _EN_ITEM
188189

@@ -430,10 +431,10 @@ typedef struct SettingsDataStruct {
430431
//
431432
// HAS_TRINAMIC_CONFIG
432433
//
433-
tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
434-
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
435-
tmc_sgt_t tmc_sgt; // M914 X Y Z X2 Y2 Z2 Z3 Z4
436-
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
434+
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
435+
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
436+
mot_stepper_int16_t tmc_sgt; // M914 X Y Z I J K U V W X2 Y2 Z2 Z3 Z4
437+
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
437438

438439
//
439440
// LIN_ADVANCE
@@ -1220,7 +1221,7 @@ void MarlinSettings::postprocess() {
12201221
{
12211222
_FIELD_TEST(tmc_stepper_current);
12221223

1223-
tmc_stepper_current_t tmc_stepper_current{0};
1224+
per_stepper_uint16_t tmc_stepper_current{0};
12241225

12251226
#if HAS_TRINAMIC_CONFIG
12261227
#if AXIS_IS_TMC(X)
@@ -1300,7 +1301,7 @@ void MarlinSettings::postprocess() {
13001301
_FIELD_TEST(tmc_hybrid_threshold);
13011302

13021303
#if ENABLED(HYBRID_THRESHOLD)
1303-
tmc_hybrid_threshold_t tmc_hybrid_threshold{0};
1304+
per_stepper_uint32_t tmc_hybrid_threshold{0};
13041305
TERN_(X_HAS_STEALTHCHOP, tmc_hybrid_threshold.X = stepperX.get_pwm_thrs());
13051306
TERN_(Y_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y = stepperY.get_pwm_thrs());
13061307
TERN_(Z_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z = stepperZ.get_pwm_thrs());
@@ -1325,7 +1326,7 @@ void MarlinSettings::postprocess() {
13251326
TERN_(E7_HAS_STEALTHCHOP, tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs());
13261327
#else
13271328
#define _EN_ITEM(N) , .E##N = 30
1328-
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
1329+
const per_stepper_uint32_t tmc_hybrid_threshold = {
13291330
NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3),
13301331
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
13311332
REPEAT(E_STEPPERS, _EN_ITEM)
@@ -1339,7 +1340,7 @@ void MarlinSettings::postprocess() {
13391340
// TMC StallGuard threshold
13401341
//
13411342
{
1342-
tmc_sgt_t tmc_sgt{0};
1343+
mot_stepper_int16_t tmc_sgt{0};
13431344
#if USE_SENSORLESS
13441345
NUM_AXIS_CODE(
13451346
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
@@ -1367,7 +1368,7 @@ void MarlinSettings::postprocess() {
13671368
{
13681369
_FIELD_TEST(tmc_stealth_enabled);
13691370

1370-
tmc_stealth_enabled_t tmc_stealth_enabled = { false };
1371+
per_stepper_bool_t tmc_stealth_enabled = { false };
13711372
TERN_(X_HAS_STEALTHCHOP, tmc_stealth_enabled.X = stepperX.get_stored_stealthChop());
13721373
TERN_(Y_HAS_STEALTHCHOP, tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop());
13731374
TERN_(Z_HAS_STEALTHCHOP, tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop());
@@ -2168,7 +2169,7 @@ void MarlinSettings::postprocess() {
21682169
{
21692170
_FIELD_TEST(tmc_stepper_current);
21702171

2171-
tmc_stepper_current_t currents;
2172+
per_stepper_uint16_t currents;
21722173
EEPROM_READ(currents);
21732174

21742175
#if HAS_TRINAMIC_CONFIG
@@ -2247,7 +2248,7 @@ void MarlinSettings::postprocess() {
22472248

22482249
// TMC Hybrid Threshold
22492250
{
2250-
tmc_hybrid_threshold_t tmc_hybrid_threshold;
2251+
per_stepper_uint32_t tmc_hybrid_threshold;
22512252
_FIELD_TEST(tmc_hybrid_threshold);
22522253
EEPROM_READ(tmc_hybrid_threshold);
22532254

@@ -2283,7 +2284,7 @@ void MarlinSettings::postprocess() {
22832284
// TMC StallGuard threshold.
22842285
//
22852286
{
2286-
tmc_sgt_t tmc_sgt;
2287+
mot_stepper_int16_t tmc_sgt;
22872288
_FIELD_TEST(tmc_sgt);
22882289
EEPROM_READ(tmc_sgt);
22892290
#if USE_SENSORLESS
@@ -2312,7 +2313,7 @@ void MarlinSettings::postprocess() {
23122313
{
23132314
_FIELD_TEST(tmc_stealth_enabled);
23142315

2315-
tmc_stealth_enabled_t tmc_stealth_enabled;
2316+
per_stepper_bool_t tmc_stealth_enabled;
23162317
EEPROM_READ(tmc_stealth_enabled);
23172318

23182319
#if HAS_TRINAMIC_CONFIG

β€ŽMarlin/src/module/stepper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Stepper stepper; // Singleton
153153
#endif
154154
#endif
155155

156-
axis_flags_t Stepper::axis_enabled; // {0}
156+
stepper_flags_t Stepper::axis_enabled; // {0}
157157

158158
// private:
159159

β€ŽMarlin/src/module/stepper.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ typedef struct {
261261
};
262262
constexpr ena_mask_t linear_bits() { return _BV(NUM_AXES) - 1; }
263263
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << NUM_AXES; }
264-
} axis_flags_t;
264+
} stepper_flags_t;
265265

266266
// All the stepper enable pins
267267
constexpr pin_t ena_pins[] = {
@@ -596,7 +596,7 @@ class Stepper {
596596
static void refresh_motor_power();
597597
#endif
598598

599-
static axis_flags_t axis_enabled; // Axis stepper(s) ENABLED states
599+
static stepper_flags_t axis_enabled; // Axis stepper(s) ENABLED states
600600

601601
static bool axis_is_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
602602
return TEST(axis_enabled.bits, INDEX_OF_AXIS(axis, eindex));

β€ŽMarlin/src/module/temperature.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
12831283
static hotend_pid_t work_pid[HOTENDS];
12841284
static float temp_iState[HOTENDS] = { 0 },
12851285
temp_dState[HOTENDS] = { 0 };
1286-
static bool pid_reset[HOTENDS] = { false };
1286+
static Flags<HOTENDS> pid_reset;
12871287
const float pid_error = temp_hotend[ee].target - temp_hotend[ee].celsius;
12881288

12891289
float pid_output;
@@ -1293,17 +1293,17 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
12931293
|| TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out)
12941294
) {
12951295
pid_output = 0;
1296-
pid_reset[ee] = true;
1296+
pid_reset.set(ee);
12971297
}
12981298
else if (pid_error > PID_FUNCTIONAL_RANGE) {
12991299
pid_output = PID_MAX;
1300-
pid_reset[ee] = true;
1300+
pid_reset.set(ee);
13011301
}
13021302
else {
13031303
if (pid_reset[ee]) {
13041304
temp_iState[ee] = 0.0;
13051305
work_pid[ee].Kd = 0.0;
1306-
pid_reset[ee] = false;
1306+
pid_reset.clear(ee);
13071307
}
13081308

13091309
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);

0 commit comments

Comments
Β (0)