diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp
index 3c85b7308c..faf4e6f204 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/Marlin.cpp
@@ -617,9 +617,7 @@ void kill(PGM_P const lcd_msg/*=NULL*/) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
- #if ENABLED(EXTENSIBLE_UI)
- UI::onPrinterKilled(lcd_msg ? lcd_msg : PSTR(MSG_KILLED));
- #elif ENABLED(ULTRA_LCD)
+ #if ENABLED(ULTRA_LCD) || ENABLED(EXTENSIBLE_UI)
kill_screen(lcd_msg ? lcd_msg : PSTR(MSG_KILLED));
#else
UNUSED(lcd_msg);
diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp
index f324f804a4..56ac9216f4 100644
--- a/Marlin/src/lcd/extensible_ui/ui_api.cpp
+++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp
@@ -1,3 +1,25 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
/**************
* ui_api.cpp *
**************/
@@ -29,6 +51,7 @@
#include "../../module/probe.h"
#include "../../module/temperature.h"
#include "../../libs/duration_t.h"
+#include "../../HAL/shared/Delay.h"
#if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
#include "../../module/tool_change.h"
@@ -64,14 +87,70 @@ inline float clamp(const float value, const float minimum, const float maximum)
return MAX(MIN(value, maximum), minimum);
}
+static bool printer_killed = false;
+
namespace UI {
+ #ifdef __SAM3X8E__
+ /**
+ * Implement a special millis() to allow time measurement
+ * within an ISR (such as when the printer is killed).
+ *
+ * To keep proper time, must be called at least every 1s.
+ */
+ uint32_t safe_millis() {
+ // Not killed? Just call millis()
+ if (!printer_killed) return millis();
+
+ static uint32_t currTimeHI = 0; /* Current time */
+
+ // Machine was killed, reinit SysTick so we are able to compute time without ISRs
+ if (currTimeHI == 0) {
+ // Get the last time the Arduino time computed (from CMSIS) and convert it to SysTick
+ currTimeHI = (uint32_t)((GetTickCount() * (uint64_t)(F_CPU/8000)) >> 24);
+
+ // Reinit the SysTick timer to maximize its period
+ SysTick->LOAD = SysTick_LOAD_RELOAD_Msk; // get the full range for the systick timer
+ SysTick->VAL = 0; // Load the SysTick Counter Value
+ SysTick->CTRL = // MCLK/8 as source
+ // No interrupts
+ SysTick_CTRL_ENABLE_Msk; // Enable SysTick Timer
+ }
+
+ // Check if there was a timer overflow from the last read
+ if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) {
+ // There was. This means (SysTick_LOAD_RELOAD_Msk * 1000 * 8)/F_CPU ms has elapsed
+ currTimeHI++;
+ }
+
+ // Calculate current time in milliseconds
+ uint32_t currTimeLO = SysTick_LOAD_RELOAD_Msk - SysTick->VAL; // (in MCLK/8)
+ uint64_t currTime = ((uint64_t)currTimeLO) | (((uint64_t)currTimeHI) << 24);
+
+ // The ms count is
+ return (uint32_t)(currTime / (F_CPU / 8000));
+ }
+
+ #else
+
+ // TODO: Implement for AVR
+ uint32_t safe_millis() { return millis(); }
+
+ #endif
+
+ void delay_us(unsigned long us) {
+ DELAY_US(us);
+ }
void delay_ms(unsigned long ms) {
- safe_delay(ms);
+ if (printer_killed)
+ DELAY_US(ms * 1000);
+ else
+ safe_delay(ms);
}
void yield() {
- thermalManager.manage_heater();
+ if (!printer_killed)
+ thermalManager.manage_heater();
}
float getActualTemp_celsius(const uint8_t extruder) {
@@ -491,7 +570,7 @@ namespace UI {
}
const char* FileList::filename() {
- return IFSD(card.longFilename && card.longFilename[0]) ? card.longFilename : card.filename, "");
+ return IFSD(card.longFilename && card.longFilename[0] ? card.longFilename : card.filename, "");
}
const char* FileList::shortFilename() {
@@ -603,4 +682,11 @@ void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
UI::onStatusChanged(buff);
}
+void kill_screen(PGM_P msg) {
+ if (!printer_killed) {
+ printer_killed = true;
+ UI::onPrinterKilled(msg);
+ }
+}
+
#endif // EXTENSIBLE_UI
diff --git a/Marlin/src/lcd/extensible_ui/ui_api.h b/Marlin/src/lcd/extensible_ui/ui_api.h
index 548706e594..7f72cd523f 100644
--- a/Marlin/src/lcd/extensible_ui/ui_api.h
+++ b/Marlin/src/lcd/extensible_ui/ui_api.h
@@ -1,3 +1,25 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
/************
* ui_api.h *
************/
@@ -127,6 +149,9 @@ namespace UI {
#endif
#endif
+ // This safe_millis is safe to use even when printer is killed (as long as called at least every 1 second)
+ uint32_t safe_millis();
+ void delay_us(unsigned long us);
void delay_ms(unsigned long ms);
void yield(); // Within lengthy loop, call this periodically
diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h
index b1d9490ecf..9f5f5200ee 100644
--- a/Marlin/src/lcd/ultralcd.h
+++ b/Marlin/src/lcd/ultralcd.h
@@ -30,6 +30,7 @@
bool lcd_detected();
void lcd_update();
void lcd_setalertstatusPGM(PGM_P message);
+ void kill_screen(PGM_P lcd_msg);
#else
inline void lcd_init() {}
inline bool lcd_detected() { return true; }