Merge remote-tracking branch 'upstream/MK25' into MK25

This commit is contained in:
Robert Pelnar 2018-03-27 15:46:22 +02:00
commit bd0eebcfbb
11 changed files with 296 additions and 92 deletions

View File

@ -7,12 +7,12 @@
#define STR(x) STR_HELPER(x)
// Firmware version
#define FW_VERSION "3.1.2-alpha"
#define FW_COMMIT_NR 255
#define FW_VERSION "3.1.3"
#define FW_COMMIT_NR 309
// FW_VERSION_UNKNOWN means this is an unofficial build.
// The firmware should only be checked into github with this symbol.
#define FW_DEV_VERSION FW_VERSION_UNKNOWN
#define FW_REPOSITORY "Prusa3D/MK3"
#define FW_REPOSITORY "Unknown"
#define FW_VERSION_FULL FW_VERSION "-" STR(FW_COMMIT_NR)
// Debug version has debugging enabled (the symbol DEBUG_BUILD is set).

View File

@ -54,6 +54,7 @@
#include "pins_arduino.h"
#include "math.h"
#include "util.h"
#include "Timer.h"
#include <avr/wdt.h>
@ -3228,7 +3229,8 @@ void process_commands()
#ifdef PINDA_THERMISTOR
if (true)
{
if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS])) {
if (!(axis_known_position[X_AXIS] && axis_known_position[Y_AXIS] && axis_known_position[Z_AXIS]))
{
// We don't know where we are! HOME!
// Push the commands to the front of the message queue in the reverse order!
// There shall be always enough space reserved for these commands.
@ -3238,7 +3240,14 @@ void process_commands()
}
lcd_show_fullscreen_message_and_wait_P(MSG_TEMP_CAL_WARNING);
bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(MSG_STEEL_SHEET_CHECK, false, false);
if (result) lcd_show_fullscreen_message_and_wait_P(MSG_REMOVE_STEEL_SHEET);
if (result)
{
current_position[Z_AXIS] = 50;
current_position[Y_AXIS] = 190;
plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000 / 60, active_extruder);
st_synchronize();
lcd_show_fullscreen_message_and_wait_P(MSG_REMOVE_STEEL_SHEET);
}
lcd_update_enable(true);
KEEPALIVE_STATE(NOT_BUSY); //no need to print busy messages as we print current temperatures periodicaly
SERIAL_ECHOLNPGM("PINDA probe calibration start");
@ -6720,6 +6729,31 @@ void handle_status_leds(void) {
}
#endif
#ifdef SAFETYTIMER
/**
* @brief Turn off heating after 15 minutes of inactivity
*/
static void handleSafetyTimer()
{
static_assert(EXTRUDERS == 1,"Implemented only for one extruder.");
static Timer safetyTimer;
if (IS_SD_PRINTING || is_usb_printing || (custom_message_type == 4) || (lcd_commands_type == LCD_COMMAND_V2_CAL) ||
(!degTargetBed() && !degTargetHotend(0)))
{
safetyTimer.stop();
}
else if ((degTargetBed() || degTargetHotend(0)) && (!safetyTimer.running()))
{
safetyTimer.start();
}
else if (safetyTimer.expired(15*60*1000))
{
setTargetBed(0);
setTargetHotend(0, 0);
}
}
#endif //SAFETYTIMER
void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
{
#ifdef PAT9125
@ -6763,18 +6797,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument s
#endif //PAT9125
#ifdef SAFETYTIMER
static uint32_t safety_timer = 0;
if (degTargetBed() || degTargetHotend(0))
{
if ((safety_timer == 0) || IS_SD_PRINTING || is_usb_printing || (custom_message_type == 4) || (lcd_commands_type == LCD_COMMAND_V2_CAL))
safety_timer = millis();
else if ((safety_timer + (15*60*1000)) < millis())
{
setTargetBed(0);
setTargetHotend(0, 0);
safety_timer = 0;
}
}
handleSafetyTimer();
#endif //SAFETYTIMER

29
Firmware/MenuStack.cpp Normal file
View File

@ -0,0 +1,29 @@
/**
* @file
* @author Marek Bel
*/
#include "MenuStack.h"
/**
* @brief Push menu on stack
* @param menu
* @param position selected position in menu being pushed
*/
void MenuStack::push(menuFunc_t menu, uint8_t position)
{
if (m_index >= max_depth) return;
m_stack[m_index].menu = menu;
m_stack[m_index].position = position;
++m_index;
}
/**
* @brief Pop menu from stack
* @return Record containing menu function pointer and previously selected line number
*/
MenuStack::Record MenuStack::pop()
{
if (m_index != 0) m_index--;
return m_stack[m_index];
}

34
Firmware/MenuStack.h Normal file
View File

@ -0,0 +1,34 @@
/**
* @file
* @author Marek Bel
*/
#ifndef MENUSTACK_H
#define MENUSTACK_H
#include <stdint.h>
/** Pointer to function implementing menu.*/
typedef void (*menuFunc_t)();
/**
* @brief Stack implementation for navigating menu structure
*/
class MenuStack
{
public:
struct Record
{
menuFunc_t menu;
uint8_t position;
};
MenuStack():m_stack(),m_index(0) {}
void push(menuFunc_t menu, uint8_t position);
Record pop();
void reset(){m_index = 0;}
private:
static const int max_depth = 4;
Record m_stack[max_depth];
uint8_t m_index;
};
#endif /* FIRMWARE_MENUSTACK_H_ */

55
Firmware/Timer.cpp Normal file
View File

@ -0,0 +1,55 @@
/**
* @file
* @author Marek Bel
*/
#include "Timer.h"
#include "Arduino.h"
Timer::Timer() : m_isRunning(false), m_started()
{
}
/**
* @brief Start timer
*/
void Timer::start()
{
m_started = millis();
m_isRunning = true;
}
/**
* @brief Timer has expired
*
* Timer is considered expired after msPeriod has passed from time the timer was started.
* This function must be called at least each (unsigned long maximum value - msPeriod) milliseconds to be sure to
* catch first expiration.
* This function is expected to handle wrap around of time register well.
*
* @param msPeriod Time interval in milliseconds.
* @retval true Timer has expired
* @retval false Timer not expired yet, or is not running, or time window in which is timer considered expired passed.
*/
bool Timer::expired(unsigned long msPeriod)
{
if (!m_isRunning) return false;
bool expired = false;
const unsigned long now = millis();
if (m_started <= m_started + msPeriod)
{
if ((now >= m_started + msPeriod) || (now < m_started))
{
expired = true;
}
}
else
{
if ((now >= m_started + msPeriod) && (now < m_started))
{
expired = true;
}
}
if (expired) m_isRunning = false;
return expired;
}

30
Firmware/Timer.h Normal file
View File

@ -0,0 +1,30 @@
/*
* @file
* @author Marek Bel
*/
#ifndef TIMER_H
#define TIMER_H
/**
* @brief simple timer
*
* Simple and memory saving implementation. Should handle timer register wrap around well.
* Maximum period is at least 49 days. Resolution is one millisecond. To save memory, doesn't store timer period.
* If you wish timer which is storing period, derive from this. If you need time intervals smaller than 65 seconds
* consider implementing timer with smaller underlying type.
*/
class Timer
{
public:
Timer();
void start();
void stop(){m_isRunning = false;}
bool running(){return m_isRunning;}
bool expired(unsigned long msPeriod);
private:
bool m_isRunning;
unsigned long m_started;
};
#endif /* TIMER_H */

View File

@ -61,8 +61,10 @@ const char * const MSG_AUTO_HOME_LANG_TABLE[1] PROGMEM = {
};
const char MSG_AUTO_MODE_ON_EN[] PROGMEM = "Mode [auto power]";
const char * const MSG_AUTO_MODE_ON_LANG_TABLE[1] PROGMEM = {
MSG_AUTO_MODE_ON_EN
const char MSG_AUTO_MODE_ON_CZ[] PROGMEM = "Mod [automaticky]";
const char * const MSG_AUTO_MODE_ON_LANG_TABLE[LANG_NUM] PROGMEM = {
MSG_AUTO_MODE_ON_EN,
MSG_AUTO_MODE_ON_CZ
};
const char MSG_A_RETRACT_EN[] PROGMEM = "A-retract";
@ -1986,14 +1988,14 @@ const char * const MSG_SHOW_END_STOPS_LANG_TABLE[LANG_NUM] PROGMEM = {
};
const char MSG_SILENT_MODE_OFF_EN[] PROGMEM = "Mode [high power]";
const char MSG_SILENT_MODE_OFF_CZ[] PROGMEM = "Mod [Normal]";
const char MSG_SILENT_MODE_OFF_CZ[] PROGMEM = "Mod [vys. vykon]";
const char * const MSG_SILENT_MODE_OFF_LANG_TABLE[LANG_NUM] PROGMEM = {
MSG_SILENT_MODE_OFF_EN,
MSG_SILENT_MODE_OFF_CZ
};
const char MSG_SILENT_MODE_ON_EN[] PROGMEM = "Mode [silent]";
const char MSG_SILENT_MODE_ON_CZ[] PROGMEM = "Mod [Stealth]";
const char MSG_SILENT_MODE_ON_CZ[] PROGMEM = "Mod [tichy]";
const char * const MSG_SILENT_MODE_ON_LANG_TABLE[LANG_NUM] PROGMEM = {
MSG_SILENT_MODE_ON_EN,
MSG_SILENT_MODE_ON_CZ

View File

@ -40,8 +40,8 @@ extern const char* const MSG_AUTOLOAD_FILAMENT_LANG_TABLE[LANG_NUM];
#define MSG_AUTOLOAD_FILAMENT LANG_TABLE_SELECT(MSG_AUTOLOAD_FILAMENT_LANG_TABLE)
extern const char* const MSG_AUTO_HOME_LANG_TABLE[1];
#define MSG_AUTO_HOME LANG_TABLE_SELECT_EXPLICIT(MSG_AUTO_HOME_LANG_TABLE, 0)
extern const char* const MSG_AUTO_MODE_ON_LANG_TABLE[1];
#define MSG_AUTO_MODE_ON LANG_TABLE_SELECT_EXPLICIT(MSG_AUTO_MODE_ON_LANG_TABLE, 0)
extern const char* const MSG_AUTO_MODE_ON_LANG_TABLE[LANG_NUM];
#define MSG_AUTO_MODE_ON LANG_TABLE_SELECT(MSG_AUTO_MODE_ON_LANG_TABLE)
extern const char* const MSG_A_RETRACT_LANG_TABLE[1];
#define MSG_A_RETRACT LANG_TABLE_SELECT_EXPLICIT(MSG_A_RETRACT_LANG_TABLE, 0)
extern const char* const MSG_BABYSTEPPING_X_LANG_TABLE[1];

View File

@ -103,8 +103,9 @@
#define MSG_INSERT_FILAMENT "Vlozte filament"
#define MSG_CHANGING_FILAMENT "Vymena filamentu!"
#define MSG_SILENT_MODE_ON "Mod [Stealth]"
#define MSG_SILENT_MODE_OFF "Mod [Normal]"
#define MSG_SILENT_MODE_ON "Mod [tichy]"
#define MSG_SILENT_MODE_OFF "Mod [vys. vykon]"
#define MSG_AUTO_MODE_ON "Mod [automaticky]"
#define MSG_REBOOT "Restartujte tiskarnu"
#define MSG_TAKE_EFFECT " pro projeveni zmen"

View File

@ -20,7 +20,7 @@ float world2machine_shift[2];
#define WEIGHT_FIRST_ROW_Y_LOW (0.0f)
#define BED_ZERO_REF_X (- 22.f + X_PROBE_OFFSET_FROM_EXTRUDER) // -22 + 23 = 1
#define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER) // -0.6 + 5 = 4.4
#define BED_ZERO_REF_Y (- 0.6f + Y_PROBE_OFFSET_FROM_EXTRUDER + 4) // -0.6 + 5 = 4.4
// Scaling of the real machine axes against the programmed dimensions in the firmware.
// The correction is tiny, here around 0.5mm on 250mm length.
@ -56,10 +56,10 @@ const float bed_skew_angle_extreme = (0.25f * M_PI / 180.f);
// Positions of the bed reference points in the machine coordinates, referenced to the P.I.N.D.A sensor.
// The points are the following: center front, center right, center rear, center left.
const float bed_ref_points_4[] PROGMEM = {
13.f - BED_ZERO_REF_X, 10.4f - 4.f - BED_ZERO_REF_Y,
221.f - BED_ZERO_REF_X, 10.4f - 4.f - BED_ZERO_REF_Y,
221.f - BED_ZERO_REF_X, 202.4f - 4.f - BED_ZERO_REF_Y,
13.f - BED_ZERO_REF_X, 202.4f - 4.f - BED_ZERO_REF_Y
13.f - BED_ZERO_REF_X, 10.4f - BED_ZERO_REF_Y,
221.f - BED_ZERO_REF_X, 10.4f - BED_ZERO_REF_Y,
221.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y,
13.f - BED_ZERO_REF_X, 202.4f - BED_ZERO_REF_Y
};
const float bed_ref_points[] PROGMEM = {

View File

@ -1,6 +1,7 @@
#include "temperature.h"
#include "ultralcd.h"
#ifdef ULTRA_LCD
#include "MenuStack.h"
#include "Marlin.h"
#include "language.h"
#include "cardreader.h"
@ -39,7 +40,7 @@ extern bool fsensor_enabled;
#endif //PAT9125
//Function pointer to menu functions.
typedef void (*menuFunc_t)();
static void lcd_sd_updir();
@ -91,6 +92,18 @@ union MenuData
int rear2;
} adjustBed;
struct TuneMenu
{
// editMenuParentState is used when an edit menu is entered, so it knows
// the return menu and encoder state.
struct EditMenuParentState editMenuParentState;
// To recognize, whether the menu has been just initialized.
int8_t status;
// Backup of extrudemultiply, to recognize, that the value has been changed and
// it needs to be applied.
int16_t extrudemultiply;
} tuneMenu;
// editMenuParentState is used when an edit menu is entered, so it knows
// the return menu and encoder state.
struct EditMenuParentState editMenuParentState;
@ -105,7 +118,7 @@ union Data
byte b[2];
int value;
};
static MenuStack menuStack;
int8_t ReInitLCD = 0;
int8_t SDscrool = 0;
@ -223,7 +236,7 @@ static void lcd_delta_calibrate_menu();
static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
/* Different types of actions that can be used in menu items. */
static void menu_action_back(menuFunc_t data);
static void menu_action_back(menuFunc_t data = 0);
#define menu_action_back_RAM menu_action_back
static void menu_action_submenu(menuFunc_t data);
static void menu_action_gcode(const char* pgcode);
@ -320,14 +333,12 @@ volatile uint8_t slow_buttons;//Contains the bits of the currently pressed butto
uint8_t currentMenuViewOffset; /* scroll offset in the current menu */
uint8_t lastEncoderBits;
uint16_t encoderPosition;
uint16_t savedEncoderPosition;
#if (SDCARDDETECT > 0)
bool lcd_oldcardstatus;
#endif
#endif //ULTIPANEL
menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */
menuFunc_t savedMenu;
uint32_t lcd_next_update_millis;
uint8_t lcd_status_update_delay;
bool ignore_click = false;
@ -339,6 +350,25 @@ uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD nee
// float raw_Ki, raw_Kd;
#endif
/**
* @brief Go to menu
*
* In MENU_ITEM(submenu,... ) use MENU_ITEM(back,...) or
* menu_action_back() and menu_action_submenu() instead, otherwise menuStack will be broken.
*
* It is acceptable to call lcd_goto_menu(menu) directly from MENU_ITEM(function,...), if destination menu
* is the same, from which function was called.
*
* @param menu target menu
* @param encoder position in target menu
* @param feedback
* * true sound feedback (click)
* * false no feedback
* @param reset_menu_state
* * true reset menu state global union
* * false do not reset menu state global union
*/
static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true, bool reset_menu_state = true)
{
asm("cli");
@ -510,8 +540,8 @@ static void lcd_status_screen()
if (current_click && (lcd_commands_type != LCD_COMMAND_STOP_PRINT)) //click is aborted unless stop print finishes
{
lcd_goto_menu(lcd_main_menu);
menuStack.reset(); //redundant, as already done in lcd_return_to_status(), just to be sure
menu_action_submenu(lcd_main_menu);
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
currentMenu == lcd_status_screen
@ -955,7 +985,8 @@ void lcd_commands()
{
lcd_implementation_clear();
lcd_goto_menu(lcd_babystep_z, 0, false);
menuStack.reset();
menu_action_submenu(lcd_babystep_z);
enquecommand_P(PSTR("G1 X60.0 E9.0 F1000.0")); //intro line
enquecommand_P(PSTR("G1 X100.0 E12.5 F1000.0")); //intro line
enquecommand_P(PSTR("G92 E0.0"));
@ -1365,6 +1396,7 @@ static void lcd_return_to_status() {
);
lcd_goto_menu(lcd_status_screen, 0, false);
menuStack.reset();
}
@ -1517,7 +1549,7 @@ static void lcd_menu_extruder_info()
lcd.print(itostr3(pat9125_b));
// Display LASER shutter time from Filament sensor
/* Shutter register is an index of LASER shutter time. It is automatically controlled by the chips internal
/* Shutter register is an index of LASER shutter time. It is automatically controlled by the chip's internal
auto-exposure algorithm. When the chip is tracking on a good reflection surface, the Shutter is small.
When the chip is tracking on a poor reflection surface, the Shutter is large. Value ranges from 0 to
46. */
@ -1617,9 +1649,7 @@ static void lcd_menu_fails_stats()
fprintf_P(lcdout, PSTR(ESC_H(0,0)"Last print failures"ESC_H(1,1)"Filam. runouts %-3d"ESC_H(0,2)"Total failures"ESC_H(1,3)"Filam. runouts %-3d"), filamentLast, filamentTotal);
if (lcd_clicked())
{
lcd_quick_feedback();
//lcd_return_to_status();
lcd_goto_menu(lcd_main_menu, 8); //TODO: Remove hard coded encoder value.
menu_action_back();
}
}
#endif //TMC2130
@ -1802,13 +1832,13 @@ static void lcd_support_menu()
void lcd_set_fan_check() {
fans_check_enabled = !fans_check_enabled;
eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED, fans_check_enabled);
lcd_goto_menu(lcd_settings_menu, 8);
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
void lcd_set_filament_autoload() {
filament_autoload_enabled = !filament_autoload_enabled;
eeprom_update_byte((unsigned char *)EEPROM_FSENS_AUTOLOAD_ENABLED, filament_autoload_enabled);
lcd_goto_menu(lcd_settings_menu, 8);
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
void lcd_unLoadFilament()
@ -2184,7 +2214,7 @@ static void _lcd_move(const char *name, int axis, int min, int max) {
}
}
if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis); {
if (LCD_CLICKED) menu_action_back(); {
}
}
@ -2206,7 +2236,7 @@ static void lcd_move_e()
{
lcd_implementation_drawedit(PSTR("Extruder"), ftostr31(current_position[E_AXIS]));
}
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis);
if (LCD_CLICKED) menu_action_back();
}
else {
lcd_implementation_clear();
@ -2358,7 +2388,7 @@ static void _lcd_babystep(int axis, const char *msg)
(axis == 0) ? EEPROM_BABYSTEP_X : ((axis == 1) ? EEPROM_BABYSTEP_Y : EEPROM_BABYSTEP_Z),
&menuData.babyStep.babystepMem[axis]);
}
if (LCD_CLICKED) lcd_goto_menu(lcd_main_menu);
if (LCD_CLICKED) menu_action_back();
}
static void lcd_babystep_x() {
@ -2373,6 +2403,14 @@ static void lcd_babystep_z() {
static void lcd_adjust_bed();
/**
* @brief adjust bed reset menu item function
*
* To be used as MENU_ITEM(function,...) inside lcd_adjust_bed submenu. In such case lcd_goto_menu usage
* is correct and doesn't break menuStack.
* Because we did not leave the menu, the menuData did not reset.
* Force refresh of the bed leveling data.
*/
static void lcd_adjust_bed_reset()
{
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1);
@ -2380,9 +2418,7 @@ static void lcd_adjust_bed_reset()
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_RIGHT, 0);
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_FRONT, 0);
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_REAR , 0);
lcd_goto_menu(lcd_adjust_bed, 0, false);
// Because we did not leave the menu, the menuData did not reset.
// Force refresh of the bed leveling data.
lcd_goto_menu(lcd_adjust_bed, 0, false); //doesn't break menuStack
menuData.adjustBed.status = 0;
}
@ -3006,7 +3042,7 @@ static void lcd_show_end_stops() {
static void menu_show_end_stops() {
lcd_show_end_stops();
if (LCD_CLICKED) lcd_goto_menu(lcd_calibration_menu);
if (LCD_CLICKED) lcd_goto_menu(lcd_calibration_menu); //doesn't break menuStack
}
// Lets the user move the Z carriage up to the end stoppers.
@ -3394,7 +3430,7 @@ static void lcd_sort_type_set() {
}
eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort);
presort_flag = true;
lcd_goto_menu(lcd_settings_menu, 8);
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
#endif //SDCARD_SORT_ALPHA
@ -3518,8 +3554,8 @@ static void lcd_fsensor_state_set()
lcd_fsensor_fail();
}
}
if (IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) lcd_goto_menu(lcd_tune_menu, 7);
else lcd_goto_menu(lcd_settings_menu, 7);
if (IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) lcd_goto_menu(lcd_tune_menu);
else lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
#endif //PAT9125
@ -3584,16 +3620,18 @@ void lcd_temp_calibration_set() {
temp_cal_active = !temp_cal_active;
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active);
digipot_init();
lcd_goto_menu(lcd_settings_menu, 10);
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
#ifdef HAS_SECOND_SERIAL_PORT
void lcd_second_serial_set() {
if(selectedSerialPort == 1) selectedSerialPort = 0;
else selectedSerialPort = 1;
eeprom_update_byte((unsigned char *)EEPROM_SECOND_SERIAL_ACTIVE, selectedSerialPort);
MYSERIAL.begin(BAUDRATE);
lcd_goto_menu(lcd_settings_menu, 11);
lcd_goto_menu(lcd_settings_menu);//doesn't break menuStack
}
#endif //HAS_SECOND_SERIAL_PORT
void lcd_calibrate_pinda() {
enquecommand_P(PSTR("G76"));
@ -4607,7 +4645,7 @@ static void lcd_disable_farm_mode() {
lcd_return_to_status();
}
else {
lcd_goto_menu(lcd_settings_menu);
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
}
lcd_update_enable(true);
lcdDrawUpdate = 2;
@ -5326,7 +5364,17 @@ static void lcd_colorprint_change() {
static void lcd_tune_menu()
{
EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu));
if (menuData.tuneMenu.status == 0) {
// Menu was entered. Mark the menu as entered and save the current extrudemultiply value.
menuData.tuneMenu.status = 1;
menuData.tuneMenu.extrudemultiply = extrudemultiply;
} else if (menuData.tuneMenu.extrudemultiply != extrudemultiply) {
// extrudemultiply has been changed from the child menu. Apply the new value.
menuData.tuneMenu.extrudemultiply = extrudemultiply;
calculate_extruder_multipliers();
}
EEPROM_read(EEPROM_SILENT, (uint8_t*)&SilentModeMenu, sizeof(SilentModeMenu));
@ -6647,32 +6695,24 @@ static void lcd_quick_feedback()
lcd_implementation_quick_feedback();
}
#define ENC_STACK_SIZE 3
static uint8_t enc_stack[ENC_STACK_SIZE]; //encoder is originaly uint16, but for menu
static uint8_t enc_stack_cnt = 0;
static void lcd_push_encoder(void)
{
if (enc_stack_cnt >= ENC_STACK_SIZE) return;
enc_stack[enc_stack_cnt] = encoderPosition;
enc_stack_cnt++;
}
static void lcd_pop_encoder(void)
{
if (enc_stack_cnt == 0) return;
enc_stack_cnt--;
encoderPosition = enc_stack[enc_stack_cnt];
}
/** Menu action functions **/
static void menu_action_back(menuFunc_t data) {
lcd_goto_menu(data);
lcd_pop_encoder();
/**
* @brief Go up in menu structure
* @param data unused parameter
*/
static void menu_action_back(menuFunc_t data)
{
MenuStack::Record record = menuStack.pop();
lcd_goto_menu(record.menu);
encoderPosition = record.position;
}
/**
* @brief Go deeper into menu structure
* @param data nested menu
*/
static void menu_action_submenu(menuFunc_t data) {
lcd_push_encoder();
menuStack.push(currentMenu, encoderPosition);
lcd_goto_menu(data);
}
static void menu_action_gcode(const char* pgcode) {
@ -7093,10 +7133,6 @@ void lcd_buttons_update()
if (millis() > button_blanking_time) {
button_blanking_time = millis() + BUTTON_BLANKING_TIME;
if (button_pressed == false && long_press_active == false) {
if (currentMenu != lcd_move_z) {
savedMenu = currentMenu;
savedEncoderPosition = encoderPosition;
}
long_press_timer = millis();
button_pressed = true;
}
@ -7105,7 +7141,7 @@ void lcd_buttons_update()
long_press_active = true;
move_menu_scale = 1.0;
lcd_goto_menu(lcd_move_z);
menu_action_submenu(lcd_move_z);
}
}
}
@ -7115,13 +7151,7 @@ void lcd_buttons_update()
button_blanking_time = millis() + BUTTON_BLANKING_TIME;
if (long_press_active == false) { //button released before long press gets activated
if (currentMenu == lcd_move_z) {
//return to previously active menu and previous encoder position
lcd_goto_menu(savedMenu, savedEncoderPosition);
}
else {
newbutton |= EN_C;
}
}
else if (currentMenu == lcd_move_z) lcd_quick_feedback();
//button_pressed is set back to false via lcd_quick_feedback function