Skip to content

Commit a41e60f

Browse files
thinkyheadtomek2k1
authored andcommitted
πŸ§‘β€πŸ’» General and Axis-based bitfield flags (MarlinFirmware#23989)
1 parent d8ceac7 commit a41e60f

14 files changed

+106
-51
lines changed

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

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

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

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

β€Ž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
@@ -519,7 +519,7 @@ void PrintJobRecovery::resume() {
519519
EXTRUDER_LOOP() {
520520
if (info.retract[e] != 0.0) {
521521
fwretract.current_retract[e] = info.retract[e];
522-
fwretract.retracted[e] = true;
522+
fwretract.retracted.set(e);
523523
}
524524
}
525525
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())) {
@@ -58,7 +58,7 @@ inline axis_flags_t selected_axis_bits() {
5858
}
5959

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

@@ -141,7 +141,7 @@ void GcodeSuite::M17() {
141141
}
142142
}
143143

144-
void try_to_disable(const axis_flags_t to_disable) {
144+
void try_to_disable(const stepper_flags_t to_disable) {
145145
ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;
146146

147147
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 LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } tmc_stepper_current_t;
183-
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;
184-
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
185-
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;
183+
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;
184+
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;
185+
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t;
186+
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;
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...
434-
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z...
435-
tmc_sgt_t tmc_sgt; // M914 X Y Z...
436-
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z...
434+
per_stepper_uint16_t tmc_stepper_current; // M906 X Y Z...
435+
per_stepper_uint32_t tmc_hybrid_threshold; // M913 X Y Z...
436+
mot_stepper_int16_t tmc_sgt; // M914 X Y Z...
437+
per_stepper_bool_t tmc_stealth_enabled; // M569 X Y Z...
437438

438439
//
439440
// LIN_ADVANCE
@@ -1213,7 +1214,7 @@ void MarlinSettings::postprocess() {
12131214
{
12141215
_FIELD_TEST(tmc_stepper_current);
12151216

1216-
tmc_stepper_current_t tmc_stepper_current{0};
1217+
per_stepper_uint16_t tmc_stepper_current{0};
12171218

12181219
#if HAS_TRINAMIC_CONFIG
12191220
#if AXIS_IS_TMC(X)
@@ -1284,7 +1285,7 @@ void MarlinSettings::postprocess() {
12841285
_FIELD_TEST(tmc_hybrid_threshold);
12851286

12861287
#if ENABLED(HYBRID_THRESHOLD)
1287-
tmc_hybrid_threshold_t tmc_hybrid_threshold{0};
1288+
per_stepper_uint32_t tmc_hybrid_threshold{0};
12881289
TERN_(X_HAS_STEALTHCHOP, tmc_hybrid_threshold.X = stepperX.get_pwm_thrs());
12891290
TERN_(Y_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y = stepperY.get_pwm_thrs());
12901291
TERN_(Z_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z = stepperZ.get_pwm_thrs());
@@ -1306,7 +1307,7 @@ void MarlinSettings::postprocess() {
13061307
TERN_(E7_HAS_STEALTHCHOP, tmc_hybrid_threshold.E7 = stepperE7.get_pwm_thrs());
13071308
#else
13081309
#define _EN_ITEM(N) , .E##N = 30
1309-
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
1310+
const per_stepper_uint32_t tmc_hybrid_threshold = {
13101311
LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3),
13111312
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
13121313
REPEAT(E_STEPPERS, _EN_ITEM)
@@ -1320,7 +1321,7 @@ void MarlinSettings::postprocess() {
13201321
// TMC StallGuard threshold
13211322
//
13221323
{
1323-
tmc_sgt_t tmc_sgt{0};
1324+
mot_stepper_int16_t tmc_sgt{0};
13241325
#if USE_SENSORLESS
13251326
LINEAR_AXIS_CODE(
13261327
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
@@ -1345,7 +1346,7 @@ void MarlinSettings::postprocess() {
13451346
{
13461347
_FIELD_TEST(tmc_stealth_enabled);
13471348

1348-
tmc_stealth_enabled_t tmc_stealth_enabled = { false };
1349+
per_stepper_bool_t tmc_stealth_enabled = { false };
13491350
TERN_(X_HAS_STEALTHCHOP, tmc_stealth_enabled.X = stepperX.get_stored_stealthChop());
13501351
TERN_(Y_HAS_STEALTHCHOP, tmc_stealth_enabled.Y = stepperY.get_stored_stealthChop());
13511352
TERN_(Z_HAS_STEALTHCHOP, tmc_stealth_enabled.Z = stepperZ.get_stored_stealthChop());
@@ -2135,7 +2136,7 @@ void MarlinSettings::postprocess() {
21352136
{
21362137
_FIELD_TEST(tmc_stepper_current);
21372138

2138-
tmc_stepper_current_t currents;
2139+
per_stepper_uint16_t currents;
21392140
EEPROM_READ(currents);
21402141

21412142
#if HAS_TRINAMIC_CONFIG
@@ -2205,7 +2206,7 @@ void MarlinSettings::postprocess() {
22052206

22062207
// TMC Hybrid Threshold
22072208
{
2208-
tmc_hybrid_threshold_t tmc_hybrid_threshold;
2209+
per_stepper_uint32_t tmc_hybrid_threshold;
22092210
_FIELD_TEST(tmc_hybrid_threshold);
22102211
EEPROM_READ(tmc_hybrid_threshold);
22112212

@@ -2238,7 +2239,7 @@ void MarlinSettings::postprocess() {
22382239
// TMC StallGuard threshold.
22392240
//
22402241
{
2241-
tmc_sgt_t tmc_sgt;
2242+
mot_stepper_int16_t tmc_sgt;
22422243
_FIELD_TEST(tmc_sgt);
22432244
EEPROM_READ(tmc_sgt);
22442245
#if USE_SENSORLESS
@@ -2264,7 +2265,7 @@ void MarlinSettings::postprocess() {
22642265
{
22652266
_FIELD_TEST(tmc_stealth_enabled);
22662267

2267-
tmc_stealth_enabled_t tmc_stealth_enabled;
2268+
per_stepper_bool_t tmc_stealth_enabled;
22682269
EEPROM_READ(tmc_stealth_enabled);
22692270

22702271
#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
@@ -252,7 +252,7 @@ typedef struct {
252252
};
253253
constexpr ena_mask_t linear_bits() { return _BV(LINEAR_AXES) - 1; }
254254
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << LINEAR_AXES; }
255-
} axis_flags_t;
255+
} stepper_flags_t;
256256

257257
// All the stepper enable pins
258258
constexpr pin_t ena_pins[] = {
@@ -587,7 +587,7 @@ class Stepper {
587587
static void refresh_motor_power();
588588
#endif
589589

590-
static axis_flags_t axis_enabled; // Axis stepper(s) ENABLED states
590+
static stepper_flags_t axis_enabled; // Axis stepper(s) ENABLED states
591591

592592
static bool axis_is_enabled(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
593593
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
@@ -1092,7 +1092,7 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
10921092
static hotend_pid_t work_pid[HOTENDS];
10931093
static float temp_iState[HOTENDS] = { 0 },
10941094
temp_dState[HOTENDS] = { 0 };
1095-
static bool pid_reset[HOTENDS] = { false };
1095+
static Flags<HOTENDS> pid_reset;
10961096
const float pid_error = temp_hotend[ee].target - temp_hotend[ee].celsius;
10971097

10981098
float pid_output;
@@ -1102,17 +1102,17 @@ void Temperature::min_temp_error(const heater_id_t heater_id) {
11021102
|| TERN0(HEATER_IDLE_HANDLER, heater_idle[ee].timed_out)
11031103
) {
11041104
pid_output = 0;
1105-
pid_reset[ee] = true;
1105+
pid_reset.set(ee);
11061106
}
11071107
else if (pid_error > PID_FUNCTIONAL_RANGE) {
11081108
pid_output = BANG_MAX;
1109-
pid_reset[ee] = true;
1109+
pid_reset.set(ee);
11101110
}
11111111
else {
11121112
if (pid_reset[ee]) {
11131113
temp_iState[ee] = 0.0;
11141114
work_pid[ee].Kd = 0.0;
1115-
pid_reset[ee] = false;
1115+
pid_reset.clear(ee);
11161116
}
11171117

11181118
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)