diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp index 3c85b7308..faf4e6f20 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 f324f804a..56ac9216f 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 548706e59..7f72cd523 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 b1d9490ec..9f5f5200e 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; }