Implement custom delay/millis for EXTENSIBLE_UI (#12188)

This commit is contained in:
Marcio Teixeira 2018-10-22 18:37:48 -06:00 committed by Scott Lahteine
parent 3a3ab3391f
commit fc31da1114
4 changed files with 116 additions and 6 deletions

View file

@ -617,9 +617,7 @@ void kill(PGM_P const lcd_msg/*=NULL*/) {
SERIAL_ERROR_START(); SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_ERR_KILLED); SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
#if ENABLED(EXTENSIBLE_UI) #if ENABLED(ULTRA_LCD) || ENABLED(EXTENSIBLE_UI)
UI::onPrinterKilled(lcd_msg ? lcd_msg : PSTR(MSG_KILLED));
#elif ENABLED(ULTRA_LCD)
kill_screen(lcd_msg ? lcd_msg : PSTR(MSG_KILLED)); kill_screen(lcd_msg ? lcd_msg : PSTR(MSG_KILLED));
#else #else
UNUSED(lcd_msg); UNUSED(lcd_msg);

View file

@ -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 <http://www.gnu.org/licenses/>.
*
*/
/************** /**************
* ui_api.cpp * * ui_api.cpp *
**************/ **************/
@ -29,6 +51,7 @@
#include "../../module/probe.h" #include "../../module/probe.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
#include "../../libs/duration_t.h" #include "../../libs/duration_t.h"
#include "../../HAL/shared/Delay.h"
#if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER) #if DO_SWITCH_EXTRUDER || ENABLED(SWITCHING_NOZZLE) || ENABLED(PARKING_EXTRUDER)
#include "../../module/tool_change.h" #include "../../module/tool_change.h"
@ -64,13 +87,69 @@ inline float clamp(const float value, const float minimum, const float maximum)
return MAX(MIN(value, maximum), minimum); return MAX(MIN(value, maximum), minimum);
} }
static bool printer_killed = false;
namespace UI { 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) { void delay_ms(unsigned long ms) {
if (printer_killed)
DELAY_US(ms * 1000);
else
safe_delay(ms); safe_delay(ms);
} }
void yield() { void yield() {
if (!printer_killed)
thermalManager.manage_heater(); thermalManager.manage_heater();
} }
@ -491,7 +570,7 @@ namespace UI {
} }
const char* FileList::filename() { 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() { const char* FileList::shortFilename() {
@ -603,4 +682,11 @@ void lcd_status_printf_P(const uint8_t level, const char * const fmt, ...) {
UI::onStatusChanged(buff); UI::onStatusChanged(buff);
} }
void kill_screen(PGM_P msg) {
if (!printer_killed) {
printer_killed = true;
UI::onPrinterKilled(msg);
}
}
#endif // EXTENSIBLE_UI #endif // EXTENSIBLE_UI

View file

@ -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 <http://www.gnu.org/licenses/>.
*
*/
/************ /************
* ui_api.h * * ui_api.h *
************/ ************/
@ -127,6 +149,9 @@ namespace UI {
#endif #endif
#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 delay_ms(unsigned long ms);
void yield(); // Within lengthy loop, call this periodically void yield(); // Within lengthy loop, call this periodically

View file

@ -30,6 +30,7 @@
bool lcd_detected(); bool lcd_detected();
void lcd_update(); void lcd_update();
void lcd_setalertstatusPGM(PGM_P message); void lcd_setalertstatusPGM(PGM_P message);
void kill_screen(PGM_P lcd_msg);
#else #else
inline void lcd_init() {} inline void lcd_init() {}
inline bool lcd_detected() { return true; } inline bool lcd_detected() { return true; }