You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
12 KiB

/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#ifndef __MARLIN_LCD_API_H__
#define __MARLIN_LCD_API_H__
class Marlin_LCD_API {
public:
typedef const __FlashStringHelper *progmem_str;
enum axis_t {
X,
Y,
Z,
E0,
E1
};
static const uint8_t extruderCount;
static const uint8_t fanCount;
static float getActualTemp_celsius(const uint8_t extruder);
static float getTargetTemp_celsius(const uint8_t extruder);
static float getFan_percent(const uint8_t fan);
static float getAxisPosition_mm(const axis_t axis);
static float getAxisSteps_per_mm(const axis_t axis);
static uint8_t getProgress_percent();
static uint32_t getProgress_seconds_elapsed();
static float getFeedRate_percent();
static float getZOffset_mm();
static bool isAxisPositionKnown(const axis_t axis);
static bool isMoving();
static progmem_str getFirmwareName();
static void setTargetTemp_celsius(const uint8_t extruder, float temp);
static void setFan_percent(const uint8_t fan, float percent);
static void setAxisPosition_mm(const axis_t axis, float position, float _feedrate_mm_s);
static void setAxisSteps_per_mm(const axis_t axis, float steps_per_mm);
static void incrementZOffset_mm(const float z_offset);
static void setFeedrate_percent(const float percent);
static void runGCode(progmem_str gcode);
static float clamp(float value, float minimum, float maximum) {return max(min(value,maximum),minimum);};
static void initMedia();
static void checkMedia();
static bool isPrintingFromMedia();
static bool isPrinting();
static bool isMediaInserted();
static void stopPrint();
static void pausePrint();
static void resumePrint();
static void onCardInserted();
static void onCardRemoved();
static void onPrinterKilled(const char* lcd_msg);
static void onPlayTone(const uint16_t frequency, const uint16_t duration);
static uint16_t getMediaFileCount();
static void printFromSDCard(const char *filename);
static void changeDir(const char *dirname);
static void upDir();
static bool isAtRootDir();
class Media_Iterator;
};
class Marlin_LCD_API::Media_Iterator {
private:
uint16_t index;
uint16_t num_files;
public:
Media_Iterator(uint16_t start_index /* = 0*/);
bool hasMore();
void seek(uint16_t);
void next();
const char *longFilename();
const char *shortFilename();
const char *filename();
uint16_t value() {return index;}
uint16_t count() {return num_files;}
bool isDirectory();
};
#if defined(MSG_MARLIN)
const uint8_t Marlin_LCD_API::extruderCount = EXTRUDERS;
const uint8_t Marlin_LCD_API::fanCount = 1;
float Marlin_LCD_API::getActualTemp_celsius(const uint8_t extruder) {
if(extruder) {
return thermalManager.degHotend(extruder-1);
} else {
return thermalManager.degBed();
}
}
float Marlin_LCD_API::getTargetTemp_celsius(const uint8_t extruder) {
if(extruder) {
return thermalManager.degTargetHotend(extruder-1);
} else {
return thermalManager.degTargetBed();
}
}
float Marlin_LCD_API::getFan_percent(const uint8_t fan) {
return ((float(fanSpeeds[fan]) + 1) * 100) / 256;
}
float Marlin_LCD_API::getAxisPosition_mm(const Marlin_LCD_API::axis_t axis) {
switch(axis) {
case X: return current_position[X_AXIS]; break;
case Y: return current_position[Y_AXIS]; break;
case Z: return current_position[Z_AXIS]; break;
case E0: return current_position[E_AXIS]; break;
case E1: return current_position[E_AXIS+1]; break;
}
}
void Marlin_LCD_API::setAxisPosition_mm(const Marlin_LCD_API::axis_t axis, float position, float _feedrate_mm_s) {
set_destination_from_current();
switch(axis) {
case X: destination[X_AXIS] = position; break;
case Y: destination[Y_AXIS] = position; break;
case Z: destination[Z_AXIS] = position; break;
case E0: destination[E_AXIS] = position; break;
case E1: destination[E_AXIS+1] = position; break;
}
float old_feedrate = feedrate_mm_s;
feedrate_mm_s = _feedrate_mm_s;
prepare_move_to_destination();
feedrate_mm_s = old_feedrate;
}
bool Marlin_LCD_API::isMoving() {
return planner.blocks_queued();
}
float Marlin_LCD_API::getAxisSteps_per_mm(const Marlin_LCD_API::axis_t axis) {
switch(axis) {
case X: return planner.axis_steps_per_mm[X_AXIS];
case Y: return planner.axis_steps_per_mm[Y_AXIS];
case Z: return planner.axis_steps_per_mm[Z_AXIS];
case E0: return planner.axis_steps_per_mm[E_AXIS];
case E1: return planner.axis_steps_per_mm[E_AXIS+1];
}
}
void Marlin_LCD_API::setAxisSteps_per_mm(const Marlin_LCD_API::axis_t axis, float steps_per_mm) {
switch(axis) {
case X: planner.axis_steps_per_mm[X_AXIS] = steps_per_mm; break;
case Y: planner.axis_steps_per_mm[Y_AXIS] = steps_per_mm; break;
case Z: planner.axis_steps_per_mm[Z_AXIS] = steps_per_mm; break;
case E0: planner.axis_steps_per_mm[E_AXIS] = steps_per_mm; break;
case E1: planner.axis_steps_per_mm[E_AXIS+1] = steps_per_mm; break;
}
}
void Marlin_LCD_API::incrementZOffset_mm(float babystep_increment) {
const float new_zoffset = zprobe_zoffset + babystep_increment;
if (WITHIN(new_zoffset, Z_PROBE_OFFSET_RANGE_MIN, Z_PROBE_OFFSET_RANGE_MAX)) {
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
if (planner.leveling_active) {
thermalManager.babystep_axis(Z_AXIS, babystep_increment);
}
#endif
zprobe_zoffset = new_zoffset;
}
}
uint8_t Marlin_LCD_API::getProgress_percent() {
#if ENABLED(SDSUPPORT)
return card.percentDone();
#endif
}
uint32_t Marlin_LCD_API::getProgress_seconds_elapsed() {
const duration_t elapsed = print_job_timer.duration();
return elapsed.value;
}
float Marlin_LCD_API::getFeedRate_percent() {
return feedrate_percentage;
}
float Marlin_LCD_API::getZOffset_mm() {
return zprobe_zoffset;
}
void Marlin_LCD_API::runGCode(progmem_str gcode) {
enqueue_and_echo_commands_P((const char*)gcode);
}
bool Marlin_LCD_API::isAxisPositionKnown(const axis_t axis) {
switch(axis) {
case X: return axis_known_position[X_AXIS]; break;
case Y: return axis_known_position[Y_AXIS]; break;
case Z: return axis_known_position[Z_AXIS]; break;
}
}
Marlin_LCD_API::progmem_str Marlin_LCD_API::getFirmwareName() {
return F("Marlin " SHORT_BUILD_VERSION LULZBOT_FW_VERSION);
}
void Marlin_LCD_API::setTargetTemp_celsius(const uint8_t extruder, float temp) {
if(extruder) {
thermalManager.setTargetHotend(clamp(temp,0,500), extruder-1);
} else {
thermalManager.setTargetBed(clamp(temp,0,200));
}
}
void Marlin_LCD_API::setFan_percent(const uint8_t fan, float percent) {
if (fan < FAN_COUNT) {
fanSpeeds[fan] = clamp(round(percent*256/100-1), 0, 255);
}
}
void Marlin_LCD_API::setFeedrate_percent(const float percent) {
feedrate_percentage = clamp(percent, 10, 500);
}
void Marlin_LCD_API::printFromSDCard(const char *filename) {
card.openAndPrintFile(filename);
}
void Marlin_LCD_API::changeDir(const char *dirname) {
card.chdir(dirname);
}
void Marlin_LCD_API::upDir() {
card.updir();
}
bool Marlin_LCD_API::isAtRootDir() {
card.getWorkDirName();
return card.filename[0] == '/';
}
void lcd_setstatusPGM(const char * const message, int8_t level /* = 0 */);
uint8_t lcd_sd_status;
void Marlin_LCD_API::initMedia() {
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
SET_INPUT_PULLUP(SD_DETECT_PIN);
lcd_sd_status = 2; // UNKNOWN
#endif
}
void Marlin_LCD_API::checkMedia() {
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
const bool sd_status = IS_SD_INSERTED;
if (sd_status != lcd_sd_status) {
SERIAL_PROTOCOLLNPAIR("SD Status: ", sd_status);
if (sd_status) {
card.initsd();
if (lcd_sd_status != 2) onCardInserted();
SERIAL_PROTOCOLLNPAIR("Card: ",1);
}
else {
card.release();
if (lcd_sd_status != 2) onCardRemoved();
SERIAL_PROTOCOLLNPAIR("Card: ",0);
}
lcd_sd_status = sd_status;
}
#endif // SDSUPPORT && SD_DETECT_PIN
}
bool Marlin_LCD_API::isPrintingFromMedia() {
#if ENABLED(SDSUPPORT)
return card.cardOK && card.isFileOpen() && card.sdprinting;
#else
return false;
#endif
}
bool Marlin_LCD_API::isPrinting() {
return (planner.movesplanned() || IS_SD_PRINTING ||
#if ENABLED(SDSUPPORT)
(card.cardOK && card.isFileOpen()));
#else
false;
#endif
}
bool Marlin_LCD_API::isMediaInserted() {
#if ENABLED(SDSUPPORT)
return IS_SD_INSERTED;
#else
return false;
#endif
}
void Marlin_LCD_API::pausePrint() {
#if ENABLED(SDSUPPORT)
card.pauseSDPrint();
print_job_timer.pause();
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M125"));
#endif
lcd_setstatusPGM(PSTR(MSG_PRINT_PAUSED), -1);
#endif
}
void Marlin_LCD_API::resumePrint() {
#if ENABLED(SDSUPPORT)
#if ENABLED(PARK_HEAD_ON_PAUSE)
enqueue_and_echo_commands_P(PSTR("M24"));
#else
card.startFileprint();
print_job_timer.start();
#endif
#endif
}
void Marlin_LCD_API::stopPrint() {
#if ENABLED(SDSUPPORT)
card.stopSDPrint();
clear_command_queue();
quickstop_stepper();
print_job_timer.stop();
thermalManager.disable_all_heaters();
#if FAN_COUNT > 0
for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
#endif
wait_for_heatup = false;
lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
#endif
}
Marlin_LCD_API::Media_Iterator::Media_Iterator(uint16_t start_index /* = 0*/) {
num_files = card.get_num_Files();
index = min(start_index, num_files-1);
seek(index);
}
bool Marlin_LCD_API::Media_Iterator::hasMore() {
return (index < (num_files - 1)) && (num_files > 0);
}
void Marlin_LCD_API::Media_Iterator::next() {
if(hasMore()) {
index++;
seek(index);
}
}
void Marlin_LCD_API::Media_Iterator::seek(uint16_t index) {
const uint16_t nr =
#if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA)
num_files - 1 -
#endif
index;
#if ENABLED(SDCARD_SORT_ALPHA)
card.getfilename_sorted(nr);
#else
card.getfilename(nr);
#endif
}
const char *Marlin_LCD_API::Media_Iterator::filename() {
return (card.longFilename && card.longFilename[0]) ? card.longFilename : card.filename;
}
const char *Marlin_LCD_API::Media_Iterator::shortFilename() {
return card.filename;
}
const char *Marlin_LCD_API::Media_Iterator::longFilename() {
return card.longFilename;
}
bool Marlin_LCD_API::Media_Iterator::isDirectory() {
return card.filenameIsDir;
}
#endif
#endif MARLIN_LCD_API__MARLIN_LCD_API_H__