Skip to content

Commit 2976bb4

Browse files
committed
🔨 Better FT Motion menu string code
1 parent 4f93f31 commit 2976bb4

File tree

1 file changed

+74
-22
lines changed

1 file changed

+74
-22
lines changed

Marlin/src/lcd/menu/menu_motion.cpp

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -401,19 +401,48 @@ void menu_move() {
401401

402402
#endif // HAS_DYNAMIC_FREQ
403403

404+
// Suppress warning about storing a stack address in a static string pointer
405+
#pragma GCC diagnostic push
406+
#pragma GCC diagnostic ignored "-Wdangling-pointer"
407+
408+
#if ALL(__AVR__, HAS_MARLINUI_U8GLIB) && DISABLED(REDUCE_CODE_SIZE_FOR_FT_MOTION_ON_AVR)
409+
#define CACHE_PREV_STRING
410+
#endif
411+
404412
void menu_ft_motion() {
405413
// Define stuff ahead of the menu loop
406-
MString<20> shaper_name[NUM_AXES_SHAPED] {};
407-
#if HAS_X_AXIS
408-
for (uint_fast8_t a = X_AXIS; a < NUM_AXES_SHAPED; ++a)
409-
shaper_name[a] = get_shaper_name(AxisEnum(a));
410-
#endif
411-
#if HAS_DYNAMIC_FREQ
412-
MString<20> dmode = get_dyn_freq_mode_name();
413-
#endif
414-
415414
ft_config_t &c = ftMotion.cfg;
416415

416+
#ifdef __AVR__
417+
// Copy Flash strings to RAM for C-string substitution
418+
// For U8G paged rendering check and skip extra string copy
419+
#if HAS_X_AXIS
420+
MString<20> shaper_name;
421+
TERN_(CACHE_PREV_STRING, int8_t prev_a = -1);
422+
auto _shaper_name = [&](const AxisEnum a) {
423+
if (TERN1(CACHE_PREV_STRING, a != prev_a)) {
424+
TERN_(CACHE_PREV_STRING, prev_a = a);
425+
shaper_name = get_shaper_name(a);
426+
}
427+
return shaper_name;
428+
};
429+
#endif
430+
#if HAS_DYNAMIC_FREQ
431+
MString<20> dmode;
432+
TERN_(CACHE_PREV_STRING, bool got_d = false);
433+
auto _dmode = [&]{
434+
if (TERN1(CACHE_PREV_STRING, !got_d)) {
435+
TERN_(CACHE_PREV_STRING, got_d = true);
436+
dmode = get_dyn_freq_mode_name();
437+
}
438+
return dmode;
439+
};
440+
#endif
441+
#else
442+
auto _shaper_name = [](const AxisEnum a) { return get_shaper_name(a); };
443+
auto _dmode = []{ return get_dyn_freq_mode_name(); };
444+
#endif
445+
417446
START_MENU();
418447
BACK_ITEM(MSG_MOTION);
419448

@@ -426,7 +455,7 @@ void menu_move() {
426455
// Show only when FT Motion is active (or optionally always show)
427456
if (c.active || ENABLED(FT_MOTION_NO_MENU_TOGGLE)) {
428457
#if HAS_X_AXIS
429-
SUBMENU_N_S(X_AXIS, shaper_name[X_AXIS], MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
458+
SUBMENU_N_S(X_AXIS, _shaper_name(X_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
430459

431460
if (AXIS_HAS_SHAPER(X)) {
432461
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq.x, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.update_shaping_params);
@@ -436,7 +465,7 @@ void menu_move() {
436465
}
437466
#endif
438467
#if HAS_Y_AXIS
439-
SUBMENU_N_S(Y_AXIS, shaper_name[Y_AXIS], MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
468+
SUBMENU_N_S(Y_AXIS, _shaper_name(Y_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
440469

441470
if (AXIS_HAS_SHAPER(Y)) {
442471
EDIT_ITEM_FAST_N(float42_52, Y_AXIS, MSG_FTM_BASE_FREQ_N, &c.baseFreq.y, FTM_MIN_SHAPE_FREQ, (FTM_FS) / 2, ftMotion.update_shaping_params);
@@ -447,7 +476,7 @@ void menu_move() {
447476
#endif
448477

449478
#if HAS_DYNAMIC_FREQ
450-
SUBMENU_S(dmode, MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
479+
SUBMENU_S(_dmode(), MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
451480
if (c.dynFreqMode != dynFreqMode_DISABLED) {
452481
#if HAS_X_AXIS
453482
EDIT_ITEM_FAST_N(float42_52, X_AXIS, MSG_FTM_DFREQ_K_N, &c.dynFreqK.x, 0.0f, 20.0f);
@@ -469,13 +498,34 @@ void menu_move() {
469498

470499
void menu_tune_ft_motion() {
471500
// Define stuff ahead of the menu loop
472-
MString<20> shaper_name[NUM_AXES_SHAPED] {};
473-
#if HAS_X_AXIS
474-
for (uint_fast8_t a = X_AXIS; a < NUM_AXES_SHAPED; ++a)
475-
shaper_name[a] = get_shaper_name(AxisEnum(a));
476-
#endif
477-
#if HAS_DYNAMIC_FREQ
478-
MString<20> dmode = get_dyn_freq_mode_name();
501+
#ifdef __AVR__
502+
// Copy Flash strings to RAM for C-string substitution
503+
// For U8G paged rendering check and skip extra string copy
504+
#if HAS_X_AXIS
505+
MString<20> shaper_name;
506+
TERN_(CACHE_PREV_STRING, int8_t prev_a = -1);
507+
auto _shaper_name = [&](const AxisEnum a) {
508+
if (TERN1(CACHE_PREV_STRING, a != prev_a)) {
509+
TERN_(CACHE_PREV_STRING, prev_a = a);
510+
shaper_name = get_shaper_name(a);
511+
}
512+
return shaper_name;
513+
};
514+
#endif
515+
#if HAS_DYNAMIC_FREQ
516+
MString<20> dmode;
517+
TERN_(CACHE_PREV_STRING, bool got_d = false);
518+
auto _dmode = [&]{
519+
if (TERN1(CACHE_PREV_STRING, !got_d)) {
520+
TERN_(CACHE_PREV_STRING, got_d = true);
521+
dmode = get_dyn_freq_mode_name();
522+
}
523+
return dmode;
524+
};
525+
#endif
526+
#else
527+
auto _shaper_name = [](const AxisEnum a) { return get_shaper_name(a); };
528+
auto _dmode = []{ return get_dyn_freq_mode_name(); };
479529
#endif
480530

481531
#if HAS_EXTRUDERS
@@ -486,13 +536,13 @@ void menu_move() {
486536
BACK_ITEM(MSG_TUNE);
487537

488538
#if HAS_X_AXIS
489-
SUBMENU_N_S(X_AXIS, shaper_name[X_AXIS], MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
539+
SUBMENU_N_S(X_AXIS, _shaper_name(X_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_x);
490540
#endif
491541
#if HAS_Y_AXIS
492-
SUBMENU_N_S(Y_AXIS, shaper_name[Y_AXIS], MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
542+
SUBMENU_N_S(Y_AXIS, _shaper_name(Y_AXIS), MSG_FTM_CMPN_MODE, menu_ftm_shaper_y);
493543
#endif
494544
#if HAS_DYNAMIC_FREQ
495-
SUBMENU_S(dmode, MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
545+
SUBMENU_S(_dmode(), MSG_FTM_DYN_MODE, menu_ftm_dyn_mode);
496546
#endif
497547
#if HAS_EXTRUDERS
498548
EDIT_ITEM(bool, MSG_LINEAR_ADVANCE, &c.linearAdvEna);
@@ -503,6 +553,8 @@ void menu_move() {
503553
END_MENU();
504554
}
505555

556+
#pragma GCC diagnostic pop
557+
506558
#endif // FT_MOTION_MENU
507559

508560
void menu_motion() {

0 commit comments

Comments
 (0)