Merge pull request #174 from PavelSindler/MK2
Sorting files in SD card menu; xyz cal. details menu updated show real skew even if axes were orthogonalized during cal.
This commit is contained in:
commit
9753446e2e
|
|
@ -5,7 +5,7 @@
|
||||||
#include "Configuration_prusa.h"
|
#include "Configuration_prusa.h"
|
||||||
|
|
||||||
// Firmware version
|
// Firmware version
|
||||||
#define FW_version "3.0.12-2"
|
#define FW_version "3.0.12-3"
|
||||||
|
|
||||||
#define FW_PRUSA3D_MAGIC "PRUSA3DFW"
|
#define FW_PRUSA3D_MAGIC "PRUSA3DFW"
|
||||||
#define FW_PRUSA3D_MAGIC_LEN 10
|
#define FW_PRUSA3D_MAGIC_LEN 10
|
||||||
|
|
@ -47,6 +47,8 @@
|
||||||
#define EEPROM_TEMP_CAL_ACTIVE (EEPROM_PROBE_TEMP_SHIFT - 1)
|
#define EEPROM_TEMP_CAL_ACTIVE (EEPROM_PROBE_TEMP_SHIFT - 1)
|
||||||
#define EEPROM_BOWDEN_LENGTH (EEPROM_TEMP_CAL_ACTIVE - 2*4) //4 x int for bowden lengths for multimaterial
|
#define EEPROM_BOWDEN_LENGTH (EEPROM_TEMP_CAL_ACTIVE - 2*4) //4 x int for bowden lengths for multimaterial
|
||||||
#define EEPROM_CALIBRATION_STATUS_PINDA (EEPROM_BOWDEN_LENGTH - 1) //0 - not calibrated; 1 - calibrated
|
#define EEPROM_CALIBRATION_STATUS_PINDA (EEPROM_BOWDEN_LENGTH - 1) //0 - not calibrated; 1 - calibrated
|
||||||
|
#define EEPROM_SD_SORT (EEPROM_CALIBRATION_STATUS_PINDA - 1) //0 -time, 1-alpha, 2-none
|
||||||
|
#define EEPROM_XYZ_CAL_SKEW (EEPROM_SD_SORT - 4)
|
||||||
|
|
||||||
// Currently running firmware, each digit stored as uint16_t.
|
// Currently running firmware, each digit stored as uint16_t.
|
||||||
// The flavor differentiates a dev, alpha, beta, release candidate or a release version.
|
// The flavor differentiates a dev, alpha, beta, release candidate or a release version.
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,53 @@
|
||||||
// using:
|
// using:
|
||||||
//#define MENU_ADDAUTOSTART
|
//#define MENU_ADDAUTOSTART
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort SD file listings in alphabetical order.
|
||||||
|
*
|
||||||
|
* With this option enabled, items on SD cards will be sorted
|
||||||
|
* by name for easier navigation.
|
||||||
|
*
|
||||||
|
* By default...
|
||||||
|
*
|
||||||
|
* - Use the slowest -but safest- method for sorting.
|
||||||
|
* - Folders are sorted to the top.
|
||||||
|
* - The sort key is statically allocated.
|
||||||
|
* - No added G-code (M34) support.
|
||||||
|
* - 40 item sorting limit. (Items after the first 40 are unsorted.)
|
||||||
|
*
|
||||||
|
* SD sorting uses static allocation (as set by SDSORT_LIMIT), allowing the
|
||||||
|
* compiler to calculate the worst-case usage and throw an error if the SRAM
|
||||||
|
* limit is exceeded.
|
||||||
|
*
|
||||||
|
* - SDSORT_USES_RAM provides faster sorting via a static directory buffer.
|
||||||
|
* - SDSORT_USES_STACK does the same, but uses a local stack-based buffer.
|
||||||
|
* - SDSORT_CACHE_NAMES will retain the sorted file listing in RAM. (Expensive!)
|
||||||
|
* - SDSORT_DYNAMIC_RAM only uses RAM when the SD menu is visible. (Use with caution!)
|
||||||
|
*/
|
||||||
|
#define SDCARD_SORT_ALPHA //Alphabetical sorting of SD files menu
|
||||||
|
|
||||||
|
// SD Card Sorting options
|
||||||
|
// In current firmware Prusa Firmware version,
|
||||||
|
// SDSORT_CACHE_NAMES and SDSORT_DYNAMIC_RAM is not supported and must be set to false.
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
#define SD_SORT_TIME 0
|
||||||
|
#define SD_SORT_ALPHA 1
|
||||||
|
#define SD_SORT_NONE 2
|
||||||
|
|
||||||
|
#define SDSORT_LIMIT 40 // Maximum number of sorted items (10-256).
|
||||||
|
#define FOLDER_SORTING -1 // -1=above 0=none 1=below
|
||||||
|
#define SDSORT_GCODE false // Allow turning sorting on/off with LCD and M34 g-code.
|
||||||
|
#define SDSORT_USES_RAM true // Pre-allocate a static array for faster pre-sorting.
|
||||||
|
#define SDSORT_USES_STACK true // Prefer the stack for pre-sorting to give back some SRAM. (Negated by next 2 options.)
|
||||||
|
#define SDSORT_CACHE_NAMES false // Keep sorted items in RAM longer for speedy performance. Most expensive option.
|
||||||
|
#define SDSORT_DYNAMIC_RAM false // Use dynamic allocation (within SD menus). Least expensive option. Set SDSORT_LIMIT before use!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SDCARD_SORT_ALPHA)
|
||||||
|
#define HAS_FOLDER_SORTING (FOLDER_SORTING || SDSORT_GCODE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Show a progress bar on the LCD when printing from SD?
|
// Show a progress bar on the LCD when printing from SD?
|
||||||
//#define LCD_PROGRESS_BAR
|
//#define LCD_PROGRESS_BAR
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -326,7 +326,8 @@ extern bool mesh_bed_leveling_flag;
|
||||||
extern bool mesh_bed_run_from_menu;
|
extern bool mesh_bed_run_from_menu;
|
||||||
|
|
||||||
extern float distance_from_min[3];
|
extern float distance_from_min[3];
|
||||||
extern float angleDiff;
|
|
||||||
|
extern bool sortAlpha;
|
||||||
|
|
||||||
extern void calculate_volumetric_multipliers();
|
extern void calculate_volumetric_multipliers();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@
|
||||||
#define TEST(n,b) (((n)&BIT(b))!=0)
|
#define TEST(n,b) (((n)&BIT(b))!=0)
|
||||||
#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (BIT(b))
|
#define SET_BIT(n,b,value) (n) ^= ((-value)^(n)) & (BIT(b))
|
||||||
|
|
||||||
|
|
||||||
// look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html
|
// look here for descriptions of G-codes: http://linuxcnc.org/handbook/gcode/g-code.html
|
||||||
// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
|
// http://objects.reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes
|
||||||
|
|
||||||
|
|
@ -292,7 +291,8 @@ char snmm_filaments_used = 0;
|
||||||
int selectedSerialPort;
|
int selectedSerialPort;
|
||||||
|
|
||||||
float distance_from_min[3];
|
float distance_from_min[3];
|
||||||
float angleDiff;
|
|
||||||
|
bool sortAlpha = false;
|
||||||
|
|
||||||
bool volumetric_enabled = false;
|
bool volumetric_enabled = false;
|
||||||
float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA
|
float filament_size[EXTRUDERS] = { DEFAULT_NOMINAL_FILAMENT_DIA
|
||||||
|
|
@ -1208,6 +1208,9 @@ void setup()
|
||||||
if (eeprom_read_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA) == 255) {
|
if (eeprom_read_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA) == 255) {
|
||||||
eeprom_write_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0);
|
eeprom_write_byte((uint8_t*)EEPROM_CALIBRATION_STATUS_PINDA, 0);
|
||||||
}
|
}
|
||||||
|
if (eeprom_read_byte((uint8_t*)EEPROM_SD_SORT) == 255) {
|
||||||
|
eeprom_write_byte((uint8_t*)EEPROM_SD_SORT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef DEBUG_DISABLE_STARTMSGS
|
#ifndef DEBUG_DISABLE_STARTMSGS
|
||||||
check_babystep(); //checking if Z babystep is in allowed range
|
check_babystep(); //checking if Z babystep is in allowed range
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,19 @@
|
||||||
|
|
||||||
#ifdef SDSUPPORT
|
#ifdef SDSUPPORT
|
||||||
|
|
||||||
|
#define LONGEST_FILENAME (longFilename[0] ? longFilename : filename)
|
||||||
|
|
||||||
|
|
||||||
CardReader::CardReader()
|
CardReader::CardReader()
|
||||||
{
|
{
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
sort_count = 0;
|
||||||
|
#if SDSORT_GCODE
|
||||||
|
sort_alpha = true;
|
||||||
|
sort_folders = FOLDER_SORTING;
|
||||||
|
//sort_reverse = false;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
filesize = 0;
|
filesize = 0;
|
||||||
sdpos = 0;
|
sdpos = 0;
|
||||||
sdprinting = false;
|
sdprinting = false;
|
||||||
|
|
@ -50,94 +59,114 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/)
|
/**
|
||||||
{
|
* Dive into a folder and recurse depth-first to perform a pre-set operation lsAction:
|
||||||
dir_t p;
|
* LS_Count - Add +1 to nrFiles for every file within the parent
|
||||||
uint8_t cnt=0;
|
* LS_GetFilename - Get the filename of the file indexed by nrFiles
|
||||||
|
* LS_SerialPrint - Print the full path and size of each file to serial output
|
||||||
while (parent.readDir(p, longFilename) > 0)
|
*/
|
||||||
{
|
|
||||||
if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
|
|
||||||
{
|
|
||||||
|
|
||||||
char path[13*2];
|
void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) {
|
||||||
char lfilename[13];
|
dir_t p;
|
||||||
createFilename(lfilename,p);
|
uint8_t cnt = 0;
|
||||||
|
|
||||||
path[0]=0;
|
|
||||||
if(strlen(prepend)==0) //avoid leading / if already in prepend
|
|
||||||
{
|
|
||||||
strcat(path,"/");
|
|
||||||
}
|
|
||||||
strcat(path,prepend);
|
|
||||||
strcat(path,lfilename);
|
|
||||||
strcat(path,"/");
|
|
||||||
|
|
||||||
//Serial.print(path);
|
|
||||||
|
|
||||||
SdFile dir;
|
|
||||||
if(!dir.open(parent,lfilename, O_READ))
|
|
||||||
{
|
|
||||||
if(lsAction==LS_SerialPrint)
|
|
||||||
{
|
|
||||||
SERIAL_ECHO_START;
|
|
||||||
SERIAL_ECHORPGM(MSG_SD_CANT_ENTER_SUBDIR);
|
|
||||||
SERIAL_ECHOLN(lfilename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lsDive(path,dir);
|
|
||||||
//close done automatically by destructor of SdFile
|
|
||||||
|
|
||||||
|
// Read the next entry from a directory
|
||||||
}
|
while (parent.readDir(p, longFilename) > 0) {
|
||||||
else
|
|
||||||
{
|
|
||||||
char pn0 = p.name[0];
|
|
||||||
if (pn0 == DIR_NAME_FREE) break;
|
|
||||||
if (pn0 == DIR_NAME_DELETED || pn0 == '.' || pn0 == '_') continue;
|
|
||||||
char lf0 = longFilename[0];
|
|
||||||
if (lf0 == '.' || lf0 == '_') continue;
|
|
||||||
|
|
||||||
if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
|
// If the entry is a directory and the action is LS_SerialPrint
|
||||||
// Ignore the files and directories with hidden or system attribute.
|
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) {
|
||||||
if ((p.attributes & (DIR_ATT_HIDDEN | DIR_ATT_SYSTEM)) != 0) continue;
|
|
||||||
filenameIsDir=DIR_IS_SUBDIR(&p);
|
// Get the short name for the item, which we know is a folder
|
||||||
|
char lfilename[FILENAME_LENGTH];
|
||||||
|
createFilename(lfilename, p);
|
||||||
if(!filenameIsDir)
|
|
||||||
{
|
// Allocate enough stack space for the full path to a folder, trailing slash, and nul
|
||||||
if(p.name[8]!='G') continue;
|
bool prepend_is_empty = (prepend[0] == '\0');
|
||||||
if(p.name[9]=='~') continue;
|
int len = (prepend_is_empty ? 1 : strlen(prepend)) + strlen(lfilename) + 1 + 1;
|
||||||
}
|
char path[len];
|
||||||
//if(cnt++!=nr) continue;
|
|
||||||
createFilename(filename,p);
|
// Append the FOLDERNAME12/ to the passed string.
|
||||||
if(lsAction==LS_SerialPrint)
|
// It contains the full path to the "parent" argument.
|
||||||
{
|
// We now have the full path to the item in this folder.
|
||||||
SERIAL_PROTOCOL(prepend);
|
strcpy(path, prepend_is_empty ? "/" : prepend); // root slash if prepend is empty
|
||||||
SERIAL_PROTOCOLLN(filename);
|
strcat(path, lfilename); // FILENAME_LENGTH-1 characters maximum
|
||||||
}
|
strcat(path, "/"); // 1 character
|
||||||
else if(lsAction==LS_Count)
|
|
||||||
{
|
// Serial.print(path);
|
||||||
nrFiles++;
|
|
||||||
}
|
// Get a new directory object using the full path
|
||||||
else if(lsAction==LS_GetFilename)
|
// and dive recursively into it.
|
||||||
{
|
SdFile dir;
|
||||||
if (match != NULL) {
|
if (!dir.open(parent, lfilename, O_READ)) {
|
||||||
if (strcasecmp(match, filename) == 0) return;
|
if (lsAction == LS_SerialPrint) {
|
||||||
}
|
//SERIAL_ECHO_START();
|
||||||
else if (cnt == nrFiles) return;
|
//SERIAL_ECHOPGM(MSG_SD_CANT_OPEN_SUBDIR);
|
||||||
cnt++;
|
//SERIAL_ECHOLN(lfilename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
lsDive(path, dir);
|
||||||
}
|
// close() is done automatically by destructor of SdFile
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t pn0 = p.name[0];
|
||||||
|
if (pn0 == DIR_NAME_FREE) break;
|
||||||
|
if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue;
|
||||||
|
if (longFilename[0] == '.') continue;
|
||||||
|
|
||||||
|
if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue;
|
||||||
|
|
||||||
|
filenameIsDir = DIR_IS_SUBDIR(&p);
|
||||||
|
|
||||||
|
if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue;
|
||||||
|
|
||||||
|
switch (lsAction) {
|
||||||
|
case LS_Count:
|
||||||
|
nrFiles++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LS_SerialPrint:
|
||||||
|
createFilename(filename, p);
|
||||||
|
SERIAL_PROTOCOL(prepend);
|
||||||
|
SERIAL_PROTOCOL(filename);
|
||||||
|
//SERIAL_PROTOCOLCHAR(' ');
|
||||||
|
SERIAL_PROTOCOLLN(p.fileSize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LS_GetFilename:
|
||||||
|
//SERIAL_ECHOPGM("File: ");
|
||||||
|
createFilename(filename, p);
|
||||||
|
/*MYSERIAL.println(filename);
|
||||||
|
SERIAL_ECHOPGM("Write date: ");
|
||||||
|
writeDate = p.lastWriteDate;
|
||||||
|
MYSERIAL.println(writeDate);
|
||||||
|
writeTime = p.lastWriteTime;
|
||||||
|
SERIAL_ECHOPGM("Creation date: ");
|
||||||
|
MYSERIAL.println(p.creationDate);
|
||||||
|
SERIAL_ECHOPGM("Access date: ");
|
||||||
|
MYSERIAL.println(p.lastAccessDate);
|
||||||
|
SERIAL_ECHOLNPGM("");*/
|
||||||
|
creationDate = p.creationDate;
|
||||||
|
creationTime = p.creationTime;
|
||||||
|
|
||||||
|
//writeDate = p.lastAccessDate;
|
||||||
|
|
||||||
|
if (match != NULL) {
|
||||||
|
if (strcasecmp(match, filename) == 0) return;
|
||||||
|
}
|
||||||
|
else if (cnt == nrFiles) return;
|
||||||
|
cnt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // while readDir
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::ls()
|
void CardReader::ls()
|
||||||
{
|
{
|
||||||
lsAction=LS_SerialPrint;
|
lsAction=LS_SerialPrint;
|
||||||
if(lsAction==LS_Count)
|
// if(lsAction==LS_Count)
|
||||||
nrFiles=0;
|
// nrFiles=0;
|
||||||
|
|
||||||
root.rewind();
|
root.rewind();
|
||||||
lsDive("",root);
|
lsDive("",root);
|
||||||
|
|
@ -185,6 +214,9 @@ void CardReader::initsd()
|
||||||
}
|
}
|
||||||
workDir=root;
|
workDir=root;
|
||||||
curDir=&root;
|
curDir=&root;
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
presort();
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
if(!workDir.openRoot(&volume))
|
if(!workDir.openRoot(&volume))
|
||||||
{
|
{
|
||||||
|
|
@ -203,6 +235,9 @@ void CardReader::setroot()
|
||||||
workDir=root;
|
workDir=root;
|
||||||
|
|
||||||
curDir=&workDir;
|
curDir=&workDir;
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
presort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void CardReader::release()
|
void CardReader::release()
|
||||||
{
|
{
|
||||||
|
|
@ -215,6 +250,9 @@ void CardReader::startFileprint()
|
||||||
if(cardOK)
|
if(cardOK)
|
||||||
{
|
{
|
||||||
sdprinting = true;
|
sdprinting = true;
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
flush_presort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,6 +487,9 @@ void CardReader::removeFile(char* name)
|
||||||
SERIAL_PROTOCOLPGM("File deleted:");
|
SERIAL_PROTOCOLPGM("File deleted:");
|
||||||
SERIAL_PROTOCOLLN(fname);
|
SERIAL_PROTOCOLLN(fname);
|
||||||
sdpos = 0;
|
sdpos = 0;
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
presort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -641,6 +682,267 @@ void CardReader::updir()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of a file in the current directory by sort-index
|
||||||
|
*/
|
||||||
|
void CardReader::getfilename_sorted(const uint16_t nr) {
|
||||||
|
getfilename(
|
||||||
|
#if SDSORT_GCODE
|
||||||
|
sort_alpha &&
|
||||||
|
#endif
|
||||||
|
(nr < sort_count) ? sort_order[nr] : nr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read all the files and produce a sort key
|
||||||
|
*
|
||||||
|
* We can do this in 3 ways...
|
||||||
|
* - Minimal RAM: Read two filenames at a time sorting along...
|
||||||
|
* - Some RAM: Buffer the directory just for this sort
|
||||||
|
* - Most RAM: Buffer the directory and return filenames from RAM
|
||||||
|
*/
|
||||||
|
void CardReader::presort() {
|
||||||
|
|
||||||
|
uint8_t sdSort = eeprom_read_byte((uint8_t*)EEPROM_SD_SORT);
|
||||||
|
|
||||||
|
if (sdSort == SD_SORT_NONE) return; //sd sort is turned off
|
||||||
|
#if !SDSORT_USES_RAM
|
||||||
|
lcd_set_progress();
|
||||||
|
#endif
|
||||||
|
lcd_implementation_clear();
|
||||||
|
lcd_print_at_PGM(0, 1, MSG_SORTING);
|
||||||
|
|
||||||
|
#if SDSORT_GCODE
|
||||||
|
if (!sort_alpha) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Throw away old sort index
|
||||||
|
flush_presort();
|
||||||
|
|
||||||
|
// If there are files, sort up to the limit
|
||||||
|
uint16_t fileCnt = getnrfilenames();
|
||||||
|
if (fileCnt > 0) {
|
||||||
|
|
||||||
|
// Never sort more than the max allowed
|
||||||
|
// If you use folders to organize, 20 may be enough
|
||||||
|
if (fileCnt > SDSORT_LIMIT) fileCnt = SDSORT_LIMIT;
|
||||||
|
|
||||||
|
// Sort order is always needed. May be static or dynamic.
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
sort_order = new uint8_t[fileCnt];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use RAM to store the entire directory during pre-sort.
|
||||||
|
// SDSORT_LIMIT should be set to prevent over-allocation.
|
||||||
|
#if SDSORT_USES_RAM
|
||||||
|
|
||||||
|
// If using dynamic ram for names, allocate on the heap.
|
||||||
|
#if SDSORT_CACHE_NAMES
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
sortshort = new char*[fileCnt];
|
||||||
|
sortnames = new char*[fileCnt];
|
||||||
|
#endif
|
||||||
|
#elif SDSORT_USES_STACK
|
||||||
|
char sortnames[fileCnt][LONG_FILENAME_LENGTH];
|
||||||
|
uint16_t creation_time[SDSORT_LIMIT];
|
||||||
|
uint16_t creation_date[SDSORT_LIMIT];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Folder sorting needs 1 bit per entry for flags.
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
isDir = new uint8_t[(fileCnt + 7) >> 3];
|
||||||
|
#elif SDSORT_USES_STACK
|
||||||
|
uint8_t isDir[(fileCnt + 7) >> 3];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else // !SDSORT_USES_RAM
|
||||||
|
|
||||||
|
// By default re-read the names from SD for every compare
|
||||||
|
// retaining only two filenames at a time. This is very
|
||||||
|
// slow but is safest and uses minimal RAM.
|
||||||
|
char name1[LONG_FILENAME_LENGTH + 1];
|
||||||
|
uint16_t creation_time_bckp;
|
||||||
|
uint16_t creation_date_bckp;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fileCnt > 1) {
|
||||||
|
// Init sort order.
|
||||||
|
for (uint16_t i = 0; i < fileCnt; i++) {
|
||||||
|
sort_order[i] = i;
|
||||||
|
// If using RAM then read all filenames now.
|
||||||
|
#if SDSORT_USES_RAM
|
||||||
|
getfilename(i);
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
// Use dynamic method to copy long filename
|
||||||
|
sortnames[i] = strdup(LONGEST_FILENAME);
|
||||||
|
#if SDSORT_CACHE_NAMES
|
||||||
|
// When caching also store the short name, since
|
||||||
|
// we're replacing the getfilename() behavior.
|
||||||
|
sortshort[i] = strdup(filename);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Copy filenames into the static array
|
||||||
|
strcpy(sortnames[i], LONGEST_FILENAME);
|
||||||
|
creation_time[i] = creationTime;
|
||||||
|
creation_date[i] = creationDate;
|
||||||
|
#if SDSORT_CACHE_NAMES
|
||||||
|
strcpy(sortshort[i], filename);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
// char out[30];
|
||||||
|
// sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
|
||||||
|
// SERIAL_ECHOLN(out);
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
const uint16_t bit = i & 0x07, ind = i >> 3;
|
||||||
|
if (bit == 0) isDir[ind] = 0x00;
|
||||||
|
if (filenameIsDir) isDir[ind] |= _BV(bit);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// Bubble Sort
|
||||||
|
uint16_t counter = 0;
|
||||||
|
for (uint16_t i = fileCnt; --i;) {
|
||||||
|
bool didSwap = false;
|
||||||
|
|
||||||
|
#if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used
|
||||||
|
int8_t percent = ((counter * 100) / (fileCnt-1));
|
||||||
|
for (int column = 0; column < 20; column++) {
|
||||||
|
if (column < (percent/5)) lcd_implementation_print_at(column, 2, "\x01"); //simple progress bar
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//MYSERIAL.println(int(i));
|
||||||
|
for (uint16_t j = 0; j < i; ++j) {
|
||||||
|
const uint16_t o1 = sort_order[j], o2 = sort_order[j + 1];
|
||||||
|
// Compare names from the array or just the two buffered names
|
||||||
|
#if SDSORT_USES_RAM
|
||||||
|
#define _SORT_CMP_NODIR() (strcasecmp(sortnames[o1], sortnames[o2]) > 0)
|
||||||
|
#define _SORT_CMP_TIME_NODIR() (((creation_date[o1] == creation_date[o2]) && (creation_time[o1] < creation_time[o2])) || \
|
||||||
|
(creation_date[o1] < creation_date [o2]))
|
||||||
|
#else
|
||||||
|
#define _SORT_CMP_NODIR() (strcasecmp(name1, name2) > 0) //true if lowercase(name1) > lowercase(name2)
|
||||||
|
#define _SORT_CMP_TIME_NODIR() (((creation_date_bckp == creationDate) && (creation_time_bckp < creationTime)) || \
|
||||||
|
(creation_date_bckp < creationDate))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
#if SDSORT_USES_RAM
|
||||||
|
// Folder sorting needs an index and bit to test for folder-ness.
|
||||||
|
const uint8_t ind1 = o1 >> 3, bit1 = o1 & 0x07,
|
||||||
|
ind2 = o2 >> 3, bit2 = o2 & 0x07;
|
||||||
|
#define _SORT_CMP_DIR(fs) \
|
||||||
|
(((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \
|
||||||
|
? _SORT_CMP_NODIR() \
|
||||||
|
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0)
|
||||||
|
#define _SORT_CMP_TIME_DIR(fs) \
|
||||||
|
(((isDir[ind1] & _BV(bit1)) != 0) == ((isDir[ind2] & _BV(bit2)) != 0) \
|
||||||
|
? _SORT_CMP_TIME_NODIR() \
|
||||||
|
: (isDir[fs > 0 ? ind1 : ind2] & (fs > 0 ? _BV(bit1) : _BV(bit2))) != 0)
|
||||||
|
#else
|
||||||
|
#define _SORT_CMP_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1))
|
||||||
|
#define _SORT_CMP_TIME_DIR(fs) ((dir1 == filenameIsDir) ? _SORT_CMP_TIME_NODIR() : (fs > 0 ? dir1 : !dir1))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The most economical method reads names as-needed
|
||||||
|
// throughout the loop. Slow if there are many.
|
||||||
|
#if !SDSORT_USES_RAM
|
||||||
|
|
||||||
|
getfilename(o1);
|
||||||
|
strcpy(name1, LONGEST_FILENAME); // save (or getfilename below will trounce it)
|
||||||
|
creation_date_bckp = creationDate;
|
||||||
|
creation_time_bckp = creationTime;
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
bool dir1 = filenameIsDir;
|
||||||
|
#endif
|
||||||
|
getfilename(o2);
|
||||||
|
char *name2 = LONGEST_FILENAME; // use the string in-place
|
||||||
|
|
||||||
|
#endif // !SDSORT_USES_RAM
|
||||||
|
|
||||||
|
// Sort the current pair according to settings.
|
||||||
|
if(
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
(sdSort == SD_SORT_TIME && _SORT_CMP_TIME_DIR(FOLDER_SORTING)) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_DIR(FOLDER_SORTING))
|
||||||
|
#else
|
||||||
|
(sdSort == SD_SORT_TIME && _SORT_CMP_TIME_NODIR()) || (sdSort == SD_SORT_ALPHA && _SORT_CMP_NODIR())
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
sort_order[j] = o2;
|
||||||
|
sort_order[j + 1] = o1;
|
||||||
|
didSwap = true;
|
||||||
|
//SERIAL_ECHOLNPGM("did swap");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!didSwap) break;
|
||||||
|
} //end of bubble sort loop
|
||||||
|
|
||||||
|
// Using RAM but not keeping names around
|
||||||
|
#if (SDSORT_USES_RAM && !SDSORT_CACHE_NAMES)
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
for (uint16_t i = 0; i < fileCnt; ++i) free(sortnames[i]);
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
free(isDir);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sort_order[0] = 0;
|
||||||
|
#if (SDSORT_USES_RAM && SDSORT_CACHE_NAMES)
|
||||||
|
getfilename(0);
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
sortnames = new char*[1];
|
||||||
|
sortnames[0] = strdup(LONGEST_FILENAME); // malloc
|
||||||
|
sortshort = new char*[1];
|
||||||
|
sortshort[0] = strdup(filename); // malloc
|
||||||
|
isDir = new uint8_t[1];
|
||||||
|
#else
|
||||||
|
strcpy(sortnames[0], LONGEST_FILENAME);
|
||||||
|
strcpy(sortshort[0], filename);
|
||||||
|
#endif
|
||||||
|
isDir[0] = filenameIsDir ? 0x01 : 0x00;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_count = fileCnt;
|
||||||
|
}
|
||||||
|
#if !SDSORT_USES_RAM //show progresss bar only if slow sorting method is used
|
||||||
|
for(int column = 0; column <=19; column++ ) lcd_implementation_print_at(column, 2, "\x01"); //simple progress bar
|
||||||
|
delay(500);
|
||||||
|
lcd_set_arrows();
|
||||||
|
lcd_update(2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardReader::flush_presort() {
|
||||||
|
if (sort_count > 0) {
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
delete sort_order;
|
||||||
|
#if SDSORT_CACHE_NAMES
|
||||||
|
for (uint8_t i = 0; i < sort_count; ++i) {
|
||||||
|
free(sortshort[i]); // strdup
|
||||||
|
free(sortnames[i]); // strdup
|
||||||
|
}
|
||||||
|
delete sortshort;
|
||||||
|
delete sortnames;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
sort_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CardReader::printingHasFinished()
|
void CardReader::printingHasFinished()
|
||||||
{
|
{
|
||||||
|
|
@ -664,6 +966,9 @@ void CardReader::printingHasFinished()
|
||||||
enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
||||||
}
|
}
|
||||||
autotempShutdown();
|
autotempShutdown();
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
presort();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "SdFile.h"
|
#include "SdFile.h"
|
||||||
enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
|
enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
|
||||||
|
|
||||||
class CardReader
|
class CardReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -40,6 +41,15 @@ public:
|
||||||
void updir();
|
void updir();
|
||||||
void setroot();
|
void setroot();
|
||||||
|
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
void presort();
|
||||||
|
void getfilename_sorted(const uint16_t nr);
|
||||||
|
#if SDSORT_GCODE
|
||||||
|
FORCE_INLINE void setSortOn(bool b) { sort_alpha = b; presort(); }
|
||||||
|
FORCE_INLINE void setSortFolders(int i) { sort_folders = i; presort(); }
|
||||||
|
//FORCE_INLINE void setSortReverse(bool b) { sort_reverse = b; }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
|
FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
|
||||||
FORCE_INLINE bool eof() { return sdpos>=filesize ;};
|
FORCE_INLINE bool eof() { return sdpos>=filesize ;};
|
||||||
|
|
@ -58,12 +68,60 @@ public:
|
||||||
bool sdprinting ;
|
bool sdprinting ;
|
||||||
bool cardOK ;
|
bool cardOK ;
|
||||||
char filename[13];
|
char filename[13];
|
||||||
|
uint16_t creationTime, creationDate;
|
||||||
char longFilename[LONG_FILENAME_LENGTH];
|
char longFilename[LONG_FILENAME_LENGTH];
|
||||||
bool filenameIsDir;
|
bool filenameIsDir;
|
||||||
int lastnr; //last number of the autostart;
|
int lastnr; //last number of the autostart;
|
||||||
private:
|
private:
|
||||||
SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
|
SdFile root,*curDir,workDir,workDirParents[MAX_DIR_DEPTH];
|
||||||
uint16_t workDirDepth;
|
uint16_t workDirDepth;
|
||||||
|
|
||||||
|
// Sort files and folders alphabetically.
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
uint16_t sort_count; // Count of sorted items in the current directory
|
||||||
|
#if SDSORT_GCODE
|
||||||
|
bool sort_alpha; // Flag to enable / disable the feature
|
||||||
|
int sort_folders; // Flag to enable / disable folder sorting
|
||||||
|
//bool sort_reverse; // Flag to enable / disable reverse sorting
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// By default the sort index is static
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
uint8_t *sort_order;
|
||||||
|
#else
|
||||||
|
uint8_t sort_order[SDSORT_LIMIT];
|
||||||
|
#endif
|
||||||
|
// Cache filenames to speed up SD menus.
|
||||||
|
#if SDSORT_USES_RAM
|
||||||
|
|
||||||
|
// If using dynamic ram for names, allocate on the heap.
|
||||||
|
#if SDSORT_CACHE_NAMES
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
char **sortshort, **sortnames;
|
||||||
|
#else
|
||||||
|
char sortshort[SDSORT_LIMIT][FILENAME_LENGTH];
|
||||||
|
char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
|
||||||
|
#endif
|
||||||
|
#elif !SDSORT_USES_STACK
|
||||||
|
char sortnames[SDSORT_LIMIT][FILENAME_LENGTH];
|
||||||
|
uint16_t creation_time[SDSORT_LIMIT];
|
||||||
|
uint16_t creation_date[SDSORT_LIMIT];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Folder sorting uses an isDir array when caching items.
|
||||||
|
#if HAS_FOLDER_SORTING
|
||||||
|
#if SDSORT_DYNAMIC_RAM
|
||||||
|
uint8_t *isDir;
|
||||||
|
#elif (SDSORT_CACHE_NAMES) || !(SDSORT_USES_STACK)
|
||||||
|
uint8_t isDir[(SDSORT_LIMIT + 7) >> 3];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SDSORT_USES_RAM
|
||||||
|
|
||||||
|
#endif // SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
|
|
||||||
Sd2Card card;
|
Sd2Card card;
|
||||||
SdVolume volume;
|
SdVolume volume;
|
||||||
SdFile file;
|
SdFile file;
|
||||||
|
|
@ -83,6 +141,10 @@ private:
|
||||||
int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
int16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
|
||||||
char* diveDirName;
|
char* diveDirName;
|
||||||
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
|
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
|
||||||
|
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
void flush_presort();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
extern CardReader card;
|
extern CardReader card;
|
||||||
#define IS_SD_PRINTING (card.sdprinting)
|
#define IS_SD_PRINTING (card.sdprinting)
|
||||||
|
|
|
||||||
|
|
@ -2948,6 +2948,26 @@ const char * const MSG_SOFTWARE_RESET_LANG_TABLE[1] PROGMEM = {
|
||||||
MSG_SOFTWARE_RESET_EN
|
MSG_SOFTWARE_RESET_EN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char MSG_SORTING_EN[] PROGMEM = "Sorting files";
|
||||||
|
const char * const MSG_SORTING_LANG_TABLE[1] PROGMEM = {
|
||||||
|
MSG_SORTING_EN
|
||||||
|
};
|
||||||
|
|
||||||
|
const char MSG_SORT_ALPHA_EN[] PROGMEM = "Sort: [Alphabet]";
|
||||||
|
const char * const MSG_SORT_ALPHA_LANG_TABLE[1] PROGMEM = {
|
||||||
|
MSG_SORT_ALPHA_EN
|
||||||
|
};
|
||||||
|
|
||||||
|
const char MSG_SORT_NONE_EN[] PROGMEM = "Sort: [None]";
|
||||||
|
const char * const MSG_SORT_NONE_LANG_TABLE[1] PROGMEM = {
|
||||||
|
MSG_SORT_NONE_EN
|
||||||
|
};
|
||||||
|
|
||||||
|
const char MSG_SORT_TIME_EN[] PROGMEM = "Sort: [Time]";
|
||||||
|
const char * const MSG_SORT_TIME_LANG_TABLE[1] PROGMEM = {
|
||||||
|
MSG_SORT_TIME_EN
|
||||||
|
};
|
||||||
|
|
||||||
const char MSG_SPEED_EN[] PROGMEM = "Speed";
|
const char MSG_SPEED_EN[] PROGMEM = "Speed";
|
||||||
const char MSG_SPEED_CZ[] PROGMEM = "Rychlost";
|
const char MSG_SPEED_CZ[] PROGMEM = "Rychlost";
|
||||||
const char MSG_SPEED_IT[] PROGMEM = "Velocita";
|
const char MSG_SPEED_IT[] PROGMEM = "Velocita";
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,14 @@ extern const char* const MSG_SLIGHT_SKEW_LANG_TABLE[LANG_NUM];
|
||||||
#define MSG_SLIGHT_SKEW LANG_TABLE_SELECT(MSG_SLIGHT_SKEW_LANG_TABLE)
|
#define MSG_SLIGHT_SKEW LANG_TABLE_SELECT(MSG_SLIGHT_SKEW_LANG_TABLE)
|
||||||
extern const char* const MSG_SOFTWARE_RESET_LANG_TABLE[1];
|
extern const char* const MSG_SOFTWARE_RESET_LANG_TABLE[1];
|
||||||
#define MSG_SOFTWARE_RESET LANG_TABLE_SELECT_EXPLICIT(MSG_SOFTWARE_RESET_LANG_TABLE, 0)
|
#define MSG_SOFTWARE_RESET LANG_TABLE_SELECT_EXPLICIT(MSG_SOFTWARE_RESET_LANG_TABLE, 0)
|
||||||
|
extern const char* const MSG_SORTING_LANG_TABLE[1];
|
||||||
|
#define MSG_SORTING LANG_TABLE_SELECT_EXPLICIT(MSG_SORTING_LANG_TABLE, 0)
|
||||||
|
extern const char* const MSG_SORT_ALPHA_LANG_TABLE[1];
|
||||||
|
#define MSG_SORT_ALPHA LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_ALPHA_LANG_TABLE, 0)
|
||||||
|
extern const char* const MSG_SORT_NONE_LANG_TABLE[1];
|
||||||
|
#define MSG_SORT_NONE LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_NONE_LANG_TABLE, 0)
|
||||||
|
extern const char* const MSG_SORT_TIME_LANG_TABLE[1];
|
||||||
|
#define MSG_SORT_TIME LANG_TABLE_SELECT_EXPLICIT(MSG_SORT_TIME_LANG_TABLE, 0)
|
||||||
extern const char* const MSG_SPEED_LANG_TABLE[LANG_NUM];
|
extern const char* const MSG_SPEED_LANG_TABLE[LANG_NUM];
|
||||||
#define MSG_SPEED LANG_TABLE_SELECT(MSG_SPEED_LANG_TABLE)
|
#define MSG_SPEED LANG_TABLE_SELECT(MSG_SPEED_LANG_TABLE)
|
||||||
extern const char* const MSG_STACK_ERROR_LANG_TABLE[1];
|
extern const char* const MSG_STACK_ERROR_LANG_TABLE[1];
|
||||||
|
|
|
||||||
|
|
@ -311,4 +311,8 @@
|
||||||
#define(length=15, lines=1) MSG_MEASURED_SKEW "Measured skew:"
|
#define(length=15, lines=1) MSG_MEASURED_SKEW "Measured skew:"
|
||||||
#define(length=15, lines=1) MSG_SLIGHT_SKEW "Slight skew:"
|
#define(length=15, lines=1) MSG_SLIGHT_SKEW "Slight skew:"
|
||||||
#define(length=15, lines=1) MSG_SEVERE_SKEW "Severe skew:"
|
#define(length=15, lines=1) MSG_SEVERE_SKEW "Severe skew:"
|
||||||
#define(length=20, lines=4) MSG_DEFAULT_SETTINGS_LOADED "Default settings loaded"
|
#define(length=20, lines=4) MSG_DEFAULT_SETTINGS_LOADED "Default settings loaded"
|
||||||
|
#define(length=17, lines=1) MSG_SORT_TIME "Sort: [Time]"
|
||||||
|
#define(length=17, lines=1) MSG_SORT_ALPHA "Sort: [Alphabet]"
|
||||||
|
#define(length=17, lines=1) MSG_SORT_NONE "Sort: [None]"
|
||||||
|
#define(length=20, lines=1) MSG_SORTING "Sorting files"
|
||||||
|
|
@ -143,6 +143,7 @@ BedSkewOffsetDetectionResultType calculate_machine_skew_and_offset_LS(
|
||||||
int8_t verbosity_level
|
int8_t verbosity_level
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
float angleDiff;
|
||||||
if (verbosity_level >= 10) {
|
if (verbosity_level >= 10) {
|
||||||
SERIAL_ECHOLNPGM("calculate machine skew and offset LS");
|
SERIAL_ECHOLNPGM("calculate machine skew and offset LS");
|
||||||
|
|
||||||
|
|
@ -317,6 +318,8 @@ BedSkewOffsetDetectionResultType calculate_machine_skew_and_offset_LS(
|
||||||
BedSkewOffsetDetectionResultType result = BED_SKEW_OFFSET_DETECTION_PERFECT;
|
BedSkewOffsetDetectionResultType result = BED_SKEW_OFFSET_DETECTION_PERFECT;
|
||||||
{
|
{
|
||||||
angleDiff = fabs(a2 - a1);
|
angleDiff = fabs(a2 - a1);
|
||||||
|
eeprom_update_float((float*)(EEPROM_XYZ_CAL_SKEW), angleDiff);
|
||||||
|
|
||||||
if (angleDiff > bed_skew_angle_mild)
|
if (angleDiff > bed_skew_angle_mild)
|
||||||
result = (angleDiff > bed_skew_angle_extreme) ?
|
result = (angleDiff > bed_skew_angle_extreme) ?
|
||||||
BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME :
|
BED_SKEW_OFFSET_DETECTION_SKEW_EXTREME :
|
||||||
|
|
@ -2478,7 +2481,7 @@ void count_xyz_details() {
|
||||||
a1 = asin(vec_x[1] / MACHINE_AXIS_SCALE_X);
|
a1 = asin(vec_x[1] / MACHINE_AXIS_SCALE_X);
|
||||||
/* MYSERIAL.println(vec_x[1]);
|
/* MYSERIAL.println(vec_x[1]);
|
||||||
MYSERIAL.println(a1);*/
|
MYSERIAL.println(a1);*/
|
||||||
angleDiff = fabs(a2 - a1);
|
//angleDiff = fabs(a2 - a1);
|
||||||
for (uint8_t mesh_point = 0; mesh_point < 3; ++mesh_point) {
|
for (uint8_t mesh_point = 0; mesh_point < 3; ++mesh_point) {
|
||||||
float y = vec_x[1] * pgm_read_float(bed_ref_points + mesh_point * 2) + vec_y[1] * pgm_read_float(bed_ref_points + mesh_point * 2 + 1) + cntr[1];
|
float y = vec_x[1] * pgm_read_float(bed_ref_points + mesh_point * 2) + vec_y[1] * pgm_read_float(bed_ref_points + mesh_point * 2 + 1) + cntr[1];
|
||||||
distance_from_min[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
|
distance_from_min[mesh_point] = (y - Y_MIN_POS_CALIBRATION_POINT_OUT_OF_REACH);
|
||||||
|
|
|
||||||
|
|
@ -1348,8 +1348,11 @@ static void lcd_move_e()
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_service_mode_show_result() {
|
void lcd_service_mode_show_result() {
|
||||||
|
float angleDiff;
|
||||||
lcd_set_custom_characters_degree();
|
lcd_set_custom_characters_degree();
|
||||||
count_xyz_details();
|
count_xyz_details();
|
||||||
|
angleDiff = eeprom_read_float((float*)(EEPROM_XYZ_CAL_SKEW));
|
||||||
|
|
||||||
lcd_update_enable(false);
|
lcd_update_enable(false);
|
||||||
lcd_implementation_clear();
|
lcd_implementation_clear();
|
||||||
lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
|
lcd_printPGM(MSG_Y_DISTANCE_FROM_MIN);
|
||||||
|
|
@ -2396,7 +2399,24 @@ void EEPROM_read(int pos, uint8_t* value, uint8_t size)
|
||||||
} while (--size);
|
} while (--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
static void lcd_sort_type_set() {
|
||||||
|
uint8_t sdSort;
|
||||||
|
|
||||||
|
EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));
|
||||||
|
switch (sdSort) {
|
||||||
|
case SD_SORT_TIME: sdSort = SD_SORT_ALPHA; break;
|
||||||
|
case SD_SORT_ALPHA: sdSort = SD_SORT_NONE; break;
|
||||||
|
default: sdSort = SD_SORT_TIME;
|
||||||
|
}
|
||||||
|
eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort);
|
||||||
|
lcd_goto_menu(lcd_sdcard_menu, 1);
|
||||||
|
//lcd_update(2);
|
||||||
|
//delay(1000);
|
||||||
|
|
||||||
|
card.presort();
|
||||||
|
}
|
||||||
|
#endif //SDCARD_SORT_ALPHA
|
||||||
|
|
||||||
static void lcd_silent_mode_set() {
|
static void lcd_silent_mode_set() {
|
||||||
SilentModeMenu = !SilentModeMenu;
|
SilentModeMenu = !SilentModeMenu;
|
||||||
|
|
@ -2414,6 +2434,16 @@ static void lcd_set_lang(unsigned char lang) {
|
||||||
langsel = LANGSEL_ACTIVE;
|
langsel = LANGSEL_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !SDSORT_USES_RAM
|
||||||
|
void lcd_set_arrows() {
|
||||||
|
void lcd_set_custom_characters_arrows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_set_progress() {
|
||||||
|
lcd_set_custom_characters_progress();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void lcd_force_language_selection() {
|
void lcd_force_language_selection() {
|
||||||
eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
|
eeprom_update_byte((unsigned char *)EEPROM_LANG, LANG_ID_FORCE_SELECTION);
|
||||||
}
|
}
|
||||||
|
|
@ -4119,16 +4149,24 @@ void getFileDescription(char *name, char *description) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void lcd_sdcard_menu()
|
void lcd_sdcard_menu()
|
||||||
{
|
{
|
||||||
|
uint8_t sdSort;
|
||||||
int tempScrool = 0;
|
int tempScrool = 0;
|
||||||
if (lcdDrawUpdate == 0 && LCD_CLICKED == 0)
|
if (lcdDrawUpdate == 0 && LCD_CLICKED == 0)
|
||||||
//delay(100);
|
//delay(100);
|
||||||
return; // nothing to do (so don't thrash the SD card)
|
return; // nothing to do (so don't thrash the SD card)
|
||||||
uint16_t fileCnt = card.getnrfilenames();
|
uint16_t fileCnt = card.getnrfilenames();
|
||||||
|
|
||||||
START_MENU();
|
START_MENU();
|
||||||
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
|
MENU_ITEM(back, MSG_MAIN, lcd_main_menu);
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
EEPROM_read(EEPROM_SD_SORT, (uint8_t*)&sdSort, sizeof(sdSort));
|
||||||
|
switch(sdSort){
|
||||||
|
case SD_SORT_TIME: MENU_ITEM(function, MSG_SORT_TIME, lcd_sort_type_set); break;
|
||||||
|
case SD_SORT_ALPHA: MENU_ITEM(function, MSG_SORT_ALPHA, lcd_sort_type_set); break;
|
||||||
|
default: MENU_ITEM(function, MSG_SORT_NONE, lcd_sort_type_set);
|
||||||
|
}
|
||||||
|
#endif // SDCARD_SORT_ALPHA
|
||||||
card.getWorkDirName();
|
card.getWorkDirName();
|
||||||
if (card.filename[0] == '/')
|
if (card.filename[0] == '/')
|
||||||
{
|
{
|
||||||
|
|
@ -4143,22 +4181,24 @@ void lcd_sdcard_menu()
|
||||||
{
|
{
|
||||||
if (_menuItemNr == _lineNr)
|
if (_menuItemNr == _lineNr)
|
||||||
{
|
{
|
||||||
#ifndef SDCARD_RATHERRECENTFIRST
|
const uint16_t nr = (sdSort == SD_SORT_NONE) ? (fileCnt - 1 - i) : i;
|
||||||
card.getfilename(i);
|
/* #ifdef SDCARD_RATHERRECENTFIRST
|
||||||
#else
|
#ifndef SDCARD_SORT_ALPHA
|
||||||
card.getfilename(fileCnt - 1 - i);
|
fileCnt - 1 -
|
||||||
#endif
|
#endif
|
||||||
if (card.filenameIsDir)
|
#endif
|
||||||
{
|
i;*/
|
||||||
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
} else {
|
if (sdSort == SD_SORT_NONE) card.getfilename(nr);
|
||||||
|
else card.getfilename_sorted(nr);
|
||||||
|
#else
|
||||||
|
card.getfilename(nr);
|
||||||
|
#endif
|
||||||
|
|
||||||
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
|
if (card.filenameIsDir)
|
||||||
|
MENU_ITEM(sddirectory, MSG_CARD_MENU, card.filename, card.longFilename);
|
||||||
|
else
|
||||||
|
MENU_ITEM(sdfile, MSG_CARD_MENU, card.filename, card.longFilename);
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MENU_ITEM_DUMMY();
|
MENU_ITEM_DUMMY();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,9 @@ void extr_unload_all();
|
||||||
void extr_unload_used();
|
void extr_unload_used();
|
||||||
void extr_unload();
|
void extr_unload();
|
||||||
static char snmm_stop_print_menu();
|
static char snmm_stop_print_menu();
|
||||||
|
#ifdef SDCARD_SORT_ALPHA
|
||||||
|
static void lcd_sort_type_set();
|
||||||
|
#endif
|
||||||
void stack_error();
|
void stack_error();
|
||||||
static void lcd_ping_allert();
|
static void lcd_ping_allert();
|
||||||
void lcd_printer_connected();
|
void lcd_printer_connected();
|
||||||
|
|
@ -259,4 +261,9 @@ void display_loading();
|
||||||
|
|
||||||
void lcd_service_mode_show_result();
|
void lcd_service_mode_show_result();
|
||||||
|
|
||||||
|
#if !SDSORT_USES_RAM
|
||||||
|
void lcd_set_arrows();
|
||||||
|
void lcd_set_progress();
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //ULTRALCD_H
|
#endif //ULTRALCD_H
|
||||||
|
|
@ -462,6 +462,22 @@ void lcd_set_custom_characters_arrows()
|
||||||
lcd.createChar(1, arrdown);
|
lcd.createChar(1, arrdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcd_set_custom_characters_progress()
|
||||||
|
{
|
||||||
|
byte progress[8] = {
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
B11111,
|
||||||
|
};
|
||||||
|
|
||||||
|
lcd.createChar(1, progress);
|
||||||
|
}
|
||||||
|
|
||||||
void lcd_set_custom_characters_nextpage()
|
void lcd_set_custom_characters_nextpage()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue